fix: validate base messages the same way in sm and peer

Merged
GO
15d ago
+2114-144

Part 3 of the protocol contract decided in #108. The base capability,
watchdog and disconnect messages were only partly checked, by parsers
that differed between sm and peer, and the Manager ignored the optional
validation settings.

  • CER, CEA, DWR, DWA, DPR and DPA are always checked against RFC 6733
    §§3.2, 5.3.1-5.5.2 and 6.3: base header, required fields, types and
    multiplicity, Origin-Host and Origin-Realm syntax (§4.3.1), no
    Supported-Vendor-Id of zero (§5.3.6), and no Destination-Host or
    Destination-Realm in answers (§6.2). A malformed request gets one error
    answer with a single Failed-AVP (Verified Errata ID 4615); a malformed
    answer is discarded and reported.
  • A received answer may use the generic error grammar of §7.2 with a
    3xxx or 5xxx Result-Code (§§7.1.3, 7.1.5), but not with 2xxx or 4xxx
    (§7.1.4). Answers this library sends still set the E bit only for 3xxx.
  • peer.Manager honours RejectUnknownMandatoryAVPs and ValidateRequests
    with the same pipeline and order as StateMachine (advertised
    application, then unknown mandatory AVPs per §4.1, then dictionary
    validation), and routes nothing after a rejection. Both stay off by
    default.

Refs #108

Validation

  • make check passes locally for all modules: format, test (Go 1.27.2 and
    1.26.9), race, vet, lint, vuln, windows, secrets and codeql.
  • Wire tests over TCP, written to fail on main first, cover omitted and duplicated
    required fields, wrong types and flags, Application-Id, malformed identities,
    Supported-Vendor-Id zero, destination AVPs in answers, E-bit answers with each
    result class, nested unknown mandatory AVPs and every flag combination, through
    both front ends; mutating any rule fails a named test.
  • Two review rounds found that received E-bit 5xxx answers were rejected and that
    a few prohibited values passed; both are fixed.

Summary by cubic

Implements the base message validation from #108 so the six connection-level messages (CER/CEA, DWR/DWA, DPR/DPA) are checked identically in both sm and peer front ends. Previously these were only partly checked by parsers that differed between front ends, and peer.Manager ignored the optional validation settings.

  • Base messages are now always validated against RFC 6733 grammar: header, required fields, types, multiplicity, identity syntax, Supported-Vendor-Id, and destination AVPs in answers. Malformed requests get one error answer with a single Failed-AVP; malformed answers are discarded and reported.
  • peer.Manager now honors RejectUnknownMandatoryAVPs and ValidateRequests using the same pipeline and order as StateMachine; both settings stay off by default.
  • Received answers may use the generic error grammar for 3xxx or 5xxx Result-Codes, but not for 2xxx or 4xxx. Answers this library sends still set the error bit only for 3xxx.