summaryrefslogtreecommitdiffstats
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/sshd.c b/sshd.c
index 7e008730..1333ef5e 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.566 2020/12/29 00:59:15 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.567 2021/01/09 12:10:02 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -123,6 +123,7 @@
#include "version.h"
#include "ssherr.h"
#include "sk-api.h"
+#include "srclimit.h"
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
@@ -853,7 +854,7 @@ should_drop_connection(int startups)
* while in that state.
*/
static int
-drop_connection(int sock, int startups)
+drop_connection(int sock, int startups, int notify_pipe)
{
char *laddr, *raddr;
const char msg[] = "Exceeded MaxStartups\r\n";
@@ -863,7 +864,8 @@ drop_connection(int sock, int startups)
time_t now;
now = monotime();
- if (!should_drop_connection(startups)) {
+ if (!should_drop_connection(startups) &&
+ srclimit_check_allow(sock, notify_pipe) == 1) {
if (last_drop != 0 &&
startups < options.max_startups_begin - 1) {
/* XXX maybe need better hysteresis here */
@@ -1109,6 +1111,10 @@ server_listen(void)
{
u_int i;
+ /* Initialise per-source limit tracking. */
+ srclimit_init(options.max_startups, options.per_source_max_startups,
+ options.per_source_masklen_ipv4, options.per_source_masklen_ipv6);
+
for (i = 0; i < options.num_listen_addrs; i++) {
listen_on_addrs(&options.listen_addrs[i]);
freeaddrinfo(options.listen_addrs[i].addrs);
@@ -1215,6 +1221,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
case 0:
/* child exited or completed auth */
close(startup_pipes[i]);
+ srclimit_done(startup_pipes[i]);
startup_pipes[i] = -1;
startups--;
if (startup_flags[i])
@@ -1245,9 +1252,12 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
continue;
}
if (unset_nonblock(*newsock) == -1 ||
- drop_connection(*newsock, startups) ||
- pipe(startup_p) == -1) {
+ pipe(startup_p) == -1)
+ continue;
+ if (drop_connection(*newsock, startups, startup_p[0])) {
close(*newsock);
+ close(startup_p[0]);
+ close(startup_p[1]);
continue;
}