From 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 28 Jul 2017 14:50:59 +1000 Subject: [PATCH] Expose list of completed auth methods to PAM bz#2408; ok dtucker@ --- auth-pam.c | 26 ++++++++++++++++++++++++++ session.c | 26 ++++++++++++++++++++------ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/auth-pam.c b/auth-pam.c index 9574d9ac7..de29c04c9 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -926,6 +926,27 @@ finish_pam(void) sshpam_cleanup(); } +static void +expose_authinfo(const char *caller) +{ + char *auth_info; + + /* + * Expose authentication information to PAM. + * The enviornment variable is versioned. Please increment the + * version suffix if the format of session_info changes. + */ + if (sshpam_authctxt->session_info == NULL) + auth_info = xstrdup(""); + else if ((auth_info = sshbuf_dup_string( + sshpam_authctxt->session_info)) == NULL) + fatal("%s: sshbuf_dup_string failed", __func__); + + debug2("%s: auth information in SSH_AUTH_INFO_0", caller); + do_pam_putenv("SSH_AUTH_INFO_0", auth_info); + free(auth_info); +} + u_int do_pam_account(void) { @@ -933,6 +954,8 @@ do_pam_account(void) if (sshpam_account_status != -1) return (sshpam_account_status); + expose_authinfo(__func__); + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); @@ -1057,6 +1080,9 @@ void do_pam_session(void) { debug3("PAM: opening session"); + + expose_authinfo(__func__); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&store_conv); if (sshpam_err != PAM_SUCCESS) diff --git a/session.c b/session.c index a2588e74b..698eaa879 100644 --- a/session.c +++ b/session.c @@ -984,8 +984,9 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid) } #endif /* HAVE_ETC_DEFAULT_LOGIN */ -void -copy_environment(char **source, char ***env, u_int *envsize) +static void +copy_environment_blacklist(char **source, char ***env, u_int *envsize, + const char *blacklist) { char *var_name, *var_val; int i; @@ -1001,13 +1002,22 @@ copy_environment(char **source, char ***env, u_int *envsize) } *var_val++ = '\0'; - debug3("Copy environment: %s=%s", var_name, var_val); - child_set_env(env, envsize, var_name, var_val); + if (blacklist == NULL || + match_pattern_list(var_name, blacklist, 0) != 1) { + debug3("Copy environment: %s=%s", var_name, var_val); + child_set_env(env, envsize, var_name, var_val); + } free(var_name); } } +void +copy_environment(char **source, char ***env, u_int *envsize) +{ + copy_environment_blacklist(source, env, envsize, NULL); +} + static char ** do_setup_env(Session *s, const char *shell) { @@ -1169,12 +1179,16 @@ do_setup_env(Session *s, const char *shell) if (options.use_pam) { char **p; + /* + * Don't allow SSH_AUTH_INFO variables posted to PAM to leak + * back into the environment. + */ p = fetch_pam_child_environment(); - copy_environment(p, &env, &envsize); + copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); free_pam_environment(p); p = fetch_pam_environment(); - copy_environment(p, &env, &envsize); + copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); free_pam_environment(p); } #endif /* USE_PAM */