Bugzilla – Attachment 3089 Details for
Bug 2408
Expose authentication information to PAM
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
expose SSH_AUTH_INFO_0 to PAM auth
expose_auth.patch (text/plain), 17.84 KB, created by
Radoslaw Ejsmont
on 2017-11-23 07:40:58 AEDT
(
hide
)
Description:
expose SSH_AUTH_INFO_0 to PAM auth
Filename:
MIME Type:
Creator:
Radoslaw Ejsmont
Created:
2017-11-23 07:40:58 AEDT
Size:
17.84 KB
patch
obsolete
>diff -Naur openssh-7.2p2/auth-pam.c openssh-7.2p2-patched/auth-pam.c >--- openssh-7.2p2/auth-pam.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/auth-pam.c 2017-11-22 12:32:21.000000000 +0100 >@@ -688,6 +688,11 @@ > return (NULL); > } > >+ /* Notify PAM about any already successful auth methods */ >+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY && >+ authctxt->auth_details) >+ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); >+ > ctxt = xcalloc(1, sizeof *ctxt); > > /* Start the authentication thread */ >diff -Naur openssh-7.2p2/auth.h openssh-7.2p2-patched/auth.h >--- openssh-7.2p2/auth.h 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/auth.h 2017-11-22 12:46:44.000000000 +0100 >@@ -80,6 +80,9 @@ > Buffer *loginmsg; > void *methoddata; > >+ char *last_details; >+ char *auth_details; >+ > struct sshkey **prev_userkeys; > u_int nprev_userkeys; > }; >diff -Naur openssh-7.2p2/auth2-gss.c openssh-7.2p2-patched/auth2-gss.c >--- openssh-7.2p2/auth2-gss.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/auth2-gss.c 2017-11-22 12:32:21.000000000 +0100 >@@ -275,6 +275,9 @@ > authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, > authctxt->pw)); > >+ if (authenticated) >+ authctxt->last_details = ssh_gssapi_get_displayname(); >+ > authctxt->postponed = 0; > dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); > dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); >@@ -314,6 +317,9 @@ > else > logit("GSSAPI MIC check failed"); > >+ if (authenticated) >+ authctxt->last_details = ssh_gssapi_get_displayname(); >+ > buffer_free(&b); > free(mic.value); > >diff -Naur openssh-7.2p2/auth2-hostbased.c openssh-7.2p2-patched/auth2-hostbased.c >--- openssh-7.2p2/auth2-hostbased.c 2016-03-09 19:04:48.000000000 +0100 >+++ openssh-7.2p2-patched/auth2-hostbased.c 2017-11-22 12:49:49.000000000 +0100 >@@ -60,7 +60,7 @@ > { > Buffer b; > Key *key = NULL; >- char *pkalg, *cuser, *chost, *service; >+ char *pkalg, *cuser, *chost, *service, *pubkey; > u_char *pkblob, *sig; > u_int alen, blen, slen; > int pktype; >@@ -132,15 +132,21 @@ > buffer_dump(&b); > #endif > >- pubkey_auth_info(authctxt, key, >- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); >+ pubkey = key_format_oneline(key); >+ auth_info(authctxt, >+ "%s, client user \"%.100s\", client host \"%.100s\"", >+ pubkey, cuser, chost); > > /* test for allowed key and correct signature */ > authenticated = 0; > if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && > PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), >- buffer_len(&b))) == 1) >+ buffer_len(&b))) == 1) { > authenticated = 1; >+ authctxt->last_details = pubkey; >+ } else { >+ free(pubkey); >+ } > > buffer_free(&b); > done: >@@ -202,7 +208,7 @@ > } > debug2("%s: access allowed by auth_rhosts2", __func__); > >- if (key_is_cert(key) && >+ if (key_is_cert(key) && > key_cert_check_authority(key, 1, 0, lookup, &reason)) { > error("%s", reason); > auth_debug_add("%s", reason); >diff -Naur openssh-7.2p2/auth2-pubkey.c openssh-7.2p2-patched/auth2-pubkey.c >--- openssh-7.2p2/auth2-pubkey.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/auth2-pubkey.c 2017-11-22 13:18:44.000000000 +0100 >@@ -79,7 +79,7 @@ > { > Buffer b; > Key *key = NULL; >- char *pkalg, *userstyle, *fp = NULL; >+ char *pkalg, *userstyle, *pubkey, *fp = NULL; > u_char *pkblob, *sig; > u_int alen, blen, slen; > int have_sig, pktype; >@@ -171,7 +171,9 @@ > #ifdef DEBUG_PK > buffer_dump(&b); > #endif >- pubkey_auth_info(authctxt, key, NULL); >+ >+ pubkey = key_format_oneline(key); >+ auth_info(authctxt, "%s", pubkey); > > /* test for correct signature */ > authenticated = 0; >@@ -182,6 +184,9 @@ > /* Record the successful key to prevent reuse */ > auth2_record_userkey(authctxt, key); > key = NULL; /* Don't free below */ >+ authctxt->last_details = pubkey; >+ } else { >+ free(pubkey); > } > buffer_free(&b); > free(sig); >@@ -222,7 +227,7 @@ > void > pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) > { >- char *fp, *extra; >+ char *extra, *pubkey; > va_list ap; > int i; > >@@ -232,27 +237,14 @@ > i = vasprintf(&extra, fmt, ap); > va_end(ap); > if (i < 0 || extra == NULL) >- fatal("%s: vasprintf failed", __func__); >+ fatal("%s: vasprintf failed", __func__); > } > >- if (key_is_cert(key)) { >- fp = sshkey_fingerprint(key->cert->signature_key, >- options.fingerprint_hash, SSH_FP_DEFAULT); >- auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", >- key_type(key), key->cert->key_id, >- (unsigned long long)key->cert->serial, >- key_type(key->cert->signature_key), >- fp == NULL ? "(null)" : fp, >- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); >- free(fp); >- } else { >- fp = sshkey_fingerprint(key, options.fingerprint_hash, >- SSH_FP_DEFAULT); >- auth_info(authctxt, "%s %s%s%s", key_type(key), >- fp == NULL ? "(null)" : fp, >- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); >- free(fp); >- } >+ pubkey = key_format_oneline(key); >+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", >+ extra == NULL ? "" : extra); >+ free(pubkey); >+ > free(extra); > } > >diff -Naur openssh-7.2p2/auth2.c openssh-7.2p2-patched/auth2.c >--- openssh-7.2p2/auth2.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/auth2.c 2017-11-22 12:32:21.000000000 +0100 >@@ -301,6 +301,7 @@ > const char *submethod) > { > char *methods; >+ char *prev_auth_details; > int partial = 0; > > if (!authctxt->valid && authenticated) >@@ -331,6 +332,18 @@ > if (authctxt->postponed) > return; > >+ if (authenticated || partial) { >+ prev_auth_details = authctxt->auth_details; >+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", >+ prev_auth_details ? prev_auth_details : "", >+ prev_auth_details ? ", " : "", method, >+ authctxt->last_details ? ": " : "", >+ authctxt->last_details ? authctxt->last_details : ""); >+ free(prev_auth_details); >+ } >+ free(authctxt->last_details); >+ authctxt->last_details = NULL; >+ > #ifdef USE_PAM > if (options.use_pam && authenticated) { > if (!PRIVSEP(do_pam_account())) { >diff -Naur openssh-7.2p2/gss-serv.c openssh-7.2p2-patched/gss-serv.c >--- openssh-7.2p2/gss-serv.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/gss-serv.c 2017-11-22 12:32:21.000000000 +0100 >@@ -464,6 +464,16 @@ > return (0); > } > >+/* Privileged */ >+char* >+ssh_gssapi_get_displayname(void) >+{ >+ if (gssapi_client.displayname.length != 0 && >+ gssapi_client.displayname.value != NULL) >+ return strdup((char *)gssapi_client.displayname.value); >+ return NULL; >+} >+ > /* These bits are only used for rekeying. The unpriviledged child is running > * as the user, the monitor is root. > * >diff -Naur openssh-7.2p2/key.c openssh-7.2p2-patched/key.c >--- openssh-7.2p2/key.c 2016-03-09 19:04:48.000000000 +0100 >+++ openssh-7.2p2-patched/key.c 2017-11-22 19:15:56.000000000 +0100 >@@ -288,6 +288,27 @@ > return ret; > } > >+char * >+key_format_oneline(const Key *key) >+{ >+ char *fp, *result; >+ >+ if (sshkey_is_cert(key)) { >+ fp = sshkey_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); >+ xasprintf(&result, "%s ID %s (serial %llu) CA %s %s", >+ sshkey_type(key), key->cert->key_id, >+ (unsigned long long)key->cert->serial, >+ sshkey_type(key->cert->signature_key), fp); >+ free(fp); >+ } else { >+ fp = sshkey_selected_fingerprint(key, SSH_FP_HEX); >+ xasprintf(&result, "%s %s", key_type(key), fp); >+ free(fp); >+ } >+ >+ return result; >+} >+ > /* authfile.c */ > > int >@@ -423,4 +444,3 @@ > { > return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; > } >- >diff -Naur openssh-7.2p2/key.h openssh-7.2p2-patched/key.h >--- openssh-7.2p2/key.h 2016-03-09 19:04:48.000000000 +0100 >+++ openssh-7.2p2-patched/key.h 2017-11-22 13:25:27.000000000 +0100 >@@ -90,6 +90,7 @@ > > void key_private_serialize(const Key *, struct sshbuf *); > Key *key_private_deserialize(struct sshbuf *); >+char *key_format_oneline(const Key *key); > > /* authfile.c */ > int key_save_private(Key *, const char *, const char *, const char *, >diff -Naur openssh-7.2p2/monitor.c openssh-7.2p2-patched/monitor.c >--- openssh-7.2p2/monitor.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/monitor.c 2017-11-22 13:39:21.000000000 +0100 >@@ -345,6 +345,7 @@ > { > struct mon_table *ent; > int authenticated = 0, partial = 0; >+ char *prev_auth_details; > > debug3("preauth child monitor started"); > >@@ -380,6 +381,18 @@ > auth_submethod = NULL; > authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); > >+ if (authenticated) { >+ prev_auth_details = authctxt->auth_details; >+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", >+ prev_auth_details ? prev_auth_details : "", >+ prev_auth_details ? ", " : "", auth_method, >+ authctxt->last_details ? ": " : "", >+ authctxt->last_details ? authctxt->last_details : ""); >+ free(prev_auth_details); >+ } >+ free(authctxt->last_details); >+ authctxt->last_details = NULL; >+ > /* Special handling for multiple required authentications */ > if (options.num_auth_methods != 0) { > if (!compat20) >@@ -478,7 +491,7 @@ > #ifdef GSSAPI > /* and for the GSSAPI key exchange */ > monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); >-#endif >+#endif > } else { > mon_dispatch = mon_dispatch_postauth15; > monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); >@@ -1488,6 +1501,9 @@ > debug3("%s: key %p signature %s", > __func__, key, (verified == 1) ? "verified" : "unverified"); > >+ if (verified == 1) >+ authctxt->last_details = key_format_oneline(key); >+ > /* If auth was successful then record key to ensure it isn't reused */ > if (verified == 1 && key_blobtype == MM_USERKEY) > auth2_record_userkey(authctxt, key); >@@ -2104,7 +2120,7 @@ > if (!options.gss_authentication && !options.gss_keyex) > fatal("In GSSAPI monitor when GSSAPI is disabled"); > >- authenticated = authctxt->valid && >+ authenticated = authctxt->valid && > ssh_gssapi_userok(authctxt->user, authctxt->pw); > > buffer_clear(m); >@@ -2115,11 +2131,14 @@ > > auth_method = "gssapi-with-mic"; > >+ if (authenticated) >+ authctxt->last_details = ssh_gssapi_get_displayname(); >+ > /* Monitor loop will terminate if authenticated */ > return (authenticated); > } > >-int >+int > mm_answer_gss_sign(int socket, Buffer *m) > { > gss_buffer_desc data; >@@ -2132,8 +2151,8 @@ > > data.value = buffer_get_string(m, &len); > data.length = len; >- if (data.length != 20) >- fatal("%s: data length incorrect: %d", __func__, >+ if (data.length != 20) >+ fatal("%s: data length incorrect: %d", __func__, > (int) data.length); > > /* Save the session ID on the first time around */ >@@ -2156,7 +2175,7 @@ > > /* Turn on getpwnam permissions */ > monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); >- >+ > /* And credential updating, for when rekeying */ > monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); > >@@ -2187,4 +2206,3 @@ > } > > #endif /* GSSAPI */ >- >diff -Naur openssh-7.2p2/servconf.c openssh-7.2p2-patched/servconf.c >--- openssh-7.2p2/servconf.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/servconf.c 2017-11-22 13:46:23.000000000 +0100 >@@ -172,6 +172,7 @@ > options->version_addendum = NULL; > options->fingerprint_hash = -1; > options->debian_banner = -1; >+ options->expose_auth_methods = -1; > } > > /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ >@@ -399,6 +400,8 @@ > } > #endif > >+ if (options->expose_auth_methods == -1) >+ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; > } > > /* Keyword tokens. */ >@@ -441,6 +444,7 @@ > sStreamLocalBindMask, sStreamLocalBindUnlink, > sAllowStreamLocalForwarding, sFingerprintHash, > sDebianBanner, >+ sExposeAuthenticationMethods, > sDeprecated, sUnsupported > } ServerOpCodes; > >@@ -593,6 +597,7 @@ > { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, > { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, > { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, >+ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, > { NULL, sBadOption, 0 } > }; > >@@ -981,6 +986,12 @@ > { "local", FORWARD_LOCAL }, > { NULL, -1 } > }; >+static const struct multistate multistate_exposeauthmeth[] = { >+ { "never", EXPOSE_AUTHMETH_NEVER }, >+ { "pam-only", EXPOSE_AUTHMETH_PAMONLY }, >+ { "pam-and-env", EXPOSE_AUTHMETH_PAMENV }, >+ { NULL, -1} >+}; > > int > process_server_config_line(ServerOptions *options, char *line, >@@ -1883,6 +1894,11 @@ > intptr = &options->debian_banner; > goto parse_int; > >+ case sExposeAuthenticationMethods: >+ intptr = &options->expose_auth_methods; >+ multistate_ptr = multistate_exposeauthmeth; >+ goto parse_multistate; >+ > case sDeprecated: > logit("%s line %d: Deprecated option %s", > filename, linenum, arg); >@@ -2037,6 +2053,7 @@ > M_CP_INTOPT(ip_qos_bulk); > M_CP_INTOPT(rekey_limit); > M_CP_INTOPT(rekey_interval); >+ M_CP_INTOPT(expose_auth_methods); > > /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ > #define M_CP_STROPT(n) do {\ >@@ -2140,6 +2157,8 @@ > return fmt_multistate_int(val, multistate_tcpfwd); > case sFingerprintHash: > return ssh_digest_alg_name(val); >+ case sExposeAuthenticationMethods: >+ return fmt_multistate_int(val, multistate_exposeauthmeth); > case sProtocol: > switch (val) { > case SSH_PROTO_1: >@@ -2329,6 +2348,7 @@ > dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); > dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); > dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); >+ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); > > /* string arguments */ > dump_cfg_string(sPidFile, o->pid_file); >diff -Naur openssh-7.2p2/servconf.h openssh-7.2p2-patched/servconf.h >--- openssh-7.2p2/servconf.h 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/servconf.h 2017-11-22 13:42:12.000000000 +0100 >@@ -48,6 +48,11 @@ > #define FORWARD_LOCAL (1<<1) > #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) > >+/* Expose AuthenticationMethods */ >+#define EXPOSE_AUTHMETH_NEVER 0 >+#define EXPOSE_AUTHMETH_PAMONLY 1 >+#define EXPOSE_AUTHMETH_PAMENV 2 >+ > #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ > #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ > >@@ -195,7 +200,8 @@ > > u_int num_auth_methods; > char *auth_methods[MAX_AUTH_METHODS]; >- >+ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ >+ > int fingerprint_hash; > > int debian_banner; >diff -Naur openssh-7.2p2/session.c openssh-7.2p2-patched/session.c >--- openssh-7.2p2/session.c 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/session.c 2017-11-22 12:32:21.000000000 +0100 >@@ -1151,6 +1151,12 @@ > } > *var_val++ = '\0'; > >+ if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV && >+ strcmp(var_name, "SSH_USER_AUTH") == 0) { >+ free(var_name); >+ continue; >+ } >+ > debug3("Copy environment: %s=%s", var_name, var_val); > child_set_env(env, envsize, var_name, var_val); > >@@ -1330,6 +1336,11 @@ > } > #endif /* USE_PAM */ > >+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV && >+ s->authctxt->auth_details) >+ child_set_env(&env, &envsize, "SSH_USER_AUTH", >+ s->authctxt->auth_details); >+ > if (auth_sock_name != NULL) > child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, > auth_sock_name); >@@ -2769,6 +2780,9 @@ > if (authctxt == NULL) > return; > >+ free(authctxt->auth_details); >+ authctxt->auth_details = NULL; >+ > #ifdef USE_PAM > if (options.use_pam) { > sshpam_cleanup(); >diff -Naur openssh-7.2p2/ssh-gss.h openssh-7.2p2-patched/ssh-gss.h >--- openssh-7.2p2/ssh-gss.h 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/ssh-gss.h 2017-11-22 12:32:21.000000000 +0100 >@@ -151,6 +151,7 @@ > const char *); > OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); > int ssh_gssapi_userok(char *name, struct passwd *); >+char* ssh_gssapi_get_displayname(void); > OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); > void ssh_gssapi_do_child(char ***, u_int *); > void ssh_gssapi_cleanup_creds(void); >diff -Naur openssh-7.2p2/ssh.1 openssh-7.2p2-patched/ssh.1 >--- openssh-7.2p2/ssh.1 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/ssh.1 2017-11-22 12:32:21.000000000 +0100 >@@ -1416,6 +1416,10 @@ > This variable contains the original command line if a forced command > is executed. > It can be used to extract the original arguments. >+.It Ev SSH_USER_AUTH >+This variable contains, for SSH2 only, a comma-separated list of authentication >+methods that were successfuly used to authenticate. When possible, these >+methods are extended with detailed information on the credential used. > .It Ev SSH_TTY > This is set to the name of the tty (path to the device) associated > with the current shell or command. >diff -Naur openssh-7.2p2/sshd_config.5 openssh-7.2p2-patched/sshd_config.5 >--- openssh-7.2p2/sshd_config.5 2017-11-21 20:25:16.000000000 +0100 >+++ openssh-7.2p2-patched/sshd_config.5 2017-11-22 13:49:59.000000000 +0100 >@@ -607,6 +607,21 @@ > .Dq sha256 . > The default is > .Dq sha256 . >+.It Cm ExposeAuthenticationMethods >+When using SSH2, this option controls the exposure of the list of >+successful authentication methods to PAM during the authentication >+and to the shell environment via the >+.Cm SSH_USER_AUTH >+variable. See the description of this variable for more details. >+Valid options are: >+.Dq never >+(Do not expose successful authentication methods), >+.Dq pam-only >+(Only expose them to PAM during authentication, not afterwards), >+.Dq pam-and-env >+(Expose them to PAM and keep them in the shell environment). >+The default is >+.Dq never . > .It Cm ForceCommand > Forces the execution of the command specified by > .Cm ForceCommand , >@@ -678,8 +693,8 @@ > The default is > .Dq yes . > .It Cm GSSAPIStoreCredentialsOnRekey >-Controls whether the user's GSSAPI credentials should be updated following a >-successful connection rekeying. This option can be used to accepted renewed >+Controls whether the user's GSSAPI credentials should be updated following a >+successful connection rekeying. This option can be used to accepted renewed > or updated credentials from a compatible client. The default is > .Dq no . > .It Cm HostbasedAcceptedKeyTypes
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2408
:
2754
|
2791
|
2792
|
2812
|
2846
|
2978
|
2980
|
2999
|
3022
|
3089
|
3091