nx_email_submit.nx
buildroot/runtime/nx_email_submit.nx
about
nx_email_submit.nx -- EMAIL RUNG R6: authenticated submission over TLS.
module: nishi-core.email.submit
depends: nishi-core.codec.base64
capability: CORE_EMAIL
The SEND capstone on the client side: take an authenticated, encrypted
path to a submission server (RFC 6409 ports 587 STARTTLS / 465 implicit
TLS) and log in before handing off to the R1 MAIL/RCPT/DATA flow. The
security-critical sequencing + credential encoding is pure and gated
here; the actual TLS handshake is performed by the existing nx_tls13
when the state machine emits TLS_UPGRADE (the live wiring lives in a
later nx_email_submit_io.nx).
AUTH PLAIN (RFC 4616): base64("\0authcid\0passwd"), composing the
canonical nx_base64 (not reimplemented).
AUTH LOGIN: base64(username) / base64(password) challenge tokens.
STARTTLS capability detection in the EHLO reply.
Submission state machine: 220 -> EHLO -> STARTTLS -> [TLS] -> EHLO ->
AUTH -> READY. CRUX SECURITY PROPERTY: if the server does NOT
offer STARTTLS the machine ABORTS rather than sending credentials
in cleartext.
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/ietf/rfc_6409 + rfc_4616 + rfc_3207
lineage_id: nishi_email_submit_r6
nx_safety_envelope:
intended_use: "Submission AUTH encode + STARTTLS sequencing.
Composes nx_tls13 for the upgrade (live: _io)."
sil_target: SIL3 (credential leak / downgrade)
evidence: [auth_plain_roundtrip, starttls_required_before_auth,
cleartext_creds_refused, port_select]
hazard_register: [bug-tape-STARTTLS-strip-downgrade, bug-tape-cred-cleartext]
residual_risk: "Live TLS handshake + post-AUTH MAIL/RCPT/DATA
reuse R1; OAUTHBEARER/XOAUTH2 are later."
verdict: NOT_YET_EVALUATED
dependencies 1 imports · 1 importers
imports: nx_base64.nx
imported by: nx_email_submit_gate.nx
structs
| none |
consts
| 42 | const SUB_INIT: i64 = 0 // await 220 greeting |
| 43 | const SUB_EHLO: i64 = 1 // EHLO sent, await 250 |
| 44 | const SUB_STARTTLS: i64 = 2 // STARTTLS sent, await 220 |
| 45 | const SUB_EHLO2: i64 = 3 // post-TLS EHLO sent, await 250 |
| 46 | const SUB_AUTH: i64 = 4 // AUTH sent, await 235 |
| 47 | const SUB_READY: i64 = 5 // authenticated; ready for MAIL FROM (R1) |
| 48 | const SUB_FAIL: i64 = 6 |
| 51 | const SUB_A_NONE: i64 = 0 |
| 52 | const SUB_A_EHLO: i64 = 1 |
| 53 | const SUB_A_STARTTLS: i64 = 2 |
| 54 | const SUB_A_TLS_UPGRADE: i64 = 3 // do nx_tls13 handshake, then resend EHLO |
| 55 | const SUB_A_AUTH: i64 = 4 |
| 56 | const SUB_A_READY: i64 = 5 |
| 57 | const SUB_A_ABORT: i64 = 6 |
functions
| 59 | func nx_submit_action_name(a: i64) -> *u8 |
| 69 | func sub_catn(out: *u8, oi: i64, s: *u8, len: i64) -> i64 |
| 74 | func sub_cat(out: *u8, oi: i64, s: *u8) -> i64 called by 1: nx_submit_auth_plain |
| 79 | func sub_is2xx(code: i64) -> i64 { if code >= 200 && code < 300 { return 1 } return 0 } called by 1: nx_submit_advance |
| 83 | func nx_submit_auth_plain(out: *u8, cap: i64, user: *u8, ulen: i64, pass: *u8, plen: i64, scratch: *u8) -> i64 |
| 99 | func nx_submit_auth_login_token(out: *u8, cap: i64, data: *u8, dlen: i64) -> i64 |
| 106 | func nx_submit_starttls_avail(resp: *u8, n: i64) -> i64 called by 1: main |
| 120 | func nx_submit_port(implicit_tls: i64) -> i64 called by 1: main |
| 127 | func nx_submit_advance(state: i64, code: i64, want_tls: i64, starttls_avail: i64, out_action: *i64) -> i64 |