Bugzilla – Attachment 2791 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)
v2.patch (text/plain), 9.52 KB, created by
Vincent Brillault
on 2016-02-24 02:47:21 AEDT
(
hide
)
Description:
Expose successful auth methods via environments (pam and shell)
Filename:
MIME Type:
Creator:
Vincent Brillault
Created:
2016-02-24 02:47:21 AEDT
Size:
9.52 KB
patch
obsolete
>diff --git a/auth-pam.c b/auth-pam.c >index 8425af1..22cbc3d 100644 >--- a/auth-pam.c >+++ b/auth-pam.c >@@ -689,6 +689,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 2160154..b916067 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 >diff --git a/auth2-hostbased.c b/auth2-hostbased.c >index e2327cf..0cca46e 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 = sshkey_format_oneline(key, options.fingerprint_hash); >+ 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 41b34ae..08812e9 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, *fp = NULL; >+ char *pkalg, *userstyle, *pubkey, *fp = NULL; > u_char *pkblob, *sig; > u_int alen, blen, slen; > int have_sig, pktype; >@@ -171,7 +171,8 @@ userauth_pubkey(Authctxt *authctxt) > #ifdef DEBUG_PK > buffer_dump(&b); > #endif >- pubkey_auth_info(authctxt, key, NULL); >+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); >+ auth_info(authctxt, "%s", pubkey); > > /* test for correct signature */ > authenticated = 0; >@@ -179,9 +180,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); >@@ -222,7 +226,7 @@ done: > 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 +236,13 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) > 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 = sshkey_format_oneline(key, options.fingerprint_hash); >+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", >+ extra == NULL ? "" : extra); >+ free(pubkey); > 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 ac7dd30..4452fe0 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -334,6 +334,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"); > >@@ -365,6 +366,18 @@ 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%s%s", >+ prev_auth_details ? prev_auth_details : "", >+ prev_auth_details ? ", " : "", auth_method, >+ authctxt->last_details ? ": " : "", >+ authctxt->last_details ? authctxt->last_details : ""); >+ free(authctxt->last_details); >+ authctxt->last_details = NULL; >+ free(prev_auth_details); >+ } >+ > /* Special handling for multiple required authentications */ > if (options.num_auth_methods != 0) { > if (!compat20) >@@ -1445,6 +1458,10 @@ mm_answer_keyverify(int sock, Buffer *m) > debug3("%s: key %p signature %s", > __func__, key, (verified == 1) ? "verified" : "unverified"); > >+ if (verified == 1) >+ authctxt->last_details = sshkey_format_oneline(key, >+ options.fingerprint_hash); >+ > /* 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); >diff --git a/session.c b/session.c >index 7a02500..bf893a5 100644 >--- a/session.c >+++ b/session.c >@@ -1308,6 +1308,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); >@@ -2741,6 +2745,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 cc53343..a3c2556 100644 >--- a/ssh.1 >+++ b/ssh.1 >@@ -1391,6 +1391,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. >diff --git a/sshkey.c b/sshkey.c >index 87b093e..1655b0c 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -58,6 +58,7 @@ > #define SSHKEY_INTERNAL > #include "sshkey.h" > #include "match.h" >+#include "xmalloc.h" > > /* openssh private key file format */ > #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" >@@ -1189,6 +1190,30 @@ sshkey_fingerprint(const struct sshkey *k, int dgst_alg, > return retval; > } > >+char * >+sshkey_format_oneline(const struct sshkey *key, int dgst_alg) >+{ >+ char *fp, *result; >+ >+ if (sshkey_is_cert(key)) { >+ fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg, >+ SSH_FP_DEFAULT); >+ 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 == NULL ? "(null)" : fp); >+ free(fp); >+ } else { >+ fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT); >+ xasprintf(&result, "%s %s", sshkey_type(key), >+ fp == NULL ? "(null)" : fp); >+ free(fp); >+ } >+ >+ return result; >+} >+ > #ifdef WITH_SSH1 > /* > * Reads a multiple-precision integer in decimal from the buffer, and advances >diff --git a/sshkey.h b/sshkey.h >index a20a14f..3bcfbe6 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -123,6 +123,7 @@ char *sshkey_fingerprint(const struct sshkey *, > int, enum sshkey_fp_rep); > int sshkey_fingerprint_raw(const struct sshkey *k, > int, u_char **retp, size_t *lenp); >+char *sshkey_format_oneline(const struct sshkey *k, int dgst_alg); > const char *sshkey_type(const struct sshkey *); > const char *sshkey_cert_type(const struct sshkey *); > int sshkey_write(const struct sshkey *, FILE *);
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