mirror of git://anongit.mindrot.org/openssh.git
Handle PAM_MAXTRIES from modules.
bz#2249: handle the case where PAM returns PAM_MAXTRIES by ceasing to offer password and keyboard-interative authentication methods. Should prevent "sshd ignoring max retries" warnings in the log. ok djm@ It probably won't trigger with keyboard-interactive in the default configuration because the retry counter is stored in module-private storage which goes away with the sshd PAM process (see bz#688). On the other hand, those cases probably won't log a warning either.
This commit is contained in:
parent
65c6c6b567
commit
01558b7b07
30
auth-pam.c
30
auth-pam.c
|
@ -229,6 +229,7 @@ static int sshpam_authenticated = 0;
|
|||
static int sshpam_session_open = 0;
|
||||
static int sshpam_cred_established = 0;
|
||||
static int sshpam_account_status = -1;
|
||||
static int sshpam_maxtries_reached = 0;
|
||||
static char **sshpam_env = NULL;
|
||||
static Authctxt *sshpam_authctxt = NULL;
|
||||
static const char *sshpam_password = NULL;
|
||||
|
@ -450,6 +451,8 @@ sshpam_thread(void *ctxtp)
|
|||
if (sshpam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
sshpam_err = pam_authenticate(sshpam_handle, flags);
|
||||
if (sshpam_err == PAM_MAXTRIES)
|
||||
sshpam_set_maxtries_reached(1);
|
||||
if (sshpam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
|
||||
|
@ -501,6 +504,8 @@ sshpam_thread(void *ctxtp)
|
|||
/* XXX - can't do much about an error here */
|
||||
if (sshpam_err == PAM_ACCT_EXPIRED)
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
|
||||
else if (sshpam_maxtries_reached)
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer);
|
||||
else
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
|
||||
buffer_free(&buffer);
|
||||
|
@ -741,7 +746,11 @@ sshpam_query(void *ctx, char **name, char **info,
|
|||
free(msg);
|
||||
break;
|
||||
case PAM_ACCT_EXPIRED:
|
||||
sshpam_account_status = 0;
|
||||
case PAM_MAXTRIES:
|
||||
if (type == PAM_ACCT_EXPIRED)
|
||||
sshpam_account_status = 0;
|
||||
if (type == PAM_MAXTRIES)
|
||||
sshpam_set_maxtries_reached(1);
|
||||
/* FALLTHROUGH */
|
||||
case PAM_AUTH_ERR:
|
||||
debug3("PAM: %s", pam_strerror(sshpam_handle, type));
|
||||
|
@ -1218,6 +1227,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
|
|||
sshpam_err = pam_authenticate(sshpam_handle, flags);
|
||||
sshpam_password = NULL;
|
||||
free(fake);
|
||||
if (sshpam_err == PAM_MAXTRIES)
|
||||
sshpam_set_maxtries_reached(1);
|
||||
if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
|
||||
debug("PAM: password authentication accepted for %.100s",
|
||||
authctxt->user);
|
||||
|
@ -1229,4 +1240,21 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sshpam_get_maxtries_reached(void)
|
||||
{
|
||||
return sshpam_maxtries_reached;
|
||||
}
|
||||
|
||||
void
|
||||
sshpam_set_maxtries_reached(int reached)
|
||||
{
|
||||
if (reached == 0 || sshpam_maxtries_reached)
|
||||
return;
|
||||
sshpam_maxtries_reached = 1;
|
||||
options.password_authentication = 0;
|
||||
options.kbd_interactive_authentication = 0;
|
||||
options.challenge_response_authentication = 0;
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
|
|
@ -45,6 +45,8 @@ void free_pam_environment(char **);
|
|||
void sshpam_thread_cleanup(void);
|
||||
void sshpam_cleanup(void);
|
||||
int sshpam_auth_passwd(Authctxt *, const char *);
|
||||
int sshpam_get_maxtries_reached(void);
|
||||
void sshpam_set_maxtries_reached(int);
|
||||
int is_pam_session_open(void);
|
||||
|
||||
#endif /* USE_PAM */
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "dh.h"
|
||||
#include "auth-pam.h"
|
||||
#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
|
||||
#undef TARGET_OS_MAC
|
||||
#include "zlib.h"
|
||||
|
@ -920,6 +921,9 @@ mm_answer_authpassword(int sock, Buffer *m)
|
|||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, authenticated);
|
||||
#ifdef USE_PAM
|
||||
buffer_put_int(m, sshpam_get_maxtries_reached());
|
||||
#endif
|
||||
|
||||
debug3("%s: sending result %d", __func__, authenticated);
|
||||
mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m);
|
||||
|
@ -1119,6 +1123,7 @@ mm_answer_pam_query(int sock, Buffer *m)
|
|||
free(name);
|
||||
buffer_put_cstring(m, info);
|
||||
free(info);
|
||||
buffer_put_int(m, sshpam_get_maxtries_reached());
|
||||
buffer_put_int(m, num);
|
||||
for (i = 0; i < num; ++i) {
|
||||
buffer_put_cstring(m, prompts[i]);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "packet.h"
|
||||
#include "mac.h"
|
||||
#include "log.h"
|
||||
#include "auth-pam.h"
|
||||
#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
|
||||
#undef TARGET_OS_MAC
|
||||
#include "zlib.h"
|
||||
|
@ -362,6 +363,9 @@ mm_auth_password(Authctxt *authctxt, char *password)
|
|||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
|
||||
|
||||
authenticated = buffer_get_int(&m);
|
||||
#ifdef USE_PAM
|
||||
sshpam_set_maxtries_reached(buffer_get_int(&m));
|
||||
#endif
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
|
@ -644,6 +648,7 @@ mm_sshpam_query(void *ctx, char **name, char **info,
|
|||
debug3("%s: pam_query returned %d", __func__, ret);
|
||||
*name = buffer_get_string(&m, NULL);
|
||||
*info = buffer_get_string(&m, NULL);
|
||||
sshpam_set_maxtries_reached(buffer_get_int(&m));
|
||||
*num = buffer_get_int(&m);
|
||||
if (*num > PAM_MAX_NUM_MSG)
|
||||
fatal("%s: recieved %u PAM messages, expected <= %u",
|
||||
|
|
Loading…
Reference in New Issue