A CGI submitting a batch job through the JES2 internal reader must place
a real USER=/PASSWORD= on the JOB card. Recovering the password by
re-decoding the request's Authorization: Basic header only works for
Basic auth and has no answer for the token flow, where the request
carries no password.
The password is already retained server-side: cred_login() Blowfish-
encrypts it into the persistent CRED (id.password) for the credential's
whole lifetime, including token-authenticated requests that resolve to
the same CRED. A CGI cannot simply decrypt it, because credid_dec()
reads the Blowfish key via credkey()/__wsaget() from the current GRT's
WSA, which is only initialized in httpd's own GRT. A CGI runs under its
own GRT (the #109 wall), so that key reads back as zero.
Cache the credkey() pointer in the HTTPD control block at cred_init()
time (in httpd's GRT, where credkey() is valid). The key bytes live at a
stable WSA address readable across the shared address space, so caching
the pointer is enough. Add the append-only HTTPX export
http_get_password(), which decrypts id.password with blowfish_decrypt()
using that cached key -- a pure function of (data, key) valid in any
GRT, never calling credkey()/__wsaget() from CGI context.
NULL-safe like the sibling accessors: returns NULL when unauthenticated
or when the credential carries no password (token-only session). The
returned password is RACF-canonical (upper-cased at login).
Fixes #111
Fixes #111
Summary
Adds an append-only HTTPX export,
http_get_password(), so a CGI (mvsMF) can obtain the caller's plaintext password to place a realUSER=/PASSWORD=on a JES2 internal-reader JOB card — for both Basic and token authentication.The password is already retained server-side:
cred_login()Blowfish-encrypts it into the persistentCRED(id.password) for the credential's whole lifetime, and a token request resolves to the sameCREDviacred_find_by_token(). A CGI cannot decrypt it directly becausecredid_dec()reads the Blowfish key viacredkey()/__wsaget()from the current GRT's WSA, which is only initialized in httpd's own GRT — a CGI runs under its own GRT where that key reads back as zero (the #109 wall).Changes
include/httpd.h— newCREDKEY *credkeyfield appended to theHTTPDblock (0x138); newhttp_get_passwordfunction pointer appended to theHTTPXvector (0x13C, append-only); extern prototype + public macro.src/httpd.c— cachecredkey()intohttpd->credkeyright aftercred_init()(runs in httpd's GRT, wherecredkey()is valid).src/httpxauth.c— implementhttp_get_password(). It reads the cached key pointer (nevercredkey()/__wsaget()) andblowfish_decrypt()shttpc->cred->id.password— a pure function of (data, key) valid in any GRT.src/httpx.c— wire the new entry into the static vector.docs/auth-redesign.md— add the export to the §2.4 list.Behavior
NULLwhen unauthenticated (httpc->cred == NULL), when the credential carries no password (token-only session,passflgwithoutCREDID_PASS_ENCRYPT), or when there is no room inout.cred_login()folds it before encrypting — correct for a JOB card.Security
For job submission the plaintext password is unavoidably needed by the CGI (it goes on the JOB card), so the "never hand back the decrypted password" principle can't hold here. The mitigation is to keep the key encapsulated in httpd (the CGI only receives the already-required plaintext) and have the caller
memsetits buffer immediately after building the JOB card. This is no more exposure than the current Basic-header decode, and it finally covers the token flow.Verification
make compiledbregenerated cleanly (120 entries); no new clangd diagnostics in the changed code (the remaining httpd.c/httpd.h clangd errors are pre-existing trigraph/MVS-builtin artifacts unrelated to this change).Consumer
Once merged, mvsMF's
process_jobcard()sourcesPASSWORD=fromhttp_get_password()and the userid fromhttp_get_userid(), dropsget_basic_auth_credentials(), and stops parsing theAuthorizationheader — job submit then works identically for Basic and token auth (mvslovers/mvsmf#164).