summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2004-05-30 20:43:59 +1000
committerDarren Tucker <dtucker@zip.com.au>2004-05-30 20:43:59 +1000
commit450a158d7ef01e44723802e28a65348375718a2c (patch)
treebff93c7aa376f8727e6453cee48bbbb265c1c251
parent0ffe638bbbea203848e141e624960f0c40c1d51b (diff)
- (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM
support for PasswordAuthentication=yes. ok djm@
-rw-r--r--ChangeLog6
-rw-r--r--auth-pam.c99
-rw-r--r--auth-pam.h3
-rw-r--r--auth-passwd.c4
4 files changed, 109 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 1fee7a30..f3f2fc35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20040530
+ - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM
+ support for PasswordAuthentication=yes. ok djm@
+
20040527
- (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec
contrib/README CREDITS INSTALL] Bug #873: Correct URLs for x11-ssh-askpass
@@ -1163,4 +1167,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
-$Id: ChangeLog,v 1.3368 2004/05/26 23:59:31 dtucker Exp $
+$Id: ChangeLog,v 1.3369 2004/05/30 10:43:59 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 833c850e..8de90a37 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.102 2004/05/24 01:55:36 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.103 2004/05/30 10:43:59 dtucker Exp $");
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -169,6 +169,7 @@ static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
+static const char *sshpam_password = NULL;
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
@@ -951,4 +952,100 @@ free_pam_environment(char **env)
xfree(env);
}
+/*
+ * "Blind" conversation function for password authentication. Assumes that
+ * echo-off prompts are for the password and stores messages for later
+ * display.
+ */
+static int
+sshpam_passwd_conv(int n, const struct pam_message **msg,
+ struct pam_response **resp, void *data)
+{
+ struct pam_response *reply;
+ int i;
+ size_t len;
+
+ debug3("PAM: %s called with %d messages", __func__, n);
+
+ *resp = NULL;
+
+ if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ return (PAM_CONV_ERR);
+
+ if ((reply = malloc(n * sizeof(*reply))) == NULL)
+ return (PAM_CONV_ERR);
+ memset(reply, 0, n * sizeof(*reply));
+
+ for (i = 0; i < n; ++i) {
+ switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+ case PAM_PROMPT_ECHO_OFF:
+ if (sshpam_password == NULL)
+ goto fail;
+ reply[i].resp = xstrdup(sshpam_password);
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ len = strlen(PAM_MSG_MEMBER(msg, i, msg));
+ if (len > 0) {
+ buffer_append(&loginmsg,
+ PAM_MSG_MEMBER(msg, i, msg), len);
+ buffer_append(&loginmsg, "\n", 1);
+ }
+ reply[i].resp = xstrdup("");
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ *resp = reply;
+ return (PAM_SUCCESS);
+
+ fail:
+ for(i = 0; i < n; i++) {
+ if (reply[i].resp != NULL)
+ xfree(reply[i].resp);
+ }
+ xfree(reply);
+ return (PAM_CONV_ERR);
+}
+
+static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
+
+/*
+ * Attempt password authentication via PAM
+ */
+int
+sshpam_auth_passwd(Authctxt *authctxt, const char *password)
+{
+ int flags = (options.permit_empty_passwd == 0 ?
+ PAM_DISALLOW_NULL_AUTHTOK : 0);
+
+ if (!options.use_pam || sshpam_handle == NULL)
+ fatal("PAM: %s called when PAM disabled or failed to "
+ "initialise.", __func__);
+
+ sshpam_password = password;
+ sshpam_authctxt = authctxt;
+
+ sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+ (const void *)&passwd_conv);
+ if (sshpam_err != PAM_SUCCESS)
+ fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
+ pam_strerror(sshpam_handle, sshpam_err));
+
+ sshpam_err = pam_authenticate(sshpam_handle, flags);
+ sshpam_password = NULL;
+ if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
+ debug("PAM: password authentication accepted for %.100s",
+ authctxt->user);
+ return 1;
+ } else {
+ debug("PAM: password authentication failed for %.100s: %s",
+ authctxt->valid ? authctxt->user : "an illegal user",
+ pam_strerror(sshpam_handle, sshpam_err));
+ return 0;
+ }
+}
#endif /* USE_PAM */
diff --git a/auth-pam.h b/auth-pam.h
index 1b3706e0..f479413d 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -1,4 +1,4 @@
-/* $Id: auth-pam.h,v 1.25 2004/03/08 12:04:07 dtucker Exp $ */
+/* $Id: auth-pam.h,v 1.26 2004/05/30 10:43:59 dtucker Exp $ */
/*
* Copyright (c) 2000 Damien Miller. All rights reserved.
@@ -44,5 +44,6 @@ char ** fetch_pam_child_environment(void);
void free_pam_environment(char **);
void sshpam_thread_cleanup(void);
void sshpam_cleanup(void);
+int sshpam_auth_passwd(Authctxt *, const char *);
#endif /* USE_PAM */
diff --git a/auth-passwd.c b/auth-passwd.c
index beaf0fa6..da247df7 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -91,6 +91,10 @@ auth_password(Authctxt *authctxt, const char *password)
return ok;
}
#endif
+#ifdef USE_PAM
+ if (options.use_pam)
+ return (sshpam_auth_passwd(authctxt, password) && ok);
+#endif
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
if (!expire_checked) {
expire_checked = 1;