summaryrefslogtreecommitdiffstats
path: root/auth-pam.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2019-01-20 10:22:18 +1100
committerDamien Miller <djm@mindrot.org>2019-01-20 10:22:18 +1100
commit3f0786bbe73609ac96e5a0d91425ee21129f8e04 (patch)
treebe9ab562ad56a3948fee1f27fc9a13e4700b3661 /auth-pam.c
parent08f66d9f17e12c1140d1f1cf5c4dce67e915d3cc (diff)
remove PAM dependencies on old packet API
Requires some caching of values, because the PAM code isn't always called with packet context.
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/auth-pam.c b/auth-pam.c
index d67324e1..bde0a8f5 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -248,6 +248,9 @@ static int sshpam_maxtries_reached = 0;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
+static char *sshpam_rhost = NULL;
+static char *sshpam_laddr = NULL;
+static char *sshpam_conninfo = NULL;
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
@@ -669,14 +672,17 @@ sshpam_cleanup(void)
}
static int
-sshpam_init(Authctxt *authctxt)
+sshpam_init(struct ssh *ssh, Authctxt *authctxt)
{
- const char *pam_rhost, *pam_user, *user = authctxt->user;
+ const char *pam_user, *user = authctxt->user;
const char **ptr_pam_user = &pam_user;
- char *laddr, *conninfo;
- struct ssh *ssh = active_state; /* XXX */
- if (sshpam_handle != NULL) {
+ if (sshpam_handle == NULL) {
+ if (ssh == NULL) {
+ fatal("%s: called initially with no "
+ "packet context", __func__);
+ }
+ } if (sshpam_handle != NULL) {
/* We already have a PAM context; check if the user matches */
sshpam_err = pam_get_item(sshpam_handle,
PAM_USER, (sshpam_const void **)ptr_pam_user);
@@ -695,22 +701,32 @@ sshpam_init(Authctxt *authctxt)
sshpam_handle = NULL;
return (-1);
}
- pam_rhost = auth_get_canonical_hostname(ssh, options.use_dns);
- debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost);
- sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);
- if (sshpam_err != PAM_SUCCESS) {
- pam_end(sshpam_handle, sshpam_err);
- sshpam_handle = NULL;
- return (-1);
- }
- laddr = get_local_ipaddr(packet_get_connection_in());
- xasprintf(&conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
- laddr, ssh_local_port(ssh));
- pam_putenv(sshpam_handle, conninfo);
- free(laddr);
- free(conninfo);
+ if (ssh != NULL && sshpam_rhost == NULL) {
+ /*
+ * We need to cache these as we don't have packet context
+ * during the kbdint flow.
+ */
+ sshpam_rhost = xstrdup(auth_get_canonical_hostname(ssh,
+ options.use_dns));
+ sshpam_laddr = get_local_ipaddr(
+ ssh_packet_get_connection_in(ssh));
+ xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ sshpam_laddr, ssh_local_port(ssh));
+ }
+ if (sshpam_rhost != NULL) {
+ debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost);
+ sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST,
+ sshpam_rhost);
+ if (sshpam_err != PAM_SUCCESS) {
+ pam_end(sshpam_handle, sshpam_err);
+ sshpam_handle = NULL;
+ return (-1);
+ }
+ /* Put SSH_CONNECTION in the PAM environment too */
+ pam_putenv(sshpam_handle, sshpam_conninfo);
+ }
#ifdef PAM_TTY_KLUDGE
/*
@@ -765,7 +781,7 @@ sshpam_init_ctx(Authctxt *authctxt)
return NULL;
/* Initialize PAM */
- if (sshpam_init(authctxt) == -1) {
+ if (sshpam_init(NULL, authctxt) == -1) {
error("PAM: initialization failed");
return (NULL);
}
@@ -797,7 +813,6 @@ static int
sshpam_query(void *ctx, char **name, char **info,
u_int *num, char ***prompts, u_int **echo_on)
{
- struct ssh *ssh = active_state; /* XXX */
struct sshbuf *buffer;
struct pam_ctxt *ctxt = ctx;
size_t plen;
@@ -887,8 +902,7 @@ sshpam_query(void *ctx, char **name, char **info,
}
error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ",
- sshpam_authctxt->user,
- auth_get_canonical_hostname(ssh, options.use_dns));
+ sshpam_authctxt->user, sshpam_rhost);
/* FALLTHROUGH */
default:
*num = 0;
@@ -1005,12 +1019,14 @@ KbdintDevice mm_sshpam_device = {
* This replaces auth-pam.c
*/
void
-start_pam(Authctxt *authctxt)
+start_pam(struct ssh *ssh)
{
+ Authctxt *authctxt = (Authctxt *)ssh->authctxt;
+
if (!options.use_pam)
fatal("PAM: initialisation requested when UsePAM=no");
- if (sshpam_init(authctxt) == -1)
+ if (sshpam_init(ssh, authctxt) == -1)
fatal("PAM: initialisation failed");
}