diff options
-rw-r--r-- | auth-pam.c | 30 | ||||
-rw-r--r-- | auth-pam.h | 2 | ||||
-rw-r--r-- | monitor.c | 5 | ||||
-rw-r--r-- | monitor_wrap.c | 5 |
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; | |||
229 | static int sshpam_session_open = 0; | 229 | static int sshpam_session_open = 0; |
230 | static int sshpam_cred_established = 0; | 230 | static int sshpam_cred_established = 0; |
231 | static int sshpam_account_status = -1; | 231 | static int sshpam_account_status = -1; |
232 | static int sshpam_maxtries_reached = 0; | ||
232 | static char **sshpam_env = NULL; | 233 | static char **sshpam_env = NULL; |
233 | static Authctxt *sshpam_authctxt = NULL; | 234 | static Authctxt *sshpam_authctxt = NULL; |
234 | static const char *sshpam_password = NULL; | 235 | static 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 | |||
1244 | int | ||
1245 | sshpam_get_maxtries_reached(void) | ||
1246 | { | ||
1247 | return sshpam_maxtries_reached; | ||
1248 | } | ||
1249 | |||
1250 | void | ||
1251 | sshpam_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 **); | |||
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 | int sshpam_auth_passwd(Authctxt *, const char *); |
48 | int sshpam_get_maxtries_reached(void); | ||
49 | void sshpam_set_maxtries_reached(int); | ||
48 | int is_pam_session_open(void); | 50 | int is_pam_session_open(void); |
49 | 51 | ||
50 | #endif /* USE_PAM */ | 52 | #endif /* USE_PAM */ |
@@ -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", |