|
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 |
static int |
| 956 |
sshpam_passwd_conv(int n, const struct pam_message **msg, |
| 957 |
struct pam_response **resp, void *data) |
| 958 |
{ |
| 959 |
struct pam_response *reply; |
| 960 |
int i; |
| 961 |
size_t len; |
| 962 |
|
| 963 |
debug3("PAM: %s called with %d messages", __func__, n); |
| 964 |
|
| 965 |
*resp = NULL; |
| 966 |
|
| 967 |
if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) |
| 968 |
return (PAM_CONV_ERR); |
| 969 |
|
| 970 |
if ((reply = malloc(n * sizeof(*reply))) == NULL) |
| 971 |
return (PAM_CONV_ERR); |
| 972 |
memset(reply, 0, n * sizeof(*reply)); |
| 973 |
|
| 974 |
for (i = 0; i < n; ++i) { |
| 975 |
switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
| 976 |
case PAM_PROMPT_ECHO_OFF: |
| 977 |
if (sshpam_password == NULL) |
| 978 |
goto fail; |
| 979 |
reply[i].resp = xstrdup(sshpam_password); |
| 980 |
reply[i].resp_retcode = PAM_SUCCESS; |
| 981 |
break; |
| 982 |
case PAM_ERROR_MSG: |
| 983 |
case PAM_TEXT_INFO: |
| 984 |
len = strlen(PAM_MSG_MEMBER(msg, i, msg)); |
| 985 |
if (len > 0) { |
| 986 |
buffer_append(&loginmsg, |
| 987 |
PAM_MSG_MEMBER(msg, i, msg), len); |
| 988 |
buffer_append(&loginmsg, "\n", 1); |
| 989 |
} |
| 990 |
reply[i].resp = xstrdup(""); |
| 991 |
reply[i].resp_retcode = PAM_SUCCESS; |
| 992 |
break; |
| 993 |
case PAM_AUTH_ERR: |
| 994 |
error("PAM: %s for %s%.100s from %.100s", msg, |
| 995 |
sshpam_authctxt->valid ? "" : "illegal user ", |
| 996 |
sshpam_authctxt->user, |
| 997 |
get_remote_name_or_ip(utmp_len, options.use_dns)); |
| 998 |
/* FALLTHROUGH */ |
| 999 |
default: |
| 1000 |
goto fail; |
| 1001 |
} |
| 1002 |
} |
| 1003 |
*resp = reply; |
| 1004 |
return (PAM_SUCCESS); |
| 1005 |
|
| 1006 |
fail: |
| 1007 |
for(i = 0; i < n; i++) { |
| 1008 |
if (reply[i].resp != NULL) |
| 1009 |
xfree(reply[i].resp); |
| 1010 |
} |
| 1011 |
xfree(reply); |
| 1012 |
return (PAM_CONV_ERR); |
| 1013 |
} |
| 1014 |
|
| 1015 |
static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL }; |
| 1016 |
|
| 1017 |
int |
| 1018 |
sys_auth_passwd(Authctxt *authctxt, const char *password) |
| 1019 |
{ |
| 1020 |
int result, flags = (options.permit_empty_passwd == 0 ? |
| 1021 |
PAM_DISALLOW_NULL_AUTHTOK : 0); |
| 1022 |
|
| 1023 |
sshpam_password = password; |
| 1024 |
sshpam_authctxt = authctxt; |
| 1025 |
|
| 1026 |
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
| 1027 |
(const void *)&passwd_conv); |
| 1028 |
if (sshpam_err != PAM_SUCCESS) |
| 1029 |
fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, |
| 1030 |
pam_strerror(sshpam_handle, sshpam_err)); |
| 1031 |
|
| 1032 |
result = pam_authenticate(sshpam_handle, flags); |
| 1033 |
sshpam_password = NULL; |
| 1034 |
return (result == PAM_SUCCESS); |
| 1035 |
} |
| 954 |
#endif /* USE_PAM */ |
1036 |
#endif /* USE_PAM */ |