summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 1fee7a302..f3f2fc350 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
120040530
2 - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM
3 support for PasswordAuthentication=yes. ok djm@
4
120040527 520040527
2 - (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec 6 - (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec
3 contrib/README CREDITS INSTALL] Bug #873: Correct URLs for x11-ssh-askpass 7 contrib/README CREDITS INSTALL] Bug #873: Correct URLs for x11-ssh-askpass
@@ -1163,4 +1167,4 @@
1163 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 1167 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
1164 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 1168 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
1165 1169
1166$Id: ChangeLog,v 1.3368 2004/05/26 23:59:31 dtucker Exp $ 1170$Id: ChangeLog,v 1.3369 2004/05/30 10:43:59 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 833c850e7..8de90a37a 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
31 31
32/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ 32/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
33#include "includes.h" 33#include "includes.h"
34RCSID("$Id: auth-pam.c,v 1.102 2004/05/24 01:55:36 dtucker Exp $"); 34RCSID("$Id: auth-pam.c,v 1.103 2004/05/30 10:43:59 dtucker Exp $");
35 35
36#ifdef USE_PAM 36#ifdef USE_PAM
37#if defined(HAVE_SECURITY_PAM_APPL_H) 37#if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -169,6 +169,7 @@ static int sshpam_cred_established = 0;
169static int sshpam_account_status = -1; 169static int sshpam_account_status = -1;
170static char **sshpam_env = NULL; 170static char **sshpam_env = NULL;
171static Authctxt *sshpam_authctxt = NULL; 171static Authctxt *sshpam_authctxt = NULL;
172static const char *sshpam_password = NULL;
172 173
173/* Some PAM implementations don't implement this */ 174/* Some PAM implementations don't implement this */
174#ifndef HAVE_PAM_GETENVLIST 175#ifndef HAVE_PAM_GETENVLIST
@@ -951,4 +952,100 @@ free_pam_environment(char **env)
951 xfree(env); 952 xfree(env);
952} 953}
953 954
955/*
956 * "Blind" conversation function for password authentication. Assumes that
957 * echo-off prompts are for the password and stores messages for later
958 * display.
959 */
960static int
961sshpam_passwd_conv(int n, const struct pam_message **msg,
962 struct pam_response **resp, void *data)
963{
964 struct pam_response *reply;
965 int i;
966 size_t len;
967
968 debug3("PAM: %s called with %d messages", __func__, n);
969
970 *resp = NULL;
971
972 if (n <= 0 || n > PAM_MAX_NUM_MSG)
973 return (PAM_CONV_ERR);
974
975 if ((reply = malloc(n * sizeof(*reply))) == NULL)
976 return (PAM_CONV_ERR);
977 memset(reply, 0, n * sizeof(*reply));
978
979 for (i = 0; i < n; ++i) {
980 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
981 case PAM_PROMPT_ECHO_OFF:
982 if (sshpam_password == NULL)
983 goto fail;
984 reply[i].resp = xstrdup(sshpam_password);
985 reply[i].resp_retcode = PAM_SUCCESS;
986 break;
987 case PAM_ERROR_MSG:
988 case PAM_TEXT_INFO:
989 len = strlen(PAM_MSG_MEMBER(msg, i, msg));
990 if (len > 0) {
991 buffer_append(&loginmsg,
992 PAM_MSG_MEMBER(msg, i, msg), len);
993 buffer_append(&loginmsg, "\n", 1);
994 }
995 reply[i].resp = xstrdup("");
996 reply[i].resp_retcode = PAM_SUCCESS;
997 break;
998 default:
999 goto fail;
1000 }
1001 }
1002 *resp = reply;
1003 return (PAM_SUCCESS);
1004
1005 fail:
1006 for(i = 0; i < n; i++) {
1007 if (reply[i].resp != NULL)
1008 xfree(reply[i].resp);
1009 }
1010 xfree(reply);
1011 return (PAM_CONV_ERR);
1012}
1013
1014static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
1015
1016/*
1017 * Attempt password authentication via PAM
1018 */
1019int
1020sshpam_auth_passwd(Authctxt *authctxt, const char *password)
1021{
1022 int flags = (options.permit_empty_passwd == 0 ?
1023 PAM_DISALLOW_NULL_AUTHTOK : 0);
1024
1025 if (!options.use_pam || sshpam_handle == NULL)
1026 fatal("PAM: %s called when PAM disabled or failed to "
1027 "initialise.", __func__);
1028
1029 sshpam_password = password;
1030 sshpam_authctxt = authctxt;
1031
1032 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
1033 (const void *)&passwd_conv);
1034 if (sshpam_err != PAM_SUCCESS)
1035 fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
1036 pam_strerror(sshpam_handle, sshpam_err));
1037
1038 sshpam_err = pam_authenticate(sshpam_handle, flags);
1039 sshpam_password = NULL;
1040 if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
1041 debug("PAM: password authentication accepted for %.100s",
1042 authctxt->user);
1043 return 1;
1044 } else {
1045 debug("PAM: password authentication failed for %.100s: %s",
1046 authctxt->valid ? authctxt->user : "an illegal user",
1047 pam_strerror(sshpam_handle, sshpam_err));
1048 return 0;
1049 }
1050}
954#endif /* USE_PAM */ 1051#endif /* USE_PAM */
diff --git a/auth-pam.h b/auth-pam.h
index 1b3706e07..f479413d7 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -1,4 +1,4 @@
1/* $Id: auth-pam.h,v 1.25 2004/03/08 12:04:07 dtucker Exp $ */ 1/* $Id: auth-pam.h,v 1.26 2004/05/30 10:43:59 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Damien Miller. All rights reserved. 4 * Copyright (c) 2000 Damien Miller. All rights reserved.
@@ -44,5 +44,6 @@ char ** fetch_pam_child_environment(void);
44void free_pam_environment(char **); 44void free_pam_environment(char **);
45void sshpam_thread_cleanup(void); 45void sshpam_thread_cleanup(void);
46void sshpam_cleanup(void); 46void sshpam_cleanup(void);
47int sshpam_auth_passwd(Authctxt *, const char *);
47 48
48#endif /* USE_PAM */ 49#endif /* USE_PAM */
diff --git a/auth-passwd.c b/auth-passwd.c
index beaf0fa6c..da247df7d 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -91,6 +91,10 @@ auth_password(Authctxt *authctxt, const char *password)
91 return ok; 91 return ok;
92 } 92 }
93#endif 93#endif
94#ifdef USE_PAM
95 if (options.use_pam)
96 return (sshpam_auth_passwd(authctxt, password) && ok);
97#endif
94#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) 98#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
95 if (!expire_checked) { 99 if (!expire_checked) {
96 expire_checked = 1; 100 expire_checked = 1;