openssh/openssh-7.3p1-expose-pam.patch
zombie (Zombie Ryushu) 2a7d26d2c3 Mageia Patches
2016-09-30 05:06:40 -04:00

513 lines
17 KiB
Diff

diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth2.c openssh-7.3p1-expose-pam/auth2.c
--- openssh-7.3p1/auth2.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth2.c 2016-08-07 19:29:05.288169736 +0200
@@ -293,6 +293,7 @@
const char *submethod)
{
char *methods;
+ char *prev_auth_details;
int partial = 0;
if (!authctxt->valid && authenticated)
@@ -323,6 +324,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 -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth2-gss.c openssh-7.3p1-expose-pam/auth2-gss.c
--- openssh-7.3p1/auth2-gss.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth2-gss.c 2016-08-07 19:33:42.819666662 +0200
@@ -278,9 +278,15 @@
else
logit("GSSAPI MIC check failed");
+ if (authenticated)
+ authctxt->last_details = ssh_gssapi_get_displayname();
+
buffer_free(&b);
free(mic.value);
+ 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);
diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth2-hostbased.c openssh-7.3p1-expose-pam/auth2-hostbased.c
--- openssh-7.3p1/auth2-hostbased.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth2-hostbased.c 2016-08-07 19:29:05.290169717 +0200
@@ -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 = 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 -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth2-pubkey.c openssh-7.3p1-expose-pam/auth2-pubkey.c
--- openssh-7.3p1/auth2-pubkey.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth2-pubkey.c 2016-08-07 19:29:05.290169717 +0200
@@ -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,8 @@
#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 @@
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 @@
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 @@
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 -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth.h openssh-7.3p1-expose-pam/auth.h
--- openssh-7.3p1/auth.h 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth.h 2016-08-07 19:29:05.291169708 +0200
@@ -81,6 +81,9 @@
struct sshkey **prev_userkeys;
u_int nprev_userkeys;
+
+ char *last_details;
+ char *auth_details;
};
/*
* Every authentication method has to handle authentication requests for
diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/auth-pam.c openssh-7.3p1-expose-pam/auth-pam.c
--- openssh-7.3p1/auth-pam.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/auth-pam.c 2016-08-07 19:29:05.291169708 +0200
@@ -684,6 +684,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 -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/gss-serv.c openssh-7.3p1-expose-pam/gss-serv.c
--- openssh-7.3p1/gss-serv.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/gss-serv.c 2016-08-07 19:29:05.292169699 +0200
@@ -356,6 +356,16 @@
}
/* 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)
{
diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/monitor.c openssh-7.3p1-expose-pam/monitor.c
--- openssh-7.3p1/monitor.c 2016-08-07 19:28:17.665620825 +0200
+++ openssh-7.3p1-expose-pam/monitor.c 2016-08-07 19:29:05.292169699 +0200
@@ -336,6 +336,7 @@
{
struct mon_table *ent;
int authenticated = 0, partial = 0;
+ char *prev_auth_details;
debug3("preauth child monitor started");
@@ -369,6 +370,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)
@@ -1460,6 +1473,10 @@
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);
@@ -2085,6 +2102,9 @@
auth_method = "gssapi-with-mic";
+ if (authenticated)
+ authctxt->last_details = ssh_gssapi_get_displayname();
+
/* Monitor loop will terminate if authenticated */
return (authenticated);
}
diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/servconf.c openssh-7.3p1-expose-pam/servconf.c
--- openssh-7.3p1/servconf.c 2016-08-07 19:28:17.677620710 +0200
+++ openssh-7.3p1-expose-pam/servconf.c 2016-08-07 19:32:19.025403136 +0200
@@ -170,6 +170,7 @@
options->ip_qos_bulk = -1;
options->version_addendum = NULL;
options->fingerprint_hash = -1;
+ options->expose_auth_methods = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -356,6 +357,8 @@
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
+ if (options->expose_auth_methods == -1)
+ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER;
assemble_algorithms(options);
@@ -441,6 +444,7 @@
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash,
+ sExposeAuthenticationMethods,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -584,6 +588,7 @@
{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
+ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -973,6 +978,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,
@@ -1887,6 +1898,11 @@
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);
@@ -2044,6 +2060,7 @@
M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
+ M_CP_INTOPT(expose_auth_methods);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2160,6 +2177,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:
@@ -2350,6 +2369,7 @@
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
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 -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/servconf.h openssh-7.3p1-expose-pam/servconf.h
--- openssh-7.3p1/servconf.h 2016-08-07 19:28:17.660620873 +0200
+++ openssh-7.3p1-expose-pam/servconf.h 2016-08-07 19:29:05.294169680 +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 */
@@ -196,6 +201,8 @@
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 -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/session.c openssh-7.3p1-expose-pam/session.c
--- openssh-7.3p1/session.c 2016-08-07 19:28:17.666620815 +0200
+++ openssh-7.3p1-expose-pam/session.c 2016-08-07 19:29:05.295169670 +0200
@@ -1160,6 +1160,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);
@@ -1342,6 +1348,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);
@@ -2773,6 +2784,9 @@
if (authctxt == NULL)
return;
+ free(authctxt->auth_details);
+ authctxt->auth_details = NULL;
+
#ifdef USE_PAM
if (options.use_pam) {
sshpam_cleanup();
diff -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/ssh.1 openssh-7.3p1-expose-pam/ssh.1
--- openssh-7.3p1/ssh.1 2016-08-07 19:28:17.674620739 +0200
+++ openssh-7.3p1-expose-pam/ssh.1 2016-08-07 19:29:05.295169670 +0200
@@ -1420,6 +1420,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 -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/sshd_config.5 openssh-7.3p1-expose-pam/sshd_config.5
--- openssh-7.3p1/sshd_config.5 2016-08-07 19:28:17.661620863 +0200
+++ openssh-7.3p1-expose-pam/sshd_config.5 2016-08-07 19:29:05.296169661 +0200
@@ -579,6 +579,21 @@
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 -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/ssh-gss.h openssh-7.3p1-expose-pam/ssh-gss.h
--- openssh-7.3p1/ssh-gss.h 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/ssh-gss.h 2016-08-07 19:30:15.338519247 +0200
@@ -124,6 +124,7 @@
/* In the server */
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
int ssh_gssapi_userok(char *name);
+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 -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/sshkey.c openssh-7.3p1-expose-pam/sshkey.c
--- openssh-7.3p1/sshkey.c 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/sshkey.c 2016-08-07 19:29:05.297169652 +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"
@@ -1189,6 +1190,30 @@
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 -Naur -x '*.rej' -x '*.orig' -x '*~' openssh-7.3p1/sshkey.h openssh-7.3p1-expose-pam/sshkey.h
--- openssh-7.3p1/sshkey.h 2016-07-28 00:54:27.000000000 +0200
+++ openssh-7.3p1-expose-pam/sshkey.h 2016-08-07 19:29:05.298169642 +0200
@@ -123,6 +123,7 @@
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 *);