|
Lines 169-174
static int sshpam_cred_established = 0;
Link Here
|
| 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 |
|
Lines 951-954
free_pam_environment(char **env)
Link Here
|
| 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 */ |