summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/ssh/servconf.c24
-rw-r--r--usr.bin/ssh/servconf.h4
-rw-r--r--usr.bin/ssh/sshd.819
-rw-r--r--usr.bin/ssh/sshd.c34
-rw-r--r--usr.bin/ssh/sshd_config1
5 files changed, 77 insertions, 5 deletions
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 477204cfd69..6affb51e98c 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.50 2000/07/22 09:14:36 markus Exp $");
#include "ssh.h"
#include "servconf.h"
@@ -76,6 +76,8 @@ initialize_server_options(ServerOptions *options)
options->protocol = SSH_PROTO_UNKNOWN;
options->gateway_ports = -1;
options->num_subsystems = 0;
+ options->max_startups_begin = -1;
+ options->max_startups_rate = -1;
options->max_startups = -1;
}
@@ -162,6 +164,10 @@ fill_default_server_options(ServerOptions *options)
options->gateway_ports = 0;
if (options->max_startups == -1)
options->max_startups = 10;
+ if (options->max_startups_rate == -1)
+ options->max_startups_rate = 100; /* 100% */
+ if (options->max_startups_begin == -1)
+ options->max_startups_begin = options->max_startups;
}
/* Keyword tokens. */
@@ -644,6 +650,22 @@ parse_flag:
break;
case sMaxStartups:
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: Missing MaxStartups spec.",
+ filename, linenum);
+ if (sscanf(arg, "%d:%d:%d",
+ &options->max_startups_begin,
+ &options->max_startups_rate,
+ &options->max_startups) == 3) {
+ if (options->max_startups_begin >
+ options->max_startups ||
+ options->max_startups_rate > 100 ||
+ options->max_startups_rate < 1)
+ fatal("%s line %d: Illegal MaxStartups spec.",
+ filename, linenum);
+ break;
+ }
intptr = &options->max_startups;
goto parse_int;
diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h
index 95593722dd9..3b65c6a6f26 100644
--- a/usr.bin/ssh/servconf.h
+++ b/usr.bin/ssh/servconf.h
@@ -13,7 +13,7 @@
*
*/
-/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */
+/* RCSID("$OpenBSD: servconf.h,v 1.27 2000/07/22 09:14:36 markus Exp $"); */
#ifndef SERVCONF_H
#define SERVCONF_H
@@ -100,6 +100,8 @@ typedef struct {
char *subsystem_name[MAX_SUBSYSTEMS];
char *subsystem_command[MAX_SUBSYSTEMS];
+ int max_startups_begin;
+ int max_startups_rate;
int max_startups;
} ServerOptions;
diff --git a/usr.bin/ssh/sshd.8 b/usr.bin/ssh/sshd.8
index 1eb73e4c7a2..052d20275fc 100644
--- a/usr.bin/ssh/sshd.8
+++ b/usr.bin/ssh/sshd.8
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: sshd.8,v 1.56 2000/07/06 04:06:56 aaron Exp $
+.\" $Id: sshd.8,v 1.57 2000/07/22 09:14:36 markus Exp $
.\"
.Dd September 25, 1999
.Dt SSHD 8
@@ -443,6 +443,23 @@ Additional connections will be dropped until authentication succeeds or the
.Cm LoginGraceTime
expires for a connection.
The default is 10.
+.Pp
+Alternatively, random early drop can be enabled by specifying
+the three colon separated values
+.Dq start:rate:full
+(e.g. "10:30:60").
+.Nm
+will refuse connection attempts with a probabillity of
+.Dq rate/100
+(30%)
+if there are currently
+.Dq start
+(10)
+unauthenticated connections.
+The probabillity increases linearly and all connection attempts
+are refused if the number of unauthenticated connections reaches
+.Dq full
+(60).
.It Cm PasswordAuthentication
Specifies whether password authentication is allowed.
The default is
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 66e821f2835..d8d6879e2ec 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -14,7 +14,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.123 2000/07/18 01:25:01 djm Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.124 2000/07/22 09:14:37 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -395,6 +395,35 @@ destroy_sensitive_data(void)
key_free(sensitive_data.dsa_host_key);
}
+/*
+ * returns 1 if connection should be dropped, 0 otherwise.
+ * dropping starts at connection #max_startups_begin with a probability
+ * of (max_startups_rate/100). the probability increases linearly until
+ * all connections are dropped for startups > max_startups
+ */
+int
+drop_connection(int startups)
+{
+ double p, r;
+
+ if (startups < options.max_startups_begin)
+ return 0;
+ if (startups >= options.max_startups)
+ return 1;
+ if (options.max_startups_rate == 100)
+ return 1;
+
+ p = 100 - options.max_startups_rate;
+ p *= startups - options.max_startups_begin;
+ p /= (double) (options.max_startups - options.max_startups_begin);
+ p += options.max_startups_rate;
+ p /= 100.0;
+ r = arc4random() / (double) UINT_MAX;
+
+ debug("drop_connection: p %g, r %g", p, r);
+ return (r < p) ? 1 : 0;
+}
+
int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */
int startup_pipe; /* in child */
@@ -814,7 +843,8 @@ main(int ac, char **av)
error("newsock del O_NONBLOCK: %s", strerror(errno));
continue;
}
- if (startups >= options.max_startups) {
+ if (drop_connection(startups) == 1) {
+ debug("drop connection #%d", startups);
close(newsock);
continue;
}
diff --git a/usr.bin/ssh/sshd_config b/usr.bin/ssh/sshd_config
index a0930a50e42..0faff9c50b9 100644
--- a/usr.bin/ssh/sshd_config
+++ b/usr.bin/ssh/sshd_config
@@ -51,3 +51,4 @@ PermitEmptyPasswords no
#UseLogin no
#Subsystem sftp /usr/local/sbin/sftpd
+#MaxStartup 10:30:60