diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch index 43798ab..35bed50 100644 --- a/openssh-7.2p1-audit.patch +++ b/openssh-7.2p1-audit.patch @@ -792,9 +792,9 @@ diff -up openssh-7.2p1/auth2-hostbased.c.audit openssh-7.2p1/auth2-hostbased.c if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) + buffer_len(&b))) == 1) { authenticated = 1; - + authctxt->last_details = pubkey; @@ -163,6 +163,18 @@ done: return authenticated; } @@ -825,7 +825,7 @@ diff -up openssh-7.2p1/auth2-pubkey.c.audit openssh-7.2p1/auth2-pubkey.c + PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; - /* Record the successful key to prevent reuse */ + authctxt->last_details = pubkey; @@ -258,6 +258,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } diff --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index 023abaa..45ac0f0 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -634,8 +634,8 @@ diff -up openssh-7.2p1/sshkey.c.fips openssh-7.2p1/sshkey.c #include "sshkey.h" +#include "log.h" #include "match.h" + #include "xmalloc.h" - /* openssh private key file format */ @@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch new file mode 100644 index 0000000..49f6436 --- /dev/null +++ b/openssh-7.2p2-expose-pam.patch @@ -0,0 +1,517 @@ +diff -up openssh-7.2p2/auth2.c.expose-pam openssh-7.2p2/auth2.c +--- openssh-7.2p2/auth2.c.expose-pam 2016-07-18 12:30:12.064783302 +0200 ++++ openssh-7.2p2/auth2.c 2016-07-18 12:30:12.124783255 +0200 +@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int + const char *submethod) + { + char *methods; ++ char *prev_auth_details; + int partial = 0; + + if (!authctxt->valid && authenticated) +@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int + 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 -up openssh-7.2p2/auth2-gss.c.expose-pam openssh-7.2p2/auth2-gss.c +--- openssh-7.2p2/auth2-gss.c.expose-pam 2016-07-18 12:30:12.123783256 +0200 ++++ openssh-7.2p2/auth2-gss.c 2016-07-18 12:32:08.034692086 +0200 +@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, + 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); +@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple + else + logit("GSSAPI MIC check failed"); + ++ if (authenticated) ++ authctxt->last_details = ssh_gssapi_get_displayname(); ++ + buffer_free(&b); + if (micuser != authctxt->user) + free(micuser); +diff -up openssh-7.2p2/auth2-hostbased.c.expose-pam openssh-7.2p2/auth2-hostbased.c +--- openssh-7.2p2/auth2-hostbased.c.expose-pam 2016-07-18 12:30:12.027783331 +0200 ++++ openssh-7.2p2/auth2-hostbased.c 2016-07-18 12:30:12.124783255 +0200 +@@ -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; +@@ -140,15 +140,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 -up openssh-7.2p2/auth2-pubkey.c.expose-pam openssh-7.2p2/auth2-pubkey.c +--- openssh-7.2p2/auth2-pubkey.c.expose-pam 2016-07-18 12:30:12.039783322 +0200 ++++ openssh-7.2p2/auth2-pubkey.c 2016-07-18 12:30:12.124783255 +0200 +@@ -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; +@@ -173,7 +173,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; +@@ -181,9 +182,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); +@@ -224,7 +228,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; + +@@ -234,27 +238,13 @@ pubkey_auth_info(Authctxt *authctxt, con + 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 -up openssh-7.2p2/auth.h.expose-pam openssh-7.2p2/auth.h +--- openssh-7.2p2/auth.h.expose-pam 2016-07-18 12:30:12.077783292 +0200 ++++ openssh-7.2p2/auth.h 2016-07-18 12:30:12.123783256 +0200 +@@ -84,6 +84,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 -up openssh-7.2p2/auth-pam.c.expose-pam openssh-7.2p2/auth-pam.c +--- openssh-7.2p2/auth-pam.c.expose-pam 2016-07-18 12:30:12.026783332 +0200 ++++ openssh-7.2p2/auth-pam.c 2016-07-18 12:30:12.123783256 +0200 +@@ -689,6 +689,11 @@ sshpam_init_ctx(Authctxt *authctxt) + 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 -up openssh-7.2p2/gss-serv.c.expose-pam openssh-7.2p2/gss-serv.c +--- openssh-7.2p2/gss-serv.c.expose-pam 2016-07-18 12:30:12.124783255 +0200 ++++ openssh-7.2p2/gss-serv.c 2016-07-18 12:33:08.835644264 +0200 +@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int + } + + /* 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; ++} ++ ++/* Privileged */ + int + ssh_gssapi_userok(char *user, struct passwd *pw) + { +diff -up openssh-7.2p2/monitor.c.expose-pam openssh-7.2p2/monitor.c +--- openssh-7.2p2/monitor.c.expose-pam 2016-07-18 12:30:12.093783279 +0200 ++++ openssh-7.2p2/monitor.c 2016-07-18 12:30:12.124783255 +0200 +@@ -349,6 +349,7 @@ monitor_child_preauth(Authctxt *_authctx + { + struct mon_table *ent; + int authenticated = 0, partial = 0; ++ char *prev_auth_details; + + debug3("preauth child monitor started"); + +@@ -386,6 +387,18 @@ monitor_child_preauth(Authctxt *_authctx + 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) +@@ -1498,6 +1511,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); +@@ -2140,6 +2157,9 @@ mm_answer_gss_userok(int sock, Buffer *m + + auth_method = "gssapi-with-mic"; + ++ if (authenticated) ++ authctxt->last_details = ssh_gssapi_get_displayname(); ++ + /* Monitor loop will terminate if authenticated */ + return (authenticated); + } +diff -up openssh-7.2p2/servconf.c.expose-pam openssh-7.2p2/servconf.c +--- openssh-7.2p2/servconf.c.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/servconf.c 2016-07-18 12:34:38.170574004 +0200 +@@ -176,6 +176,7 @@ initialize_server_options(ServerOptions + options->fingerprint_hash = -1; + options->use_kuserok = -1; + options->enable_k5users = -1; ++ options->expose_auth_methods = -1; + } + + /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +@@ -374,6 +375,8 @@ fill_default_server_options(ServerOption + options->enable_k5users = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; ++ if (options->expose_auth_methods == -1) ++ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; + + assemble_algorithms(options); + +@@ -451,6 +454,7 @@ typedef enum { + sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, + sStreamLocalBindMask, sStreamLocalBindUnlink, + sAllowStreamLocalForwarding, sFingerprintHash, ++ sExposeAuthenticationMethods, + sDeprecated, sUnsupported + } ServerOpCodes; + +@@ -606,6 +610,7 @@ static struct { + { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, + { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, + { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, ++ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, + { NULL, sBadOption, 0 } + }; + +@@ -994,6 +999,12 @@ static const struct multistate multistat + { "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, +@@ -1918,6 +1929,11 @@ process_server_config_line(ServerOptions + options->fingerprint_hash = value; + break; + ++ 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); +@@ -2076,6 +2092,7 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(enable_k5users); + 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 {\ +@@ -2181,6 +2198,8 @@ fmt_intarg(ServerOpCodes code, int val) + 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: +@@ -2374,6 +2393,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); ++ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff -up openssh-7.2p2/servconf.h.expose-pam openssh-7.2p2/servconf.h +--- openssh-7.2p2/servconf.h.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/servconf.h 2016-07-18 12:30:12.125783254 +0200 +@@ -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 */ + +@@ -201,6 +206,8 @@ typedef struct { + char *auth_methods[MAX_AUTH_METHODS]; + + int fingerprint_hash; ++ ++ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ + } ServerOptions; + + /* Information about the incoming connection as used by Match */ +diff -up openssh-7.2p2/session.c.expose-pam openssh-7.2p2/session.c +--- openssh-7.2p2/session.c.expose-pam 2016-07-18 12:30:12.120783258 +0200 ++++ openssh-7.2p2/session.c 2016-07-18 12:30:12.125783254 +0200 +@@ -1180,6 +1180,12 @@ copy_environment(char **source, char *** + } + *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); + +@@ -1359,6 +1365,11 @@ do_setup_env(Session *s, const char *she + } + #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); +@@ -2798,6 +2809,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 -up openssh-7.2p2/ssh.1.expose-pam openssh-7.2p2/ssh.1 +--- openssh-7.2p2/ssh.1.expose-pam 2016-07-18 12:30:12.112783264 +0200 ++++ openssh-7.2p2/ssh.1 2016-07-18 12:30:12.126783253 +0200 +@@ -1396,6 +1396,10 @@ server IP address, and server port numbe + 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 -up openssh-7.2p2/sshd_config.5.expose-pam openssh-7.2p2/sshd_config.5 +--- openssh-7.2p2/sshd_config.5.expose-pam 2016-07-18 12:30:12.113783263 +0200 ++++ openssh-7.2p2/sshd_config.5 2016-07-18 12:30:12.126783253 +0200 +@@ -570,6 +570,21 @@ and finally + See PATTERNS in + .Xr ssh_config 5 + for more information on patterns. ++.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 FingerprintHash + Specifies the hash algorithm used when logging key fingerprints. + Valid options are: +diff -up openssh-7.2p2/ssh-gss.h.expose-pam openssh-7.2p2/ssh-gss.h +--- openssh-7.2p2/ssh-gss.h.expose-pam 2016-07-18 12:30:12.125783254 +0200 ++++ openssh-7.2p2/ssh-gss.h 2016-07-18 12:35:01.906555328 +0200 +@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt + 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 -up openssh-7.2p2/sshkey.c.expose-pam openssh-7.2p2/sshkey.c +--- openssh-7.2p2/sshkey.c.expose-pam 2016-07-18 12:30:12.071783296 +0200 ++++ openssh-7.2p2/sshkey.c 2016-07-18 12:30:12.126783253 +0200 +@@ -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" +@@ -1190,6 +1191,30 @@ sshkey_fingerprint(const struct sshkey * + 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 -up openssh-7.2p2/sshkey.h.expose-pam openssh-7.2p2/sshkey.h +--- openssh-7.2p2/sshkey.h.expose-pam 2016-07-18 12:30:12.071783296 +0200 ++++ openssh-7.2p2/sshkey.h 2016-07-18 12:30:12.127783252 +0200 +@@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s + 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 *); diff --git a/openssh.spec b/openssh.spec index 3e6ed54..ac8fe34 100644 --- a/openssh.spec +++ b/openssh.spec @@ -238,6 +238,9 @@ Patch937: openssh-7.2p2-CVE-2015-8325.patch Patch938: openssh-7.2p2-certificats-regress.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch +# expose more information to PAM +# https://github.com/openssh/openssh-portable/pull/47 +Patch940: openssh-7.2p2-expose-pam.patch License: BSD @@ -476,6 +479,7 @@ popd %patch937 -p1 -b .pam_uselogin_cve %patch938 -p1 -b .certificates %patch939 -p1 -b .s390-dev +%patch940 -p1 -b .expose-pam %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race