summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2016-07-18 09:33:25 +1000
committerDarren Tucker <dtucker@zip.com.au>2016-07-18 09:33:25 +1000
commit01558b7b07af43da774d3a11a5c51fa9c310849d (patch)
tree97052332089b01018034206d1dcd683c4177f787
parent65c6c6b567ab5ab12945a5ad8e0ab3a8c26119cc (diff)
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.
-rw-r--r--auth-pam.c30
-rw-r--r--auth-pam.h2
-rw-r--r--monitor.c5
-rw-r--r--monitor_wrap.c5
4 files changed, 41 insertions, 1 deletions
diff --git a/auth-pam.c b/auth-pam.c
index 465b5a702..1f13c181c 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -229,6 +229,7 @@ static int sshpam_authenticated = 0;
229static int sshpam_session_open = 0; 229static int sshpam_session_open = 0;
230static int sshpam_cred_established = 0; 230static int sshpam_cred_established = 0;
231static int sshpam_account_status = -1; 231static int sshpam_account_status = -1;
232static int sshpam_maxtries_reached = 0;
232static char **sshpam_env = NULL; 233static char **sshpam_env = NULL;
233static Authctxt *sshpam_authctxt = NULL; 234static Authctxt *sshpam_authctxt = NULL;
234static const char *sshpam_password = NULL; 235static const char *sshpam_password = NULL;
@@ -450,6 +451,8 @@ sshpam_thread(void *ctxtp)
450 if (sshpam_err != PAM_SUCCESS) 451 if (sshpam_err != PAM_SUCCESS)
451 goto auth_fail; 452 goto auth_fail;
452 sshpam_err = pam_authenticate(sshpam_handle, flags); 453 sshpam_err = pam_authenticate(sshpam_handle, flags);
454 if (sshpam_err == PAM_MAXTRIES)
455 sshpam_set_maxtries_reached(1);
453 if (sshpam_err != PAM_SUCCESS) 456 if (sshpam_err != PAM_SUCCESS)
454 goto auth_fail; 457 goto auth_fail;
455 458
@@ -501,6 +504,8 @@ sshpam_thread(void *ctxtp)
501 /* XXX - can't do much about an error here */ 504 /* XXX - can't do much about an error here */
502 if (sshpam_err == PAM_ACCT_EXPIRED) 505 if (sshpam_err == PAM_ACCT_EXPIRED)
503 ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); 506 ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
507 else if (sshpam_maxtries_reached)
508 ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer);
504 else 509 else
505 ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); 510 ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
506 buffer_free(&buffer); 511 buffer_free(&buffer);
@@ -741,7 +746,11 @@ sshpam_query(void *ctx, char **name, char **info,
741 free(msg); 746 free(msg);
742 break; 747 break;
743 case PAM_ACCT_EXPIRED: 748 case PAM_ACCT_EXPIRED:
744 sshpam_account_status = 0; 749 case PAM_MAXTRIES:
750 if (type == PAM_ACCT_EXPIRED)
751 sshpam_account_status = 0;
752 if (type == PAM_MAXTRIES)
753 sshpam_set_maxtries_reached(1);
745 /* FALLTHROUGH */ 754 /* FALLTHROUGH */
746 case PAM_AUTH_ERR: 755 case PAM_AUTH_ERR:
747 debug3("PAM: %s", pam_strerror(sshpam_handle, type)); 756 debug3("PAM: %s", pam_strerror(sshpam_handle, type));
@@ -1218,6 +1227,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
1218 sshpam_err = pam_authenticate(sshpam_handle, flags); 1227 sshpam_err = pam_authenticate(sshpam_handle, flags);
1219 sshpam_password = NULL; 1228 sshpam_password = NULL;
1220 free(fake); 1229 free(fake);
1230 if (sshpam_err == PAM_MAXTRIES)
1231 sshpam_set_maxtries_reached(1);
1221 if (sshpam_err == PAM_SUCCESS && authctxt->valid) { 1232 if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
1222 debug("PAM: password authentication accepted for %.100s", 1233 debug("PAM: password authentication accepted for %.100s",
1223 authctxt->user); 1234 authctxt->user);
@@ -1229,4 +1240,21 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
1229 return 0; 1240 return 0;
1230 } 1241 }
1231} 1242}
1243
1244int
1245sshpam_get_maxtries_reached(void)
1246{
1247 return sshpam_maxtries_reached;
1248}
1249
1250void
1251sshpam_set_maxtries_reached(int reached)
1252{
1253 if (reached == 0 || sshpam_maxtries_reached)
1254 return;
1255 sshpam_maxtries_reached = 1;
1256 options.password_authentication = 0;
1257 options.kbd_interactive_authentication = 0;
1258 options.challenge_response_authentication = 0;
1259}
1232#endif /* USE_PAM */ 1260#endif /* USE_PAM */
diff --git a/auth-pam.h b/auth-pam.h
index a1a2b52d8..2e9a0c0a3 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -45,6 +45,8 @@ void free_pam_environment(char **);
45void sshpam_thread_cleanup(void); 45void sshpam_thread_cleanup(void);
46void sshpam_cleanup(void); 46void sshpam_cleanup(void);
47int sshpam_auth_passwd(Authctxt *, const char *); 47int sshpam_auth_passwd(Authctxt *, const char *);
48int sshpam_get_maxtries_reached(void);
49void sshpam_set_maxtries_reached(int);
48int is_pam_session_open(void); 50int is_pam_session_open(void);
49 51
50#endif /* USE_PAM */ 52#endif /* USE_PAM */
diff --git a/monitor.c b/monitor.c
index 8b3c27a76..fbe965e7c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -75,6 +75,7 @@
75#include "cipher.h" 75#include "cipher.h"
76#include "kex.h" 76#include "kex.h"
77#include "dh.h" 77#include "dh.h"
78#include "auth-pam.h"
78#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 79#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
79#undef TARGET_OS_MAC 80#undef TARGET_OS_MAC
80#include "zlib.h" 81#include "zlib.h"
@@ -920,6 +921,9 @@ mm_answer_authpassword(int sock, Buffer *m)
920 921
921 buffer_clear(m); 922 buffer_clear(m);
922 buffer_put_int(m, authenticated); 923 buffer_put_int(m, authenticated);
924#ifdef USE_PAM
925 buffer_put_int(m, sshpam_get_maxtries_reached());
926#endif
923 927
924 debug3("%s: sending result %d", __func__, authenticated); 928 debug3("%s: sending result %d", __func__, authenticated);
925 mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); 929 mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m);
@@ -1119,6 +1123,7 @@ mm_answer_pam_query(int sock, Buffer *m)
1119 free(name); 1123 free(name);
1120 buffer_put_cstring(m, info); 1124 buffer_put_cstring(m, info);
1121 free(info); 1125 free(info);
1126 buffer_put_int(m, sshpam_get_maxtries_reached());
1122 buffer_put_int(m, num); 1127 buffer_put_int(m, num);
1123 for (i = 0; i < num; ++i) { 1128 for (i = 0; i < num; ++i) {
1124 buffer_put_cstring(m, prompts[i]); 1129 buffer_put_cstring(m, prompts[i]);
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 552004902..99dc13b61 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -60,6 +60,7 @@
60#include "packet.h" 60#include "packet.h"
61#include "mac.h" 61#include "mac.h"
62#include "log.h" 62#include "log.h"
63#include "auth-pam.h"
63#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 64#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
64#undef TARGET_OS_MAC 65#undef TARGET_OS_MAC
65#include "zlib.h" 66#include "zlib.h"
@@ -362,6 +363,9 @@ mm_auth_password(Authctxt *authctxt, char *password)
362 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 363 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
363 364
364 authenticated = buffer_get_int(&m); 365 authenticated = buffer_get_int(&m);
366#ifdef USE_PAM
367 sshpam_set_maxtries_reached(buffer_get_int(&m));
368#endif
365 369
366 buffer_free(&m); 370 buffer_free(&m);
367 371
@@ -644,6 +648,7 @@ mm_sshpam_query(void *ctx, char **name, char **info,
644 debug3("%s: pam_query returned %d", __func__, ret); 648 debug3("%s: pam_query returned %d", __func__, ret);
645 *name = buffer_get_string(&m, NULL); 649 *name = buffer_get_string(&m, NULL);
646 *info = buffer_get_string(&m, NULL); 650 *info = buffer_get_string(&m, NULL);
651 sshpam_set_maxtries_reached(buffer_get_int(&m));
647 *num = buffer_get_int(&m); 652 *num = buffer_get_int(&m);
648 if (*num > PAM_MAX_NUM_MSG) 653 if (*num > PAM_MAX_NUM_MSG)
649 fatal("%s: recieved %u PAM messages, expected <= %u", 654 fatal("%s: recieved %u PAM messages, expected <= %u",