diff options
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 99 |
1 files changed, 98 insertions, 1 deletions
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" |
34 | RCSID("$Id: auth-pam.c,v 1.102 2004/05/24 01:55:36 dtucker Exp $"); | 34 | RCSID("$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; | |||
169 | static int sshpam_account_status = -1; | 169 | static int sshpam_account_status = -1; |
170 | static char **sshpam_env = NULL; | 170 | static char **sshpam_env = NULL; |
171 | static Authctxt *sshpam_authctxt = NULL; | 171 | static Authctxt *sshpam_authctxt = NULL; |
172 | static 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 | */ | ||
960 | static int | ||
961 | sshpam_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 | |||
1014 | static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL }; | ||
1015 | |||
1016 | /* | ||
1017 | * Attempt password authentication via PAM | ||
1018 | */ | ||
1019 | int | ||
1020 | sshpam_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 */ |