View | Details | Raw Unified | Return to bug 874 | Differences between
and this patch

Collapse All | Expand All

(-)auth-pam.c (+97 lines)
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 */
(-)auth-pam.h (+1 lines)
Lines 44-48 char ** fetch_pam_child_environment(void Link Here
44
void free_pam_environment(char **);
44
void free_pam_environment(char **);
45
void sshpam_thread_cleanup(void);
45
void sshpam_thread_cleanup(void);
46
void sshpam_cleanup(void);
46
void sshpam_cleanup(void);
47
int sshpam_auth_passwd(Authctxt *, const char *);
47
48
48
#endif /* USE_PAM */
49
#endif /* USE_PAM */
(-)auth-passwd.c (+4 lines)
Lines 91-96 auth_password(Authctxt *authctxt, const Link Here
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;

Return to bug 874