Index: crypto/openssh/auth-pam.c =================================================================== --- crypto/openssh/auth-pam.c +++ crypto/openssh/auth-pam.c @@ -98,6 +98,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" +#include "blacklist_client.h" extern ServerOptions options; extern Buffer loginmsg; @@ -794,6 +795,7 @@ free(msg); return (0); } + blacklistd_notify(BLACKLISTD_AUTH_FAIL); error("PAM: %s for %s%.100s from %.100s", msg, sshpam_authctxt->valid ? "" : "illegal user ", sshpam_authctxt->user, Index: crypto/openssh/auth.c =================================================================== --- crypto/openssh/auth.c +++ crypto/openssh/auth.c @@ -75,6 +75,7 @@ #include "authfile.h" #include "ssherr.h" #include "compat.h" +#include "blacklist_client.h" /* import */ extern ServerOptions options; @@ -288,9 +289,13 @@ strcmp(method, "password") == 0) authlog = logit; - if (authctxt->postponed) + if (authctxt->postponed) { authmsg = "Postponed"; - else if (partial) + if (authenticated) + blacklistd_notify(BLACKLISTD_AUTH_OK); + else + blacklistd_notify(BLACKLISTD_AUTH_FAIL); + } else if (partial) authmsg = "Partial"; else authmsg = authenticated ? "Accepted" : "Failed"; @@ -640,6 +645,7 @@ } #endif if (pw == NULL) { + blacklistd_notify(BLACKLISTD_AUTH_FAIL); logit("Invalid user %.100s from %.100s", user, get_remote_ipaddr()); #ifdef CUSTOM_FAILED_LOGIN Index: crypto/openssh/auth1.c =================================================================== --- crypto/openssh/auth1.c +++ crypto/openssh/auth1.c @@ -43,6 +43,7 @@ #endif #include "monitor_wrap.h" #include "buffer.h" +#include "blacklist_client.h" /* import */ extern ServerOptions options; @@ -337,6 +338,7 @@ char *msg; size_t len; + blacklistd_notify(BLACKLISTD_AUTH_FAIL); error("Access denied for user %s by PAM account " "configuration", authctxt->user); len = buffer_len(&loginmsg); @@ -404,6 +406,7 @@ else { debug("do_authentication: invalid user %s", user); authctxt->pw = fakepw(); + blacklistd_notify(BLACKLISTD_AUTH_FAIL); } /* Configuration may have changed as a result of Match */ Index: crypto/openssh/auth2.c =================================================================== --- crypto/openssh/auth2.c +++ crypto/openssh/auth2.c @@ -52,6 +52,7 @@ #include "pathnames.h" #include "buffer.h" #include "canohost.h" +#include "blacklist_client.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -248,6 +249,7 @@ } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); + blacklistd_notify(BLACKLISTD_AUTH_FAIL); #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_INVALID_USER)); #endif Index: crypto/openssh/blacklist.c =================================================================== --- /dev/null +++ crypto/openssh/blacklist.c @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * Copyright (c) 2016 The FreeBSD Foundation, Inc. + * All rights reserved. + * + * Portions of this software were developed by Kurt Lidl + * under sponsorship from the FreeBSD Foundation. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "ssh.h" +#include "packet.h" +#include "log.h" +#include "misc.h" +#include "servconf.h" +#include "blacklist_client.h" +#include + +static struct blacklist *blstate = NULL; + +/* import */ +extern ServerOptions options; + +void +blacklistd_init(void) +{ + + if (options.use_blacklistd) +#ifdef USE_BLACKLIST + blstate = blacklist_open(); +#else + debug("This binary is not compiled with blacklistd support."); +#endif +} + +void +blacklistd_notify(int action) +{ + int fd; + + if (blstate == NULL) + return; + +#ifdef USE_BLACKLIST + fd = packet_get_connection_in(); + if (!packet_connection_is_on_socket()) { + fprintf(stderr, "packet_connection_is_on_socket: false " + "(fd = %d)\n", fd); + } + (void)blacklist_r(blstate, action, fd, "ssh"); +#endif +} Index: crypto/openssh/blacklist_client.h =================================================================== --- /dev/null +++ crypto/openssh/blacklist_client.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * Copyright (c) 2016 The FreeBSD Foundation, Inc. + * All rights reserved. + * + * Portions of this software were developed by Kurt Lidl + * under sponsorship from the FreeBSD Foundation. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +enum blacklistd_actions { + BLACKLISTD_AUTH_OK = 0, + BLACKLISTD_AUTH_FAIL +}; + +void blacklistd_notify(int); +void blacklistd_init(void); Index: crypto/openssh/packet.c =================================================================== --- crypto/openssh/packet.c +++ crypto/openssh/packet.c @@ -86,6 +86,7 @@ #include "packet.h" #include "ssherr.h" #include "sshbuf.h" +#include "blacklist_client.h" #ifdef PACKET_DEBUG #define DBG(x) x @@ -2071,6 +2072,9 @@ case SSH_ERR_NO_KEX_ALG_MATCH: case SSH_ERR_NO_HOSTKEY_ALG_MATCH: if (ssh && ssh->kex && ssh->kex->failed_choice) { +#ifdef USE_BLACKLIST + blacklistd_notify(BLACKLISTD_AUTH_FAIL); +#endif fatal("Unable to negotiate with %.200s port %d: %s. " "Their offer: %s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r), Index: crypto/openssh/servconf.h =================================================================== --- crypto/openssh/servconf.h +++ crypto/openssh/servconf.h @@ -155,6 +155,7 @@ int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ + int use_blacklistd; int use_dns; int client_alive_interval; /* * poke the client this often to Index: crypto/openssh/servconf.c =================================================================== --- crypto/openssh/servconf.c +++ crypto/openssh/servconf.c @@ -151,6 +151,7 @@ options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; + options->use_blacklistd = -1; options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; @@ -331,6 +332,8 @@ options->max_authtries = DEFAULT_AUTH_FAIL_MAX; if (options->max_sessions == -1) options->max_sessions = DEFAULT_SESSIONS_MAX; + if (options->use_blacklistd == -1) + options->use_blacklistd = 0; if (options->use_dns == -1) options->use_dns = 1; if (options->client_alive_interval == -1) @@ -418,7 +421,7 @@ sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, - sBanner, sUseDNS, sHostbasedAuthentication, + sBanner, sUseBlacklistd, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -544,6 +547,7 @@ { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, + { "useblacklistd", sUseBlacklistd, SSHCFG_GLOBAL }, { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, @@ -1359,6 +1363,10 @@ multistate_ptr = multistate_gatewayports; goto parse_multistate; + case sUseBlacklistd: + intptr = &options->use_blacklistd; + goto parse_flag; + case sUseDNS: intptr = &options->use_dns; goto parse_flag; @@ -2295,6 +2303,7 @@ dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); + dump_cfg_fmtint(sUseBlacklistd, o->use_blacklistd); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); Index: crypto/openssh/sshd.c =================================================================== --- crypto/openssh/sshd.c +++ crypto/openssh/sshd.c @@ -135,6 +135,7 @@ #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" +#include "blacklist_client.h" #ifdef LIBWRAP #include @@ -388,6 +389,8 @@ kill(0, SIGTERM); } + blacklistd_notify(BLACKLISTD_AUTH_FAIL); + /* Log error and exit. */ sigdie("Timeout before authentication for %s", get_remote_ipaddr()); } @@ -651,6 +654,7 @@ /* Demote the child */ if (getuid() == 0 || geteuid() == 0) { + blacklistd_init(); /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, @@ -1272,6 +1276,8 @@ for (i = 0; i < options.max_startups; i++) startup_pipes[i] = -1; + blacklistd_init(); + /* * Stay listening for connections until the system crashes or * the daemon is killed with a signal. Index: crypto/openssh/sshd_config =================================================================== --- crypto/openssh/sshd_config +++ crypto/openssh/sshd_config @@ -115,6 +115,7 @@ #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 +#UseBlacklistd no #UseDNS yes #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 Index: crypto/openssh/sshd_config.5 =================================================================== --- crypto/openssh/sshd_config.5 +++ crypto/openssh/sshd_config.5 @@ -1543,6 +1543,15 @@ .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . +.It Cm UseBlacklistd +Specifies whether +.Xr sshd 8 +should attempt to send authentication success and failure messages +to the +.Xr blacklistd 8 +daemon. +The default is +.Dq no . .It Cm UseDNS Specifies whether .Xr sshd 8 Index: secure/usr.sbin/sshd/Makefile =================================================================== --- secure/usr.sbin/sshd/Makefile +++ secure/usr.sbin/sshd/Makefile @@ -16,7 +16,7 @@ sftp-server.c sftp-common.c \ sandbox-null.c sandbox-rlimit.c sandbox-systrace.c sandbox-darwin.c \ sandbox-seccomp-filter.c sandbox-capsicum.c sandbox-pledge.c \ - sandbox-solaris.c + sandbox-solaris.c blacklist.c PACKAGE= ssh # gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile @@ -40,6 +40,12 @@ LIBADD+= bsm .endif +.if ${MK_BLACKLIST_SUPPORT} != "no" +CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include +LIBADD+= blacklist +LDFLAGS+=-L${LIBBLACKLISTDIR} +.endif + .if ${MK_KERBEROS_SUPPORT} != "no" CFLAGS+= -include krb5_config.h SRCS+= krb5_config.h Index: secure/usr.sbin/sshd/Makefile.depend =================================================================== --- secure/usr.sbin/sshd/Makefile.depend +++ secure/usr.sbin/sshd/Makefile.depend @@ -17,6 +17,7 @@ kerberos5/lib/libroken \ kerberos5/lib/libwind \ lib/${CSU_DIR} \ + lib/libblacklist \ lib/libbsm \ lib/libc \ lib/libcom_err \