Bugzilla – Attachment 2754 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 successful auth methods via environments (pam and shell)
Expose valid auth methods.patch (text/plain), 8.13 KB, created by
Vincent Brillault
on 2015-11-20 08:43:00 AEDT
(
hide
)
Description:
Expose successful auth methods via environments (pam and shell)
Filename:
MIME Type:
Creator:
Vincent Brillault
Created:
2015-11-20 08:43:00 AEDT
Size:
8.13 KB
patch
obsolete
>diff --git a/auth-pam.c b/auth-pam.c >index d94c828..815c833 100644 >--- a/auth-pam.c >+++ b/auth-pam.c >@@ -688,6 +688,10 @@ sshpam_init_ctx(Authctxt *authctxt) > return (NULL); > } > >+ /* Notify PAM about any already successful auth methods */ >+ if (authctxt->auth_details) >+ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); >+ > ctxt = xcalloc(1, sizeof *ctxt); > > /* Start the authentication thread */ >diff --git a/auth.h b/auth.h >index fffbe6c..8a55f72 100644 >--- a/auth.h >+++ b/auth.h >@@ -81,6 +81,9 @@ struct Authctxt { > > struct sshkey **prev_userkeys; > u_int nprev_userkeys; >+ >+ char *last_details; >+ char *auth_details; > }; > /* > * Every authentication method has to handle authentication requests for >@@ -127,6 +130,7 @@ int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); > int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); > int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); > int user_key_allowed(struct passwd *, Key *, int); >+char *pubkey_format(const Key *key); > void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) > __attribute__((__format__ (printf, 3, 4))); > void auth2_record_userkey(Authctxt *, struct sshkey *); >diff --git a/auth2-hostbased.c b/auth2-hostbased.c >index e2327cf..856efc9 100644 >--- a/auth2-hostbased.c >+++ b/auth2-hostbased.c >@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) > { > 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 @@ userauth_hostbased(Authctxt *authctxt) > buffer_dump(&b); > #endif > >- pubkey_auth_info(authctxt, key, >- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); >+ pubkey = pubkey_format(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: >diff --git a/auth2-pubkey.c b/auth2-pubkey.c >index b1b5b74..170cd24 100644 >--- a/auth2-pubkey.c >+++ b/auth2-pubkey.c >@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) > { > Buffer b; > Key *key = NULL; >- char *pkalg, *userstyle; >+ char *pkalg, *userstyle, *pubkey; > u_char *pkblob, *sig; > u_int alen, blen, slen; > int have_sig, pktype; >@@ -168,7 +168,8 @@ userauth_pubkey(Authctxt *authctxt) > #ifdef DEBUG_PK > buffer_dump(&b); > #endif >- pubkey_auth_info(authctxt, key, NULL); >+ pubkey = pubkey_format(key); >+ auth_info(authctxt, "%s", pubkey); > > /* test for correct signature */ > authenticated = 0; >@@ -176,9 +177,12 @@ userauth_pubkey(Authctxt *authctxt) > PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > buffer_len(&b))) == 1) { > authenticated = 1; >+ authctxt->last_details = pubkey; > /* Record the successful key to prevent reuse */ > auth2_record_userkey(authctxt, key); > key = NULL; /* Don't free below */ >+ } else { >+ free(pubkey); > } > buffer_free(&b); > free(sig); >@@ -214,40 +218,50 @@ done: > return authenticated; > } > >-void >-pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) >+char * >+pubkey_format(const Key *key) > { >- char *fp, *extra; >- va_list ap; >- int i; >- >- extra = NULL; >- if (fmt != NULL) { >- va_start(ap, fmt); >- i = vasprintf(&extra, fmt, ap); >- va_end(ap); >- if (i < 0 || extra == NULL) >- fatal("%s: vasprintf failed", __func__); >- } >+ char *fp, *result; > > 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", >+ xasprintf(&result, "%s ID %s (serial %llu) CA %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); >+ fp == NULL ? "(null)" : fp); > 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); >+ xasprintf(&result, "%s %s", key_type(key), >+ fp == NULL ? "(null)" : fp); > free(fp); > } >+ >+ return result; >+} >+ >+void >+pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) >+{ >+ char *extra, *pubkey; >+ va_list ap; >+ int i; >+ >+ extra = NULL; >+ if (fmt != NULL) { >+ va_start(ap, fmt); >+ i = vasprintf(&extra, fmt, ap); >+ va_end(ap); >+ if (i < 0 || extra == NULL) >+ fatal("%s: vasprintf failed", __func__); >+ } >+ >+ pubkey = pubkey_format(key); >+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", >+ extra == NULL ? "" : extra); > free(extra); > } > >diff --git a/auth2.c b/auth2.c >index 7177962..99eb750 100644 >--- a/auth2.c >+++ b/auth2.c >@@ -293,6 +293,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, > const char *submethod) > { > char *methods; >+ char *prev_auth_details; > int partial = 0; > > if (!authctxt->valid && authenticated) >@@ -323,6 +324,18 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, > 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(authctxt->last_details); >+ authctxt->last_details = NULL; >+ free(prev_auth_details); >+ } >+ > #ifdef USE_PAM > if (options.use_pam && authenticated) { > if (!PRIVSEP(do_pam_account())) { >diff --git a/monitor.c b/monitor.c >index 395a6f6..c6b2236 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -335,6 +335,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > { > struct mon_table *ent; > int authenticated = 0, partial = 0; >+ char *prev_auth_details; > > debug3("preauth child monitor started"); > >@@ -366,6 +367,14 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > 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", >+ prev_auth_details ? prev_auth_details : "", >+ prev_auth_details ? ", " : "", auth_method); >+ free(prev_auth_details); >+ } >+ > /* Special handling for multiple required authentications */ > if (options.num_auth_methods != 0) { > if (!compat20) >diff --git a/session.c b/session.c >index 26f4742..a54dbe0 100644 >--- a/session.c >+++ b/session.c >@@ -1307,6 +1307,10 @@ do_setup_env(Session *s, const char *shell) > } > #endif /* USE_PAM */ > >+ if (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); >@@ -2735,6 +2739,9 @@ do_cleanup(Authctxt *authctxt) > if (authctxt == NULL) > return; > >+ free(authctxt->auth_details); >+ authctxt->auth_details = NULL; >+ > #ifdef USE_PAM > if (options.use_pam) { > sshpam_cleanup(); >diff --git a/ssh.1 b/ssh.1 >index 5b35b6c..1af89b3 100644 >--- a/ssh.1 >+++ b/ssh.1 >@@ -1402,6 +1402,10 @@ server IP address, and server port number. > 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.
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