810702f666
Reported by: Chad J. Milios
429 lines
14 KiB
Plaintext
429 lines
14 KiB
Plaintext
--- blacklist.c.orig 2021-04-28 13:37:52.679784000 -0700
|
|
+++ blacklist.c 2021-04-28 13:56:45.677805000 -0700
|
|
@@ -0,0 +1,92 @@
|
|
+/*-
|
|
+ * 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 <ctype.h>
|
|
+#include <stdarg.h>
|
|
+#include <stdbool.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <syslog.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include "ssh.h"
|
|
+#include "packet.h"
|
|
+#include "log.h"
|
|
+#include "misc.h"
|
|
+#include <blacklist.h>
|
|
+#include "blacklist_client.h"
|
|
+
|
|
+static struct blacklist *blstate = NULL;
|
|
+
|
|
+/* internal definition from bl.h */
|
|
+struct blacklist *bl_create(bool, char *, void (*)(int, const char *, va_list));
|
|
+
|
|
+/* impedence match vsyslog() to sshd's internal logging levels */
|
|
+void
|
|
+im_log(int priority, const char *message, va_list args)
|
|
+{
|
|
+ LogLevel imlevel;
|
|
+
|
|
+ switch (priority) {
|
|
+ case LOG_ERR:
|
|
+ imlevel = SYSLOG_LEVEL_ERROR;
|
|
+ break;
|
|
+ case LOG_DEBUG:
|
|
+ imlevel = SYSLOG_LEVEL_DEBUG1;
|
|
+ break;
|
|
+ case LOG_INFO:
|
|
+ imlevel = SYSLOG_LEVEL_INFO;
|
|
+ break;
|
|
+ default:
|
|
+ imlevel = SYSLOG_LEVEL_DEBUG2;
|
|
+ }
|
|
+ do_log2(imlevel, message, args);
|
|
+}
|
|
+
|
|
+void
|
|
+blacklist_init(void)
|
|
+{
|
|
+
|
|
+ blstate = bl_create(false, NULL, im_log);
|
|
+}
|
|
+
|
|
+void
|
|
+blacklist_notify(int action, struct ssh *ssh, const char *msg)
|
|
+{
|
|
+
|
|
+ if (blstate != NULL && ssh_packet_connection_is_on_socket(ssh))
|
|
+ (void)blacklist_r(blstate, action,
|
|
+ ssh_packet_get_connection_in(ssh), msg);
|
|
+}
|
|
--- blacklist_client.h.orig 2020-11-16 16:45:22.823087000 -0800
|
|
+++ blacklist_client.h 2020-11-16 16:45:09.761962000 -0800
|
|
@@ -0,0 +1,61 @@
|
|
+/*-
|
|
+ * 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.
|
|
+ */
|
|
+
|
|
+#ifndef BLACKLIST_CLIENT_H
|
|
+#define BLACKLIST_CLIENT_H
|
|
+
|
|
+#ifndef BLACKLIST_API_ENUM
|
|
+enum {
|
|
+ BLACKLIST_AUTH_OK = 0,
|
|
+ BLACKLIST_AUTH_FAIL,
|
|
+ BLACKLIST_ABUSIVE_BEHAVIOR,
|
|
+ BLACKLIST_BAD_USER
|
|
+};
|
|
+#endif
|
|
+
|
|
+#ifdef USE_BLACKLIST
|
|
+void blacklist_init(void);
|
|
+void blacklist_notify(int, struct ssh *, const char *);
|
|
+
|
|
+#define BLACKLIST_INIT() blacklist_init()
|
|
+#define BLACKLIST_NOTIFY(x, ssh, msg) blacklist_notify(x, ssh, msg)
|
|
+
|
|
+#else
|
|
+
|
|
+#define BLACKLIST_INIT()
|
|
+#define BLACKLIST_NOTIFY(x, ssh, msg)
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+#endif /* BLACKLIST_CLIENT_H */
|
|
--- servconf.c.orig 2021-04-15 20:55:25.000000000 -0700
|
|
+++ servconf.c 2021-04-28 13:36:19.591999000 -0700
|
|
@@ -172,6 +172,7 @@ initialize_server_options(ServerOptions *options)
|
|
options->max_sessions = -1;
|
|
options->banner = NULL;
|
|
options->use_dns = -1;
|
|
+ options->use_blacklist = -1;
|
|
options->client_alive_interval = -1;
|
|
options->client_alive_count_max = -1;
|
|
options->num_authkeys_files = 0;
|
|
@@ -410,6 +411,8 @@ fill_default_server_options(ServerOptions *options)
|
|
options->max_sessions = DEFAULT_SESSIONS_MAX;
|
|
if (options->use_dns == -1)
|
|
options->use_dns = 0;
|
|
+ if (options->use_blacklist == -1)
|
|
+ options->use_blacklist = 0;
|
|
if (options->client_alive_interval == -1)
|
|
options->client_alive_interval = 0;
|
|
if (options->client_alive_count_max == -1)
|
|
@@ -506,6 +509,7 @@ typedef enum {
|
|
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
|
|
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
|
|
sBanner, sUseDNS, sHostbasedAuthentication,
|
|
+ sUseBlacklist,
|
|
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
|
|
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
|
|
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
|
@@ -642,6 +646,8 @@ static struct {
|
|
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
|
|
{ "banner", sBanner, SSHCFG_ALL },
|
|
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
|
|
+ { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
|
|
+ { "useblocklist", sUseBlacklist, SSHCFG_GLOBAL } /* alias */,
|
|
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
|
|
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
|
|
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
|
|
@@ -1692,6 +1698,10 @@ process_server_config_line_depth(ServerOptions *option
|
|
intptr = &options->use_dns;
|
|
goto parse_flag;
|
|
|
|
+ case sUseBlacklist:
|
|
+ intptr = &options->use_blacklist;
|
|
+ goto parse_flag;
|
|
+
|
|
case sLogFacility:
|
|
log_facility_ptr = &options->log_facility;
|
|
arg = strdelim(&cp);
|
|
@@ -2872,6 +2882,7 @@ dump_config(ServerOptions *o)
|
|
dump_cfg_fmtint(sCompression, o->compression);
|
|
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
|
|
dump_cfg_fmtint(sUseDNS, o->use_dns);
|
|
+ dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
|
|
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
|
|
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
|
|
dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
|
|
--- servconf.h.orig 2020-11-16 15:51:00.752090000 -0800
|
|
+++ servconf.h 2020-11-16 15:51:02.962173000 -0800
|
|
@@ -179,6 +179,7 @@ typedef struct {
|
|
int max_sessions;
|
|
char *banner; /* SSH-2 banner message */
|
|
int use_dns;
|
|
+ int use_blacklist;
|
|
int client_alive_interval; /*
|
|
* poke the client this often to
|
|
* see if it's still there
|
|
--- auth-pam.c.orig 2020-11-16 15:52:45.816578000 -0800
|
|
+++ auth-pam.c 2020-11-16 15:54:19.796583000 -0800
|
|
@@ -105,6 +105,7 @@ extern char *__progname;
|
|
#include "ssh-gss.h"
|
|
#endif
|
|
#include "monitor_wrap.h"
|
|
+#include "blacklist_client.h"
|
|
|
|
extern ServerOptions options;
|
|
extern struct sshbuf *loginmsg;
|
|
@@ -916,6 +917,10 @@ sshpam_query(void *ctx, char **name, char **info,
|
|
sshbuf_free(buffer);
|
|
return (0);
|
|
}
|
|
+ /* XXX: ssh context unavailable here, unclear if this is even needed.
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_BAD_USER,
|
|
+ the_active_state, sshpam_authctxt->user);
|
|
+ */
|
|
error("PAM: %s for %s%.100s from %.100s", msg,
|
|
sshpam_authctxt->valid ? "" : "illegal user ",
|
|
sshpam_authctxt->user, sshpam_rhost);
|
|
--- auth.c.orig 2020-11-16 15:52:45.824171000 -0800
|
|
+++ auth.c 2020-11-16 15:57:51.091969000 -0800
|
|
@@ -76,6 +76,7 @@
|
|
#include "ssherr.h"
|
|
#include "compat.h"
|
|
#include "channels.h"
|
|
+#include "blacklist_client.h"
|
|
|
|
/* import */
|
|
extern ServerOptions options;
|
|
@@ -331,8 +332,11 @@ auth_log(struct ssh *ssh, int authenticated, int parti
|
|
authmsg = "Postponed";
|
|
else if (partial)
|
|
authmsg = "Partial";
|
|
- else
|
|
+ else {
|
|
authmsg = authenticated ? "Accepted" : "Failed";
|
|
+ if (authenticated)
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, ssh, "ssh");
|
|
+ }
|
|
|
|
if ((extra = format_method_key(authctxt)) == NULL) {
|
|
if (authctxt->auth_method_info != NULL)
|
|
@@ -586,6 +590,7 @@ getpwnamallow(struct ssh *ssh, const char *user)
|
|
aix_restoreauthdb();
|
|
#endif
|
|
if (pw == NULL) {
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, ssh, user);
|
|
logit("Invalid user %.100s from %.100s port %d",
|
|
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
|
#ifdef CUSTOM_FAILED_LOGIN
|
|
--- auth2.c.orig 2020-11-16 17:10:36.772062000 -0800
|
|
+++ auth2.c 2020-11-16 17:12:04.852943000 -0800
|
|
@@ -58,6 +58,7 @@
|
|
#endif
|
|
#include "monitor_wrap.h"
|
|
#include "digest.h"
|
|
+#include "blacklist_client.h"
|
|
|
|
/* import */
|
|
extern ServerOptions options;
|
|
@@ -295,6 +296,7 @@ input_userauth_request(int type, u_int32_t seq, struct
|
|
} else {
|
|
/* Invalid user, fake password information */
|
|
authctxt->pw = fakepw();
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, ssh, "ssh");
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
|
|
#endif
|
|
@@ -448,8 +450,10 @@ userauth_finish(struct ssh *ssh, int authenticated, co
|
|
} else {
|
|
/* 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, "ssh");
|
|
+ }
|
|
if (authctxt->failures >= options.max_authtries) {
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES));
|
|
--- packet.c.orig 2020-11-16 15:52:45.839070000 -0800
|
|
+++ packet.c 2020-11-16 15:56:09.285418000 -0800
|
|
@@ -96,6 +96,7 @@
|
|
#include "packet.h"
|
|
#include "ssherr.h"
|
|
#include "sshbuf.h"
|
|
+#include "blacklist_client.h"
|
|
|
|
#ifdef PACKET_DEBUG
|
|
#define DBG(x) x
|
|
@@ -1882,6 +1883,7 @@ sshpkt_vfatal(struct ssh *ssh, int r, const char *fmt,
|
|
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, ssh, "ssh");
|
|
ssh_packet_clear_keys(ssh);
|
|
errno = oerrno;
|
|
logdie("Unable to negotiate with %s: %s. "
|
|
--- sshd.c.orig 2021-08-19 21:03:49.000000000 -0700
|
|
+++ sshd.c 2021-09-10 10:37:17.926747000 -0700
|
|
@@ -123,6 +123,7 @@
|
|
#include "version.h"
|
|
#include "ssherr.h"
|
|
#include "sk-api.h"
|
|
+#include "blacklist_client.h"
|
|
#include "srclimit.h"
|
|
#include "dh.h"
|
|
|
|
@@ -366,6 +367,8 @@ grace_alarm_handler(int sig)
|
|
kill(0, SIGTERM);
|
|
}
|
|
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, the_active_state, "ssh");
|
|
+
|
|
/* Log error and exit. */
|
|
if (use_privsep && pmonitor != NULL && pmonitor->m_pid <= 0)
|
|
cleanup_exit(255); /* don't log in privsep child */
|
|
@@ -2225,6 +2228,9 @@ main(int ac, char **av)
|
|
if ((loginmsg = sshbuf_new()) == NULL)
|
|
fatal_f("sshbuf_new failed");
|
|
auth_debug_reset();
|
|
+
|
|
+ if (options.use_blacklist)
|
|
+ BLACKLIST_INIT();
|
|
|
|
if (use_privsep) {
|
|
if (privsep_preauth(ssh) == 1)
|
|
--- Makefile.in.orig 2022-10-03 07:51:42.000000000 -0700
|
|
+++ Makefile.in 2022-10-09 10:50:06.401377000 -0700
|
|
@@ -185,6 +185,8 @@ FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(S
|
|
FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
|
|
@UNSUPPORTED_ALGORITHMS@
|
|
|
|
+LIBSSH_OBJS+= blacklist.o
|
|
+
|
|
all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
|
|
|
|
$(LIBSSH_OBJS): Makefile.in config.h
|
|
--- sshd_config.orig 2020-11-16 16:57:14.276036000 -0800
|
|
+++ sshd_config 2020-11-16 16:57:42.183846000 -0800
|
|
@@ -94,6 +94,7 @@
|
|
#PrintLastLog yes
|
|
#TCPKeepAlive yes
|
|
#PermitUserEnvironment no
|
|
+#UseBlacklist no
|
|
#Compression delayed
|
|
#ClientAliveInterval 0
|
|
#ClientAliveCountMax 3
|
|
--- sshd_config.5.orig 2020-11-16 16:57:58.533307000 -0800
|
|
+++ sshd_config.5 2020-11-16 17:00:02.635070000 -0800
|
|
@@ -1703,6 +1703,20 @@ for authentication using
|
|
.Cm TrustedUserCAKeys .
|
|
For more details on certificates, see the CERTIFICATES section in
|
|
.Xr ssh-keygen 1 .
|
|
+.It Cm UseBlacklist
|
|
+Specifies whether
|
|
+.Xr sshd 8
|
|
+attempts to send authentication success and failure messages
|
|
+to the
|
|
+.Xr blacklistd 8
|
|
+daemon.
|
|
+The default is
|
|
+.Cm no .
|
|
+For forward compatibility with an upcoming
|
|
+.Xr blacklistd
|
|
+rename, the
|
|
+.Cm UseBlocklist
|
|
+alias can be used instead.
|
|
.It Cm UseDNS
|
|
Specifies whether
|
|
.Xr sshd 8
|
|
--- monitor.c.orig 2020-11-16 17:24:03.457283000 -0800
|
|
+++ monitor.c 2020-11-16 17:25:57.642510000 -0800
|
|
@@ -96,6 +96,7 @@
|
|
#include "match.h"
|
|
#include "ssherr.h"
|
|
#include "sk-api.h"
|
|
+#include "blacklist_client.h"
|
|
|
|
#ifdef GSSAPI
|
|
static Gssctxt *gsscontext = NULL;
|
|
@@ -342,8 +343,11 @@ monitor_child_preauth(struct ssh *ssh, struct monitor
|
|
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
|
|
auth_log(ssh, authenticated, partial,
|
|
auth_method, auth_submethod);
|
|
- if (!partial && !authenticated)
|
|
+ if (!partial && !authenticated) {
|
|
authctxt->failures++;
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL,
|
|
+ ssh, "ssh");
|
|
+ }
|
|
if (authenticated || partial) {
|
|
auth2_update_session_info(authctxt,
|
|
auth_method, auth_submethod);
|
|
@@ -1228,6 +1232,7 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct
|
|
} else {
|
|
/* Log failed attempt */
|
|
auth_log(ssh, 0, 0, auth_method, NULL);
|
|
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, ssh, "ssh");
|
|
free(cuser);
|
|
free(chost);
|
|
}
|