vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth2.c.expose-pam	2016-12-23 15:40:26.768447868 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth2.c	2016-12-23 15:40:26.818447876 +0100
Jakub Jelen 209c7a
@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int
Jakub Jelen 209c7a
 {
Jakub Jelen 17b491
 	struct ssh *ssh = active_state;	/* XXX */
Jakub Jelen 209c7a
 	char *methods;
Jakub Jelen 209c7a
+	char *prev_auth_details;
Jakub Jelen 209c7a
 	int partial = 0;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	if (!authctxt->valid && authenticated)
Jakub Jelen 209c7a
@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int
Jakub Jelen 209c7a
 	if (authctxt->postponed)
Jakub Jelen 209c7a
 		return;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (authenticated || partial) {
Jakub Jelen 209c7a
+		prev_auth_details = authctxt->auth_details;
Jakub Jelen 209c7a
+		xasprintf(&authctxt->auth_details, "%s%s%s%s%s",
Jakub Jelen 209c7a
+		    prev_auth_details ? prev_auth_details : "",
Jakub Jelen 209c7a
+		    prev_auth_details ? ", " : "", method,
Jakub Jelen 209c7a
+		    authctxt->last_details ? ": " : "",
Jakub Jelen 209c7a
+		    authctxt->last_details ? authctxt->last_details : "");
Jakub Jelen 209c7a
+		free(prev_auth_details);
Jakub Jelen 209c7a
+	}
Jakub Jelen 209c7a
+	free(authctxt->last_details);
Jakub Jelen 209c7a
+	authctxt->last_details = NULL;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 #ifdef USE_PAM
Jakub Jelen 209c7a
 	if (options.use_pam && authenticated) {
Jakub Jelen 209c7a
 		if (!PRIVSEP(do_pam_account())) {
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth2-gss.c.expose-pam openssh-7.4p1/auth2-gss.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth2-gss.c.expose-pam	2016-12-23 15:40:26.769447868 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth2-gss.c	2016-12-23 15:40:26.818447876 +0100
Jakub Jelen 209c7a
@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type,
Jakub Jelen 209c7a
 	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
Jakub Jelen 209c7a
 	    authctxt->pw));
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (authenticated)
Jakub Jelen 209c7a
+		authctxt->last_details = ssh_gssapi_get_displayname();
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	authctxt->postponed = 0;
Jakub Jelen 209c7a
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
Jakub Jelen 209c7a
 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
Jakub Jelen 209c7a
@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple
Jakub Jelen 209c7a
 	else
Jakub Jelen 209c7a
 		logit("GSSAPI MIC check failed");
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (authenticated)
Jakub Jelen 209c7a
+		authctxt->last_details = ssh_gssapi_get_displayname();
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	buffer_free(&b);
Jakub Jelen 209c7a
 	if (micuser != authctxt->user)
Jakub Jelen 209c7a
 		free(micuser);
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth2-hostbased.c.expose-pam openssh-7.4p1/auth2-hostbased.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth2-hostbased.c.expose-pam	2016-12-23 15:40:26.731447862 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth2-hostbased.c	2016-12-23 15:40:26.818447876 +0100
Jakub Jelen 209c7a
@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt)
Jakub Jelen 209c7a
 {
Jakub Jelen 209c7a
 	Buffer b;
Jakub Jelen 209c7a
 	Key *key = NULL;
Jakub Jelen 209c7a
-	char *pkalg, *cuser, *chost, *service;
Jakub Jelen 209c7a
+	char *pkalg, *cuser, *chost, *service, *pubkey;
Jakub Jelen 209c7a
 	u_char *pkblob, *sig;
Jakub Jelen 209c7a
 	u_int alen, blen, slen;
Jakub Jelen 209c7a
 	int pktype;
Jakub Jelen 209c7a
@@ -140,15 +140,21 @@ userauth_hostbased(Authctxt *authctxt)
Jakub Jelen 209c7a
 	buffer_dump(&b);
Jakub Jelen 209c7a
 #endif
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
-	pubkey_auth_info(authctxt, key,
Jakub Jelen 209c7a
-	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);
Jakub Jelen 209c7a
+	pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
Jakub Jelen 209c7a
+	auth_info(authctxt,
Jakub Jelen 209c7a
+	    "%s, client user \"%.100s\", client host \"%.100s\"",
Jakub Jelen 209c7a
+	    pubkey, cuser, chost);
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	/* test for allowed key and correct signature */
Jakub Jelen 209c7a
 	authenticated = 0;
Jakub Jelen 209c7a
 	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
Jakub Jelen 209c7a
 	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
Jakub Jelen 209c7a
-			buffer_len(&b))) == 1)
Jakub Jelen 209c7a
+			buffer_len(&b))) == 1) {
Jakub Jelen 209c7a
 		authenticated = 1;
Jakub Jelen 209c7a
+		authctxt->last_details = pubkey;
Jakub Jelen 209c7a
+	} else {
Jakub Jelen 209c7a
+		free(pubkey);
Jakub Jelen 209c7a
+	}
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	buffer_free(&b);
Jakub Jelen 209c7a
 done:
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth2-pubkey.c.expose-pam openssh-7.4p1/auth2-pubkey.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth2-pubkey.c.expose-pam	2016-12-23 15:40:26.746447864 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth2-pubkey.c	2016-12-23 15:40:26.819447876 +0100
Jakub Jelen 209c7a
@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt)
Jakub Jelen 209c7a
 {
Jakub Jelen 209c7a
 	Buffer b;
Jakub Jelen 209c7a
 	Key *key = NULL;
Jakub Jelen 209c7a
-	char *pkalg, *userstyle, *fp = NULL;
Jakub Jelen 209c7a
+	char *pkalg, *userstyle, *pubkey, *fp = NULL;
Jakub Jelen 209c7a
 	u_char *pkblob, *sig;
Jakub Jelen 209c7a
 	u_int alen, blen, slen;
Jakub Jelen 209c7a
 	int have_sig, pktype;
Jakub Jelen 6cf9b8
@@ -177,7 +177,8 @@ userauth_pubkey(Authctxt *authctxt)
Jakub Jelen 209c7a
 #ifdef DEBUG_PK
Jakub Jelen 209c7a
 		buffer_dump(&b);
Jakub Jelen 209c7a
 #endif
Jakub Jelen 209c7a
-		pubkey_auth_info(authctxt, key, NULL);
Jakub Jelen 209c7a
+		pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
Jakub Jelen 209c7a
+		auth_info(authctxt, "%s", pubkey);
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 		/* test for correct signature */
Jakub Jelen 209c7a
 		authenticated = 0;
Jakub Jelen 6cf9b8
@@ -185,9 +186,12 @@ userauth_pubkey(Authctxt *authctxt)
Jakub Jelen 209c7a
 		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
Jakub Jelen 209c7a
 		    buffer_len(&b))) == 1) {
Jakub Jelen 209c7a
 			authenticated = 1;
Jakub Jelen 209c7a
+			authctxt->last_details = pubkey;
Jakub Jelen 209c7a
 			/* Record the successful key to prevent reuse */
Jakub Jelen 209c7a
 			auth2_record_userkey(authctxt, key);
Jakub Jelen 209c7a
 			key = NULL; /* Don't free below */
Jakub Jelen 209c7a
+		} else {
Jakub Jelen 209c7a
+			free(pubkey);
Jakub Jelen 209c7a
 		}
