From 342b8b88ba0766330012185207b57cfded73abc9 Mon Sep 17 00:00:00 2001 From: Kurt Lidl Date: Fri, 12 May 2017 15:20:12 +0000 Subject: [PATCH] Refine and update blacklist support in sshd Adjust notification points slightly to catch all auth failures, rather than just the ones caused by bad usernames. Modify notification point for bad usernames to send new type of BLACKLIST_BAD_USER. (Support in libblacklist will be forthcoming soon.) Add guards to allow library headers to expose the enum of action values. Reviewed by: des Approved by: des Sponsored by: The FreeBSD Foundation --- crypto/openssh/auth-pam.c | 3 ++- crypto/openssh/auth.c | 4 ++-- crypto/openssh/auth1.c | 5 +++-- crypto/openssh/auth2.c | 5 +++-- crypto/openssh/blacklist.c | 6 +++--- crypto/openssh/blacklist_client.h | 12 ++++++++---- crypto/openssh/packet.c | 2 +- crypto/openssh/sshd.c | 2 +- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c index 8f8625894c8e..77e9e2bae7d3 100644 --- a/crypto/openssh/auth-pam.c +++ b/crypto/openssh/auth-pam.c @@ -799,7 +799,8 @@ sshpam_query(void *ctx, char **name, char **info, free(msg); return (0); } - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, + sshpam_authctxt->user); error("PAM: %s for %s%.100s from %.100s", msg, sshpam_authctxt->valid ? "" : "illegal user ", sshpam_authctxt->user, diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index a769f31e1bbb..1343ea0938a7 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -311,7 +311,7 @@ auth_log(Authctxt *authctxt, int authenticated, int partial, else { authmsg = authenticated ? "Accepted" : "Failed"; if (authenticated) - BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK); + BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, "ssh"); } authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s", @@ -664,7 +664,7 @@ getpwnamallow(const char *user) } #endif if (pw == NULL) { - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user); logit("Invalid user %.100s from %.100s port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index 71eb0c21b260..189954425ac2 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/auth1.c @@ -338,7 +338,7 @@ do_authloop(Authctxt *authctxt) char *msg; size_t len; - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh"); error("Access denied for user %s by PAM account " "configuration", authctxt->user); len = buffer_len(&loginmsg); @@ -364,6 +364,7 @@ do_authloop(Authctxt *authctxt) if (authenticated) return; + BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh"); if (++authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); @@ -406,7 +407,7 @@ do_authentication(Authctxt *authctxt) else { debug("do_authentication: invalid user %s", user); authctxt->pw = fakepw(); - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user); } /* Configuration may have changed as a result of Match */ diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 133b09a43ae0..b6695f79d0aa 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -245,7 +245,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_INVALID_USER)); #endif @@ -386,8 +385,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, /* Allow initial try of "none" auth without failure penalty */ if (!partial && !authctxt->server_caused_failure && - (authctxt->attempt > 1 || strcmp(method, "none") != 0)) + (authctxt->attempt > 1 || strcmp(method, "none") != 0)) { authctxt->failures++; + BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh"); + } if (authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); diff --git a/crypto/openssh/blacklist.c b/crypto/openssh/blacklist.c index 4c9d91dec164..b4f5d3e128c1 100644 --- a/crypto/openssh/blacklist.c +++ b/crypto/openssh/blacklist.c @@ -46,8 +46,8 @@ #include "log.h" #include "misc.h" #include "servconf.h" -#include "blacklist_client.h" #include +#include "blacklist_client.h" static struct blacklist *blstate = NULL; @@ -88,10 +88,10 @@ blacklist_init(void) } void -blacklist_notify(int action) +blacklist_notify(int action, const char *msg) { if (blstate != NULL && packet_connection_is_on_socket()) (void)blacklist_r(blstate, action, - packet_get_connection_in(), "ssh"); + packet_get_connection_in(), msg); } diff --git a/crypto/openssh/blacklist_client.h b/crypto/openssh/blacklist_client.h index 9479bb27be46..af5a2a6d3c1d 100644 --- a/crypto/openssh/blacklist_client.h +++ b/crypto/openssh/blacklist_client.h @@ -34,22 +34,26 @@ #ifndef BLACKLIST_CLIENT_H #define BLACKLIST_CLIENT_H +#ifndef BLACKLIST_API_ENUM enum { BLACKLIST_AUTH_OK = 0, - BLACKLIST_AUTH_FAIL + BLACKLIST_AUTH_FAIL, + BLACKLIST_ABUSIVE_BEHAVIOR, + BLACKLIST_BAD_USER }; +#endif #ifdef USE_BLACKLIST void blacklist_init(void); -void blacklist_notify(int); +void blacklist_notify(int, const char *); #define BLACKLIST_INIT() blacklist_init() -#define BLACKLIST_NOTIFY(x) blacklist_notify(x) +#define BLACKLIST_NOTIFY(x,msg) blacklist_notify(x,msg) #else #define BLACKLIST_INIT() -#define BLACKLIST_NOTIFY(x) +#define BLACKLIST_NOTIFY(x,msg) #endif diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index 5db5828749a4..9ef5778baffc 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -2104,7 +2104,7 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r) case SSH_ERR_NO_KEX_ALG_MATCH: case SSH_ERR_NO_HOSTKEY_ALG_MATCH: if (ssh && ssh->kex && ssh->kex->failed_choice) { - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh"); logdie("Unable to negotiate with %.200s port %d: %s. " "Their offer: %s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r), diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 57090d6d51a0..50d3701e78b2 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -371,7 +371,7 @@ grace_alarm_handler(int sig) kill(0, SIGTERM); } - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); + BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh"); /* Log error and exit. */ sigdie("Timeout before authentication for %s port %d",