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
This commit is contained in:
Kurt Lidl 2017-05-12 15:20:12 +00:00
parent b168d62f00
commit 342b8b88ba
8 changed files with 23 additions and 16 deletions

View File

@ -799,7 +799,8 @@ sshpam_query(void *ctx, char **name, char **info,
free(msg); free(msg);
return (0); return (0);
} }
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); BLACKLIST_NOTIFY(BLACKLIST_BAD_USER,
sshpam_authctxt->user);
error("PAM: %s for %s%.100s from %.100s", msg, error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ", sshpam_authctxt->valid ? "" : "illegal user ",
sshpam_authctxt->user, sshpam_authctxt->user,

View File

@ -311,7 +311,7 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
else { else {
authmsg = authenticated ? "Accepted" : "Failed"; authmsg = authenticated ? "Accepted" : "Failed";
if (authenticated) 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", authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
@ -664,7 +664,7 @@ getpwnamallow(const char *user)
} }
#endif #endif
if (pw == NULL) { if (pw == NULL) {
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user);
logit("Invalid user %.100s from %.100s port %d", logit("Invalid user %.100s from %.100s port %d",
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#ifdef CUSTOM_FAILED_LOGIN #ifdef CUSTOM_FAILED_LOGIN

View File

@ -338,7 +338,7 @@ do_authloop(Authctxt *authctxt)
char *msg; char *msg;
size_t len; size_t len;
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
error("Access denied for user %s by PAM account " error("Access denied for user %s by PAM account "
"configuration", authctxt->user); "configuration", authctxt->user);
len = buffer_len(&loginmsg); len = buffer_len(&loginmsg);
@ -364,6 +364,7 @@ do_authloop(Authctxt *authctxt)
if (authenticated) if (authenticated)
return; return;
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
if (++authctxt->failures >= options.max_authtries) { if (++authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS #ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
@ -406,7 +407,7 @@ do_authentication(Authctxt *authctxt)
else { else {
debug("do_authentication: invalid user %s", user); debug("do_authentication: invalid user %s", user);
authctxt->pw = fakepw(); authctxt->pw = fakepw();
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user);
} }
/* Configuration may have changed as a result of Match */ /* Configuration may have changed as a result of Match */

View File

@ -245,7 +245,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
} else { } else {
logit("input_userauth_request: invalid user %s", user); logit("input_userauth_request: invalid user %s", user);
authctxt->pw = fakepw(); authctxt->pw = fakepw();
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
#ifdef SSH_AUDIT_EVENTS #ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_INVALID_USER)); PRIVSEP(audit_event(SSH_INVALID_USER));
#endif #endif
@ -386,8 +385,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
/* Allow initial try of "none" auth without failure penalty */ /* Allow initial try of "none" auth without failure penalty */
if (!partial && !authctxt->server_caused_failure && if (!partial && !authctxt->server_caused_failure &&
(authctxt->attempt > 1 || strcmp(method, "none") != 0)) (authctxt->attempt > 1 || strcmp(method, "none") != 0)) {
authctxt->failures++; authctxt->failures++;
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
}
if (authctxt->failures >= options.max_authtries) { if (authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS #ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));

View File

@ -46,8 +46,8 @@
#include "log.h" #include "log.h"
#include "misc.h" #include "misc.h"
#include "servconf.h" #include "servconf.h"
#include "blacklist_client.h"
#include <blacklist.h> #include <blacklist.h>
#include "blacklist_client.h"
static struct blacklist *blstate = NULL; static struct blacklist *blstate = NULL;
@ -88,10 +88,10 @@ blacklist_init(void)
} }
void void
blacklist_notify(int action) blacklist_notify(int action, const char *msg)
{ {
if (blstate != NULL && packet_connection_is_on_socket()) if (blstate != NULL && packet_connection_is_on_socket())
(void)blacklist_r(blstate, action, (void)blacklist_r(blstate, action,
packet_get_connection_in(), "ssh"); packet_get_connection_in(), msg);
} }

View File

@ -34,22 +34,26 @@
#ifndef BLACKLIST_CLIENT_H #ifndef BLACKLIST_CLIENT_H
#define BLACKLIST_CLIENT_H #define BLACKLIST_CLIENT_H
#ifndef BLACKLIST_API_ENUM
enum { enum {
BLACKLIST_AUTH_OK = 0, BLACKLIST_AUTH_OK = 0,
BLACKLIST_AUTH_FAIL BLACKLIST_AUTH_FAIL,
BLACKLIST_ABUSIVE_BEHAVIOR,
BLACKLIST_BAD_USER
}; };
#endif
#ifdef USE_BLACKLIST #ifdef USE_BLACKLIST
void blacklist_init(void); void blacklist_init(void);
void blacklist_notify(int); void blacklist_notify(int, const char *);
#define BLACKLIST_INIT() blacklist_init() #define BLACKLIST_INIT() blacklist_init()
#define BLACKLIST_NOTIFY(x) blacklist_notify(x) #define BLACKLIST_NOTIFY(x,msg) blacklist_notify(x,msg)
#else #else
#define BLACKLIST_INIT() #define BLACKLIST_INIT()
#define BLACKLIST_NOTIFY(x) #define BLACKLIST_NOTIFY(x,msg)
#endif #endif

View File

@ -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_KEX_ALG_MATCH:
case SSH_ERR_NO_HOSTKEY_ALG_MATCH: case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
if (ssh && ssh->kex && ssh->kex->failed_choice) { 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. " logdie("Unable to negotiate with %.200s port %d: %s. "
"Their offer: %s", ssh_remote_ipaddr(ssh), "Their offer: %s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), ssh_err(r), ssh_remote_port(ssh), ssh_err(r),

View File

@ -371,7 +371,7 @@ grace_alarm_handler(int sig)
kill(0, SIGTERM); kill(0, SIGTERM);
} }
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, "ssh");
/* Log error and exit. */ /* Log error and exit. */
sigdie("Timeout before authentication for %s port %d", sigdie("Timeout before authentication for %s port %d",