Jakub Jelen 209c7a
 		buffer_free(&b);
Jakub Jelen 209c7a
 		free(sig);
Jakub Jelen 6cf9b8
@@ -228,7 +232,7 @@ done:
Jakub Jelen 209c7a
 void
Jakub Jelen 209c7a
 pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
Jakub Jelen 209c7a
 {
Jakub Jelen 209c7a
-	char *fp, *extra;
Jakub Jelen 209c7a
+	char *extra, *pubkey;
Jakub Jelen 209c7a
 	va_list ap;
Jakub Jelen 209c7a
 	int i;
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -238,27 +242,13 @@ pubkey_auth_info(Authctxt *authctxt, con
Jakub Jelen 209c7a
 		i = vasprintf(&extra, fmt, ap);
Jakub Jelen 209c7a
 		va_end(ap);
Jakub Jelen 209c7a
 		if (i < 0 || extra == NULL)
Jakub Jelen 209c7a
-			fatal("%s: vasprintf failed", __func__);	
Jakub Jelen 209c7a
+			fatal("%s: vasprintf failed", __func__);
Jakub Jelen 209c7a
 	}
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
-	if (key_is_cert(key)) {
Jakub Jelen 209c7a
-		fp = sshkey_fingerprint(key->cert->signature_key,
Jakub Jelen 209c7a
-		    options.fingerprint_hash, SSH_FP_DEFAULT);
Jakub Jelen 209c7a
-		auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", 
Jakub Jelen 209c7a
-		    key_type(key), key->cert->key_id,
Jakub Jelen 209c7a
-		    (unsigned long long)key->cert->serial,
Jakub Jelen 209c7a
-		    key_type(key->cert->signature_key),
Jakub Jelen 209c7a
-		    fp == NULL ? "(null)" : fp,
Jakub Jelen 209c7a
-		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
Jakub Jelen 209c7a
-		free(fp);
Jakub Jelen 209c7a
-	} else {
Jakub Jelen 209c7a
-		fp = sshkey_fingerprint(key, options.fingerprint_hash,
Jakub Jelen 209c7a
-		    SSH_FP_DEFAULT);
Jakub Jelen 209c7a
-		auth_info(authctxt, "%s %s%s%s", key_type(key),
Jakub Jelen 209c7a
-		    fp == NULL ? "(null)" : fp,
Jakub Jelen 209c7a
-		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
Jakub Jelen 209c7a
-		free(fp);
Jakub Jelen 209c7a
-	}
Jakub Jelen 209c7a
+	pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
Jakub Jelen 209c7a
+	auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ",
Jakub Jelen 209c7a
+	    extra == NULL ? "" : extra);
Jakub Jelen 209c7a
+	free(pubkey);
Jakub Jelen 209c7a
 	free(extra);
Jakub Jelen 209c7a
 }
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth.h.expose-pam openssh-7.4p1/auth.h
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth.h.expose-pam	2016-12-23 15:40:26.782447870 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth.h	2016-12-23 15:40:26.819447876 +0100
Jakub Jelen 209c7a
@@ -84,6 +84,9 @@ struct Authctxt {
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	struct sshkey	**prev_userkeys;
Jakub Jelen 209c7a
 	u_int		 nprev_userkeys;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
+	char		*last_details;
Jakub Jelen 209c7a
+	char		*auth_details;
Jakub Jelen 209c7a
 };
