Static analysis findings for nc_program_manager: 8 security criticals (FTP plaintext, LSV2 cleartext, path traversal, license bypass), 4 functional bugs, 3 NRE risks, 3 resource leaks. See BUG_ANALYSIS.md for prioritized fix list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
Project State
Project Reference
See: .paul/PROJECT.md (updated 2026-05-18)
Core value: Machinists transfer CNC programs to/from any controller without manual steps or internet Current focus: v0.7 Build Hardening — formalize obfuscation pipeline + close v0.6 review findings
Current Position
Milestone: v0.7 Build Hardening — In Progress Phase: 17 of 18 (build-pipeline) — Not started Plan: Not started Status: Ready to plan Phase 17 Last activity: 2026-05-25 — Milestone v0.7 created (phases 17 build-pipeline, 18 review-fixes)
Progress:
- Milestone v0.1: [██████████] 100% (complete)
- Milestone v0.2: [██████████] 100% (complete)
- Milestone v0.3: [██████████] 100% (complete)
- Milestone v0.4: [██████████] 100% (complete)
- Milestone v0.5: [██████████] 100% (complete)
- Milestone v0.6: [██████████] 100% (complete)
- Milestone v0.7: [░░░░░░░░░░] 0%
- Phase 17: [░░░░░░░░░░] 0%
- Phase 18: [░░░░░░░░░░] 0%
Loop Position
PLAN ──▶ APPLY ──▶ UNIFY
○ ○ ○ [Ready for Phase 17 PLAN]
What Was Built (v0.6 Fagor Support — complete)
Phase 16 — Fagor FTP
Cnc/Models/CncManufacturer.cs— aggiuntoFagorall'enumCnc/Fagor/FagorConnectionConfig.cs— nuovo, ProgramDirectory/Users/Prg/, ProgramExtension.ncdefaultCnc/Fagor/IFagorFtpClient.cs— nuovo, interfaccia mirror SiemensCnc/Fagor/FagorFtpClient.cs— nuovo, FtpWebRequest + ASCII, mirror Siemens 1:1Cnc/Fagor/FagorMachine.cs— nuovo, implementaICncMachineconResolvePathadattato perProgramExtensionconfigurabileCnc/CncMachineFactory.cs— caseFagorcon porta default 21Cnc/NcProgramValidator.cs— refactor: helperIsRestrictiveDialect()(Fanuc+Mitsubishi); check generic (block 80, no tab, no lowercase, nested parens, comment 32) gated per-produttore. CaseFagoraggiunto inValidateName(max 24 char, noñ, solo lettere/cifre/spazi) eValidateForbiddenChars(nessuna restrizione contenuto)ArgParser.cs— case"fagor"aggiuntoProgram.cs— help text aggiornato (manufacturer/username/password)NcProgramManager.csproj— 4<Compile Include>per Cnc\Fagor*.csNcProgramManager.Tests/Unit/FagorMachineTests.cs— nuovo, 12 unit test conMock<IFagorFtpClient>+ 2 test con validator reale (ñ, lunghezza)NcProgramManager.Tests/Integration/FagorMachineIntegrationTests.cs— nuovo, 5 stub-based + 1 hardware skip (FAGOR_TEST_IP)NcProgramManager.Tests/Unit/NcProgramValidatorTests.cs— 8 nuovi test Fagor; 3 test esistenti spostati da Siemens a Fanuc dopo refactor gatingNcProgramManager.Tests/NcProgramManager.Tests.csproj— 2<Compile Include>aggiuntiREADME.md— sezione "Controller Fagor" in italiano: modelli supportati (8060/8065/8070), non supportati (8055 base, 8025-8050), regole nome programma, env var test
Modelli supportati: Fagor 8060, 8065, 8070 (FTP nativo); Fagor 8055 (richiede opzione Ethernet). Modelli non supportati: 8025/8030/8040/8050 (solo RS232, modulo seriale non implementato).
Phase 16-02 — Fagor Fixup (post-review)
Fix derivati da code review v0.6:
Cnc/NcProgramValidator.cs— FagorValidateName: split stem/extension viaLastIndexOf('.'); whitelist letter/digit/space applicata solo allo stem (consente.nco altre estensioni). Letteraliñsostituiti con escape Unicodeñ(codepage safety)NcProgramManager.Tests/Unit/NcProgramValidatorTests.cs:- 3 nuovi test lock Siemens (lowercase/tab/long-block ora esenti)
- 3 nuovi test lock Heidenhain (lowercase/tab/long-block ora esenti)
- 4 nuovi test Fagor (
.ncextension success,.pimextension success, stem con simbolo fail,ñescape) - 1 test esistente Fagor
ñmigrato a escapeñ
NcProgramManager.Tests/Unit/CncMachineFactoryTests.cs— aggiuntoCreate_Fagor_ReturnsFagorMachine.paul/ISSUES.md— aggiunte ISS-012..ISS-017 da review findings (non risolti in v0.6, deferiti)
Issue follow-up aperti: ISS-012, ISS-013, ISS-014, ISS-015, ISS-016, ISS-017
What Was Built (v0.5 Operational Quality — complete)
Phase 15 — Logging
nlog.config— rolling file target (daily, 7-day archive) + console (levels="Info",${message}layout);throwConfigExceptions=truepackages.config/NcProgramManager.csproj— NLog 5.2.8 reference + Content/CopyAlways entryFanucMachine.cs,HeidenhainMachine.cs,SiemensMachine.cs,MitsubishiMachine.cs— logger field + SetState catch →_log.Warn; Dispose catches annotatedLsv2Client.cs— logger field + Info at connect/disconnect + cleanup catch annotationsProgram.cs— logger field + 3×_log.Errorin catch blocks + 103×_log.Info(all Console.Write/WriteLine replaced); zero Console.Write/WriteLine remain- ISS-003 closed; ISS-004 closed
What Was Built (v0.4 Robustness — complete)
Phase 14 — Test Hardening
NcProgramManager.Tests/Integration/HardwareTestHelper.cs—GetIpOrSkip(string)callsAssert.Ignorewhen env var missing; ISS-007 closedHeidenhainMachineIntegrationTests.cs,SiemensMachineIntegrationTests.cs,MitsubishiMachineIntegrationTests.cs—Hardware_ConnectAsync_RealMachine+[Category("Hardware")]added to eachNcProgramManager.Tests/Unit/LicenseFileTests.cs— 4 tests covering empty, whitespace, valid base64, nonexistent pathLicenseValidatorTests.cs—Validate_EmptyFingerprint_ReturnsFalseadded; ISS-008 scaffold complete
Phase 13 — Robustness Fixes
Licensing/MachineFingerprint.cs— null guards on both WMI reads (?.Value?.ToString() ?? string.Empty); ISS-001 closedLicensing/LicenseValidator.cs—SHA256CryptoServiceProviderinusingblock insideValidate(); ISS-005 closedCnc/Heidenhain/Lsv2Client.cs—Connect()calls_tcp.Close()on timeout branch to abort pending socket; ISS-006 closed
What Was Built (v0.3 Code Quality — complete)
Phase 11 — Refactor
ArgParser.cs— static class,Parse(string[]) → InputArgs; all CLI regex parsing extracted from Program.csProgram.cs— no static state;Scarica/Inviatake explicitInputArgs;VediErroretakesbool debugModeProgram.cs— try/finally withconnectedflag inScaricaandInvia; connection leak fixedProgram.cs—PrintErrors(IReadOnlyList<CncError>)helper;CncResult.Errorsprinted on every failureAesCrypt.cs— deleted (dead code, no references)
Phase 12 — Docs CLI
README.md— params table expanded from 6 → 16 entries (all CLI args documented)README.md— codici errore section: 12 error codes with causa probabile + soluzione
What Was Built (v0.1 Multi-CN Release)
Phase 1 — CNC Abstraction
- Namespace:
Fanuc_integration.Cnc.*→FanucProgramManager.Cnc.*(29 files) IFocasDialectextended:UploadStart/DownloadStartacceptshort fileTypeIFanucMachinecreated: extendsICncMachinewith tool offset + work zero R/WCncManufacturerenum: Fanuc, Heidenhain, Siemens, Mitsubishi- All 29
Cnc/**/*.csfiles added to csproj
Phase 2 — Heidenhain LSV2
HeidenhainConnectionConfig— IP, port 19000, credentials, timeoutLsv2Client— TCP framing, CRC-16/CCITT, login (SELECT+LOG_IN), ReceiveFile/SendFileHeidenhainMachine : ICncMachine— RunGuardedAsync pattern, state machine
Phase 3 — Siemens + Mitsubishi FTP
SiemensConnectionConfig/SiemensFtpClient/SiemensMachine : ICncMachineMitsubishiConnectionConfig/MitsubishiFtpClient/MitsubishiMachine : ICncMachine
Phase 4 — Wiring
CncMachineFactory— creates rightICncMachinefromInputArgsInputArgs— addedmanufacturer,username,passwordfieldsProgram.cs— full rewrite usingICncMachine; Fanuc 3-file viaIFanucMachinecast
Phase 5 — NC Validator
ValidationSeverity/ValidationError/ValidationResultmodel typesINcProgramValidator+NcProgramValidator(5 universal + per-manufacturer rules)- Validator injected into all 4 machine classes; upload blocked on Error severity
NcProgramValidatorTests— 30+ NUnit tests
Test Infrastructure
NcProgramManager.Tests/— NUnit 3.13.3 + Moq 4.18.4, .NET 4.7.2FtpServerStub+Lsv2ServerStub— in-process TCP stubs- Unit + integration tests; Fanuc FOCAS tests
[Ignore]d (Windows-only DLL)
What Was Built (v0.2 NcProgramManager — complete)
Phase 06 — Rename Cleanup
- Namespace:
FanucProgramManager.*→NcProgramManager.*(all files) - Project renamed, test folder renamed, dead
FANUCMachine.csdeleted
Phase 07 — License Core
IMachineFingerprint/ILicenseValidatorinterfacesMachineFingerprint— WMI CPU/BIOS fingerprintLicenseFile.TryRead— reads.licfile, returns base64 signatureLicenseValidator.Validate— RSA-SHA256 verifyLicenseValidatorTests— 6 unit tests (testable via internal ctor injection)
Phase 08 — License Integration
Program.cs— RSA check wired at startup;checkLicensedeleted;license.licnext to EXEInputArgs.cs—-chiave=field removed
Phase 09 — License Generator
LicenseGeneratorstandalone console tool (separate repo:ssh://git@3nt-git.duckdns.org:222/davide.trentin/license-generator.git)- Commands:
keygen(RSA 2048-bit pair),fingerprint(WMI, Windows),sign(RSA-SHA256 → .lic) - Real public key embedded in
Licensing/LicenseValidator.cs(PLACEHOLDER removed) private.key.xmlat~/Documents/mine/c#/LicenseGenerator/(gitignored — keep secure)
Phase 10 — README Docs
README.mdin NcProgramManager root — Italian, operator-facing: CLI args, license setup, examples, controllers tableREADME.mdin LicenseGenerator repo — Italian, vendor-facing: keygen first-run, 4-step license issuance workflow, commands table, security
CLI Args (current — all 16)
-azione=— action (Scarica/Invia)-manufacturer=fanuc|heidenhain|siemens|mitsubishi(default: fanuc)-ip=— CNC IP (Ethernet)-porta=— port (Ethernet)-tipo=— connection type: 3=Ethernet, 2=HSSB (Fanuc legacy)-nodo=— HSSB node (Fanuc only)-username=(Heidenhain/Siemens/Mitsubishi)-password=(Heidenhain/Siemens/Mitsubishi)-pathprogramma=— local file path (required for Invia)-path=— CNC program path; default 1 = //CNC_MEM/USER/PATH1/-workzero=— include work zero offset-tooloffset=— include tool offset-commento=— program comment-compatibility— compatibility mode flag-debug=— keep terminal open after operation-help— show help and exit- License: place
license.licnext to EXE (no CLI arg)
Accumulated Context
Decisions
- .NET 4.7.2 locked — max compatibility
- RSA asymmetric offline licensing: private key vendor-only, public key embedded in binary
license.licalways atAppDomain.CurrentDomain.BaseDirectory— no CLI overrideRSACryptoServiceProvider+SHA256CryptoServiceProvider(not HashAlgorithmName) — .NET 4.7.2 compat- Constructor injection pattern: internal ctor accepts key XML — testable without Windows WMI
- LicenseGenerator: standalone separate repo — vendor tool, never shipped to customers
- Heidenhain: LSV2 port 19000, needs real hardware testing
- Siemens: FTP
/_N_MPF_DIR/, needs Sinumerik FTP option enabled on machine #= Warning in Fanuc/Mitsubishi — macro variable indicator- NLog console target
levels="Info",${message}layout — all operator output through NLog; Warn/Error file only - Cleanup catches: comment-only, no log — Dispose must not throw; logging infra can fail
Deferred Issues
Tracked in .paul/ISSUES.md — 11 issues total; 7 closed (ISS-001, ISS-003, ISS-004, ISS-005, ISS-006, ISS-007, ISS-008 partial).
Key open items:
- ISS-002: Blocking .GetAwaiter().GetResult() — Medium, refactor
- ISS-008: Full closure needs real Windows hardware run with env vars set
- ISS-009/010: Heidenhain/Siemens ReadActiveProgram not implemented — deferred
private.key.xmlowned by root (external repo) — runsudo chown $USER ~/Documents/mine/c#/LicenseGenerator/private.key.xml
Blockers/Concerns
None — v0.5 complete.
Git State
Last commit: 68c5a55 — chore(paul): close v0.6 Fagor Support milestone, log ISS-012..017
LicenseGenerator repo: commit 2ef68dd — feat: initial LicenseGenerator
Branch: main
Uncommitted (pre-Phase 17 work, to fold into 17-01):
- Program.cs —
#if !DEBUGwrap license check - NcProgramManager.csproj — Obfuscate target (Release-only)
- NcProgramManager.crproj — ConfuserEx config
- tools/ConfuserEx/ — CLI 1.6.0 (vendored; consider gitignore)
- 4 test files —
result.Error→string.Join("; ", result.Errors)fix
Codebase Mapped
Date: 2026-05-18
Documents: .paul/codebase/ (7 files — STACK, ARCHITECTURE, STRUCTURE, CONVENTIONS, TESTING, INTEGRATIONS, CONCERNS)
Session Continuity
Last session: 2026-05-25 Stopped at: Milestone v0.7 Build Hardening created (phases 17 + 18 scaffolded) Next action: /paul:plan for Phase 17 (build-pipeline) Resume file: .paul/ROADMAP.md
STATE.md — Updated after every significant action