Google

Index: auth-pam.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
retrieving revision 1.102
diff -u -p -r1.102 auth-pam.c
--- auth-pam.c	24 May 2004 01:55:36 -0000	1.102
+++ auth-pam.c	28 May 2004 12:57:43 -0000
@@ -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 */
Index: auth-pam.h
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.h,v
retrieving revision 1.25
diff -u -p -r1.25 auth-pam.h
--- auth-pam.h	8 Mar 2004 12:04:07 -0000	1.25
+++ auth-pam.h	28 May 2004 11:18:05 -0000
@@ -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 */
Index: auth-passwd.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-passwd.c,v
retrieving revision 1.73
diff -u -p -r1.73 auth-passwd.c
--- auth-passwd.c	4 Mar 2004 11:59:37 -0000	1.73
+++ auth-passwd.c	28 May 2004 11:18:30 -0000
@@ -91,6 +91,10 @@ auth_password(Authctxt *authctxt, const 
 		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;


syntax highlighted by Code2HTML, v. 0.9.1