Jakub Jelen 209c7a
 /*
Jakub Jelen 209c7a
  * Every authentication method has to handle authentication requests for
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/auth-pam.c.expose-pam openssh-7.4p1/auth-pam.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/auth-pam.c.expose-pam	2016-12-23 15:40:26.731447862 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/auth-pam.c	2016-12-23 15:40:26.819447876 +0100
Jakub Jelen 6cf9b8
@@ -688,6 +688,11 @@ sshpam_init_ctx(Authctxt *authctxt)
Jakub Jelen 209c7a
 		return (NULL);
Jakub Jelen 209c7a
 	}
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	/* Notify PAM about any already successful auth methods */
Jakub Jelen 209c7a
+	if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY &&
Jakub Jelen 209c7a
+			authctxt->auth_details)
Jakub Jelen 209c7a
+		do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details);
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	ctxt = xcalloc(1, sizeof *ctxt);
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	/* Start the authentication thread */
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/gss-serv.c.expose-pam openssh-7.4p1/gss-serv.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/gss-serv.c.expose-pam	2016-12-23 15:40:26.808447874 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/gss-serv.c	2016-12-23 15:40:26.819447876 +0100
Jakub Jelen 209c7a
@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int
Jakub Jelen 209c7a
 }
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 /* Privileged */
Jakub Jelen 209c7a
+char*
Jakub Jelen 209c7a
+ssh_gssapi_get_displayname(void)
Jakub Jelen 209c7a
+{
Jakub Jelen 209c7a
+	if (gssapi_client.displayname.length != 0 &&
Jakub Jelen 209c7a
+	    gssapi_client.displayname.value != NULL)
Jakub Jelen 209c7a
+		return strdup((char *)gssapi_client.displayname.value);
Jakub Jelen 209c7a
+	return NULL;
Jakub Jelen 209c7a
+}
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
+/* Privileged */
Jakub Jelen 209c7a
 int
Jakub Jelen 209c7a
 ssh_gssapi_userok(char *user, struct passwd *pw)
Jakub Jelen 209c7a
 {
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/monitor.c.expose-pam	2016-12-23 15:40:26.794447872 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/monitor.c	2016-12-23 15:41:16.473455863 +0100
Jakub Jelen 6cf9b8
@@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx
Jakub Jelen 17b491
 	struct ssh *ssh = active_state;	/* XXX */
Jakub Jelen 209c7a
 	struct mon_table *ent;
Jakub Jelen 209c7a
 	int authenticated = 0, partial = 0;
Jakub Jelen 209c7a
+	char *prev_auth_details;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	debug3("preauth child monitor started");
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -330,6 +331,18 @@ monitor_child_preauth(Authctxt *_authctx
Jakub Jelen 209c7a
 		auth_submethod = NULL;
Jakub Jelen 209c7a
 		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+		if (authenticated) {
Jakub Jelen 209c7a
+			prev_auth_details = authctxt->auth_details;
Jakub Jelen 209c7a
+			xasprintf(&authctxt->auth_details, "%s%s%s%s%s",
Jakub Jelen 209c7a
+			    prev_auth_details ? prev_auth_details : "",
Jakub Jelen 209c7a
+			    prev_auth_details ? ", " : "", auth_method,
Jakub Jelen 209c7a
+			    authctxt->last_details ? ": " : "",
Jakub Jelen 209c7a
+			    authctxt->last_details ? authctxt->last_details : "");
Jakub Jelen 209c7a
+			free(prev_auth_details);
Jakub Jelen 209c7a
+		}
Jakub Jelen 209c7a
+		free(authctxt->last_details);
Jakub Jelen 209c7a
+		authctxt->last_details = NULL;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 		/* Special handling for multiple required authentications */
Jakub Jelen 209c7a
 		if (options.num_auth_methods != 0) {
Jakub Jelen 6cf9b8
 			if (authenticated &&
Jakub Jelen 6cf9b8
@@ -1417,6 +1430,10 @@ mm_answer_keyverify(int sock, Buffer *m)
Jakub Jelen 209c7a
 	debug3("%s: key %p signature %s",
Jakub Jelen 209c7a
 	    __func__, key, (verified == 1) ? "verified" : "unverified");
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (verified == 1)
Jakub Jelen 209c7a
+		authctxt->last_details = sshkey_format_oneline(key,
Jakub Jelen 209c7a
+		    options.fingerprint_hash);
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	/* If auth was successful then record key to ensure it isn't reused */
Jakub Jelen 209c7a
 	if (verified == 1 && key_blobtype == MM_USERKEY)
Jakub Jelen 209c7a
 		auth2_record_userkey(authctxt, key);
Jakub Jelen 6cf9b8
@@ -1860,6 +1877,9 @@ mm_answer_gss_userok(int sock, Buffer *m
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	auth_method = "gssapi-with-mic";
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (authenticated)
Jakub Jelen 209c7a
+		authctxt->last_details = ssh_gssapi_get_displayname();
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	/* Monitor loop will terminate if authenticated */
Jakub Jelen 209c7a
 	return (authenticated);
Jakub Jelen 209c7a
 }
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/servconf.c.expose-pam openssh-7.4p1/servconf.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/servconf.c.expose-pam	2016-12-23 15:40:26.810447875 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/servconf.c	2016-12-23 15:44:04.691482920 +0100
Jakub Jelen 6cf9b8
@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions
Jakub Jelen 6cf9b8
 	options->disable_forwarding = -1;
Jakub Jelen 209c7a
 	options->use_kuserok = -1;
Jakub Jelen 209c7a
 	options->enable_k5users = -1;
Jakub Jelen 209c7a
+	options->expose_auth_methods = -1;
Jakub Jelen 209c7a
 }
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
Jakub Jelen 6cf9b8
@@ -354,6 +355,8 @@ fill_default_server_options(ServerOption
Jakub Jelen 209c7a
 		options->use_kuserok = 1;
Jakub Jelen 6cf9b8
 	if (options->enable_k5users == -1)
Jakub Jelen 6cf9b8
 		options->enable_k5users = 0;
Jakub Jelen 209c7a
+	if (options->expose_auth_methods == -1)
Jakub Jelen 209c7a
+		options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	assemble_algorithms(options);
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -439,6 +442,7 @@ typedef enum {
Jakub Jelen 209c7a
 	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
Jakub Jelen 209c7a
 	sStreamLocalBindMask, sStreamLocalBindUnlink,
Jakub Jelen 6cf9b8
 	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
Jakub Jelen 209c7a
+	sExposeAuthenticationMethods,
Jakub Jelen 6cf9b8
 	sDeprecated, sIgnore, sUnsupported
Jakub Jelen 209c7a
 } ServerOpCodes;
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -595,6 +599,7 @@ static struct {
Jakub Jelen 209c7a
 	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
Jakub Jelen 209c7a
 	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
Jakub Jelen 6cf9b8
 	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
Jakub Jelen 209c7a
+	{ "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL },
Jakub Jelen 209c7a
 	{ NULL, sBadOption, 0 }
Jakub Jelen 209c7a
 };
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -984,6 +989,12 @@ static const struct multistate multistat
Jakub Jelen 209c7a
 	{ "local",			FORWARD_LOCAL },
Jakub Jelen 209c7a
 	{ NULL, -1 }
Jakub Jelen 209c7a
 };
Jakub Jelen 209c7a
+static const struct multistate multistate_exposeauthmeth[] = {
Jakub Jelen 209c7a
+	{ "never",			EXPOSE_AUTHMETH_NEVER },
Jakub Jelen 209c7a
+	{ "pam-only",			EXPOSE_AUTHMETH_PAMONLY },
Jakub Jelen 209c7a
+	{ "pam-and-env",		EXPOSE_AUTHMETH_PAMENV },
Jakub Jelen 209c7a
+	{ NULL, -1}
Jakub Jelen 209c7a
+};
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 int
Jakub Jelen 209c7a
 process_server_config_line(ServerOptions *options, char *line,
Jakub Jelen 6cf9b8
@@ -1902,6 +1913,11 @@ process_server_config_line(ServerOptions
Jakub Jelen 209c7a
 			options->fingerprint_hash = value;
Jakub Jelen 209c7a
 		break;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	case sExposeAuthenticationMethods:
Jakub Jelen 209c7a
+		intptr = &options->expose_auth_methods;
Jakub Jelen 209c7a
+		multistate_ptr = multistate_exposeauthmeth;
Jakub Jelen 209c7a
+		goto parse_multistate;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	case sDeprecated:
Jakub Jelen 6cf9b8
 	case sIgnore:
Jakub Jelen 6cf9b8
 	case sUnsupported:
Jakub Jelen 6cf9b8
@@ -2060,6 +2076,7 @@ copy_set_server_options(ServerOptions *d
Jakub Jelen 209c7a
 	M_CP_INTOPT(enable_k5users);
Jakub Jelen 209c7a
 	M_CP_INTOPT(rekey_limit);
Jakub Jelen 209c7a
 	M_CP_INTOPT(rekey_interval);
Jakub Jelen 209c7a
+	M_CP_INTOPT(expose_auth_methods);
Jakub Jelen 209c7a
 
Jakub Jelen 5878eb
 	/*
Jakub Jelen 5878eb
 	 * The bind_mask is a mode_t that may be unsigned, so we can't use
Jakub Jelen 6cf9b8
@@ -2176,6 +2193,8 @@ fmt_intarg(ServerOpCodes code, int val)
Jakub Jelen 209c7a
 		return fmt_multistate_int(val, multistate_tcpfwd);
Jakub Jelen 209c7a
 	case sFingerprintHash:
Jakub Jelen 209c7a
 		return ssh_digest_alg_name(val);
Jakub Jelen 209c7a
+	case sExposeAuthenticationMethods:
Jakub Jelen 209c7a
+		return fmt_multistate_int(val, multistate_exposeauthmeth);
Jakub Jelen 6cf9b8
 	default:
Jakub Jelen 209c7a
 		switch (val) {
Jakub Jelen 6cf9b8
 		case 0:
Jakub Jelen 6cf9b8
@@ -2356,6 +2375,7 @@ dump_config(ServerOptions *o)
Jakub Jelen 209c7a
 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
Jakub Jelen 209c7a
 	dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
Jakub Jelen 209c7a
 	dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users);
Jakub Jelen 209c7a
+	dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods);
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	/* string arguments */
Jakub Jelen 209c7a
 	dump_cfg_string(sPidFile, o->pid_file);
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/servconf.h.expose-pam openssh-7.4p1/servconf.h
Jakub Jelen 6cf9b8
--- openssh-7.4p1/servconf.h.expose-pam	2016-12-23 15:40:26.810447875 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/servconf.h	2016-12-23 15:40:26.821447876 +0100
Jakub Jelen 209c7a
@@ -48,6 +48,11 @@
Jakub Jelen 209c7a
 #define FORWARD_LOCAL		(1<<1)
Jakub Jelen 209c7a
 #define FORWARD_ALLOW		(FORWARD_REMOTE|FORWARD_LOCAL)
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+/* Expose AuthenticationMethods */
Jakub Jelen 209c7a
+#define EXPOSE_AUTHMETH_NEVER   0
Jakub Jelen 209c7a
+#define EXPOSE_AUTHMETH_PAMONLY 1
Jakub Jelen 209c7a
+#define EXPOSE_AUTHMETH_PAMENV  2
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 #define DEFAULT_AUTH_FAIL_MAX	6	/* Default for MaxAuthTries */
Jakub Jelen 209c7a
 #define DEFAULT_SESSIONS_MAX	10	/* Default for MaxSessions */
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -195,6 +200,8 @@ typedef struct {
Jakub Jelen 209c7a
 	char   *auth_methods[MAX_AUTH_METHODS];
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 	int	fingerprint_hash;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
+	int	expose_auth_methods; /* EXPOSE_AUTHMETH_* above */
Jakub Jelen 209c7a
 }       ServerOptions;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 /* Information about the incoming connection as used by Match */
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/session.c.expose-pam openssh-7.4p1/session.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/session.c.expose-pam	2016-12-23 15:40:26.794447872 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/session.c	2016-12-23 15:40:26.821447876 +0100
Jakub Jelen 6cf9b8
@@ -997,6 +997,12 @@ copy_environment(char **source, char ***
Jakub Jelen 209c7a
 		}
Jakub Jelen 209c7a
 		*var_val++ = '\0';
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+		if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV &&
Jakub Jelen 209c7a
+				strcmp(var_name, "SSH_USER_AUTH") == 0) {
Jakub Jelen 209c7a
+			free(var_name);
Jakub Jelen 209c7a
+			continue;
Jakub Jelen 209c7a
+		}
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 		debug3("Copy environment: %s=%s", var_name, var_val);
Jakub Jelen 209c7a
 		child_set_env(env, envsize, var_name, var_val);
Jakub Jelen 209c7a
 
Jakub Jelen 6cf9b8
@@ -1173,6 +1179,11 @@ do_setup_env(Session *s, const char *she
Jakub Jelen 209c7a
 	}
Jakub Jelen 209c7a
 #endif /* USE_PAM */
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV &&
Jakub Jelen 209c7a
+			s->authctxt->auth_details)
Jakub Jelen 209c7a
+		child_set_env(&env, &envsize, "SSH_USER_AUTH",
Jakub Jelen 209c7a
+		     s->authctxt->auth_details);
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 	if (auth_sock_name != NULL)
Jakub Jelen 209c7a
 		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
Jakub Jelen 209c7a
 		    auth_sock_name);
Jakub Jelen 6cf9b8
@@ -2561,6 +2572,9 @@ do_cleanup(Authctxt *authctxt)
Jakub Jelen 209c7a
 	if (authctxt == NULL)
Jakub Jelen 209c7a
 		return;
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+	free(authctxt->auth_details);
Jakub Jelen 209c7a
+	authctxt->auth_details = NULL;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 #ifdef USE_PAM
Jakub Jelen 209c7a
 	if (options.use_pam) {
Jakub Jelen 209c7a
 		sshpam_cleanup();
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/ssh.1.expose-pam openssh-7.4p1/ssh.1
Jakub Jelen 6cf9b8
--- openssh-7.4p1/ssh.1.expose-pam	2016-12-23 15:40:26.810447875 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/ssh.1	2016-12-23 15:40:26.822447877 +0100
Jakub Jelen 6cf9b8
@@ -1421,6 +1421,10 @@ server IP address, and server port numbe
Jakub Jelen 209c7a
 This variable contains the original command line if a forced command
Jakub Jelen 209c7a
 is executed.
Jakub Jelen 209c7a
 It can be used to extract the original arguments.
Jakub Jelen 209c7a
+.It Ev SSH_USER_AUTH
Jakub Jelen 209c7a
+This variable contains, for SSH2 only, a comma-separated list of authentication
Jakub Jelen 209c7a
+methods that were successfuly used to authenticate. When possible, these
Jakub Jelen 209c7a
+methods are extended with detailed information on the credential used.
Jakub Jelen 209c7a
 .It Ev SSH_TTY
Jakub Jelen 209c7a
 This is set to the name of the tty (path to the device) associated
Jakub Jelen 209c7a
 with the current shell or command.
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/sshd_config.5.expose-pam openssh-7.4p1/sshd_config.5
Jakub Jelen 6cf9b8
--- openssh-7.4p1/sshd_config.5.expose-pam	2016-12-23 15:40:26.822447877 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/sshd_config.5	2016-12-23 15:45:22.411495421 +0100
Jakub Jelen 6cf9b8
@@ -570,6 +570,21 @@ Disables all forwarding features, includ
Jakub Jelen 6cf9b8
 TCP and StreamLocal.
Jakub Jelen 6cf9b8
 This option overrides all other forwarding-related options and may
Jakub Jelen 6cf9b8
 simplify restricted configurations.
Jakub Jelen 209c7a
+.It Cm ExposeAuthenticationMethods
Jakub Jelen 209c7a
+When using SSH2, this option controls the exposure of the list of
Jakub Jelen 209c7a
+successful authentication methods to PAM during the authentication
Jakub Jelen 209c7a
+and to the shell environment via the
Jakub Jelen 209c7a
+.Cm SSH_USER_AUTH
Jakub Jelen 209c7a
+variable. See the description of this variable for more details.
Jakub Jelen 209c7a
+Valid options are:
Jakub Jelen 6cf9b8
+.Cm never
Jakub Jelen 209c7a
+(Do not expose successful authentication methods),
Jakub Jelen 6cf9b8
+.Cm pam-only
Jakub Jelen 209c7a
+(Only expose them to PAM during authentication, not afterwards),
Jakub Jelen 6cf9b8
+.Cm pam-and-env
Jakub Jelen 209c7a
+(Expose them to PAM and keep them in the shell environment).
Jakub Jelen 209c7a
+The default is
Jakub Jelen 6cf9b8
+.Cm never .
Jakub Jelen 209c7a
 .It Cm FingerprintHash
Jakub Jelen 209c7a
 Specifies the hash algorithm used when logging key fingerprints.
Jakub Jelen 209c7a
 Valid options are:
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/ssh-gss.h.expose-pam openssh-7.4p1/ssh-gss.h
Jakub Jelen 6cf9b8
--- openssh-7.4p1/ssh-gss.h.expose-pam	2016-12-23 15:40:26.811447875 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/ssh-gss.h	2016-12-23 15:40:26.823447877 +0100
Jakub Jelen 209c7a
@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt
Jakub Jelen 209c7a
     const char *);
Jakub Jelen 209c7a
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
Jakub Jelen 209c7a
 int ssh_gssapi_userok(char *name, struct passwd *);
Jakub Jelen 209c7a
+char* ssh_gssapi_get_displayname(void);
Jakub Jelen 209c7a
 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
Jakub Jelen 209c7a
 void ssh_gssapi_do_child(char ***, u_int *);
Jakub Jelen 209c7a
 void ssh_gssapi_cleanup_creds(void);
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/sshkey.c.expose-pam openssh-7.4p1/sshkey.c
Jakub Jelen 6cf9b8
--- openssh-7.4p1/sshkey.c.expose-pam	2016-12-23 15:40:26.777447869 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/sshkey.c	2016-12-23 15:40:26.823447877 +0100
Jakub Jelen 6cf9b8
@@ -57,6 +57,7 @@
Jakub Jelen 209c7a
 #define SSHKEY_INTERNAL
Jakub Jelen 209c7a
 #include "sshkey.h"
Jakub Jelen 209c7a
 #include "match.h"
Jakub Jelen 209c7a
+#include "xmalloc.h"
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
 /* openssh private key file format */
Jakub Jelen 209c7a
 #define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
Jakub Jelen 6cf9b8
@@ -1191,6 +1192,30 @@ sshkey_fingerprint(const struct sshkey *
Jakub Jelen 209c7a
 	return retval;
Jakub Jelen 209c7a
 }
Jakub Jelen 209c7a
 
Jakub Jelen 209c7a
+char *
Jakub Jelen 209c7a
+sshkey_format_oneline(const struct sshkey *key, int dgst_alg)
Jakub Jelen 209c7a
+{
Jakub Jelen 209c7a
+	char *fp, *result;
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
+	if (sshkey_is_cert(key)) {
Jakub Jelen 209c7a
+		fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg,
Jakub Jelen 209c7a
+		    SSH_FP_DEFAULT);
Jakub Jelen 209c7a
+		xasprintf(&result, "%s ID %s (serial %llu) CA %s %s",
Jakub Jelen 209c7a
+		    sshkey_type(key), key->cert->key_id,
Jakub Jelen 209c7a
+		    (unsigned long long)key->cert->serial,
Jakub Jelen 209c7a
+		    sshkey_type(key->cert->signature_key),
Jakub Jelen 209c7a
+		    fp == NULL ? "(null)" : fp);
Jakub Jelen 209c7a
+		free(fp);
Jakub Jelen 209c7a
+	} else {
Jakub Jelen 209c7a
+		fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT);
Jakub Jelen 209c7a
+		xasprintf(&result, "%s %s", sshkey_type(key),
Jakub Jelen 209c7a
+		    fp == NULL ? "(null)" : fp);
Jakub Jelen 209c7a
+		free(fp);
Jakub Jelen 209c7a
+	}
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
+	return result;
Jakub Jelen 209c7a
+}
Jakub Jelen 209c7a
+
Jakub Jelen 209c7a
 #ifdef WITH_SSH1
Jakub Jelen 209c7a
 /*
Jakub Jelen 209c7a
  * Reads a multiple-precision integer in decimal from the buffer, and advances
Jakub Jelen 6cf9b8
diff -up openssh-7.4p1/sshkey.h.expose-pam openssh-7.4p1/sshkey.h
Jakub Jelen 6cf9b8
--- openssh-7.4p1/sshkey.h.expose-pam	2016-12-23 15:40:26.777447869 +0100
Jakub Jelen 6cf9b8
+++ openssh-7.4p1/sshkey.h	2016-12-23 15:40:26.823447877 +0100
Jakub Jelen 209c7a
@@ -124,6 +124,7 @@ char		*sshkey_fingerprint(const struct s
Jakub Jelen 209c7a
     int, enum sshkey_fp_rep);
Jakub Jelen 209c7a
 int		 sshkey_fingerprint_raw(const struct sshkey *k,
Jakub Jelen 209c7a
     int, u_char **retp, size_t *lenp);
Jakub Jelen 209c7a
+char		*sshkey_format_oneline(const struct sshkey *k, int dgst_alg);
Jakub Jelen 209c7a
 const char	*sshkey_type(const struct sshkey *);
Jakub Jelen 209c7a
 const char	*sshkey_cert_type(const struct sshkey *);
Jakub Jelen 209c7a
 int		 sshkey_write(const struct sshkey *, FILE *);