- (djm) OpenBSD CVS changes:
- markus@cvs.openbsd.org 2000/07/22 03:14:37
[servconf.c servconf.h sshd.8 sshd.c sshd_config]
random early drop; ok theo, niels
- deraadt@cvs.openbsd.org 2000/07/26 11:46:51
[ssh.1]
typo
- deraadt@cvs.openbsd.org 2000/08/01 11:46:11
[sshd.8]
many fixes from pepper@mail.reppep.com
- provos@cvs.openbsd.org 2000/08/01 13:01:42
[Makefile.in util.c aux.c]
rename aux.c to util.c to help with cygwin port
- deraadt@cvs.openbsd.org 2000/08/02 00:23:31
[authfd.c]
correct sun_len; Alexander@Leidinger.net
- provos@cvs.openbsd.org 2000/08/02 10:27:17
[readconf.c sshd.8]
disable kerberos authentication by default
- provos@cvs.openbsd.org 2000/08/02 11:27:05
[sshd.8 readconf.c auth-krb4.c]
disallow kerberos authentication if we can't verify the TGT; from
dugsong@
kerberos authentication is on by default only if you have a srvtab.
- markus@cvs.openbsd.org 2000/08/04 14:30:07
[auth.c]
unused
- markus@cvs.openbsd.org 2000/08/04 14:30:35
[sshd_config]
MaxStartups
- markus@cvs.openbsd.org 2000/08/15 13:20:46
[authfd.c]
cleanup; ok niels@
- markus@cvs.openbsd.org 2000/08/17 14:05:10
[session.c]
cleanup login(1)-like jobs, no duplicate utmp entries
- markus@cvs.openbsd.org 2000/08/17 14:06:34
[session.c sshd.8 sshd.c]
sshd -u len, similar to telnetd
diff --git a/sshd.c b/sshd.c
index b6db074..ae02f2c 100644
--- a/sshd.c
+++ b/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.125 2000/08/17 20:06:34 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -139,6 +139,9 @@
unsigned char *session_id2 = NULL;
int session_id2_len = 0;
+/* record remote hostname or ip */
+unsigned int utmp_len = MAXHOSTNAMELEN;
+
/* Prototypes for various functions defined later in this file. */
void do_ssh1_kex();
void do_ssh2_kex();
@@ -400,6 +403,35 @@
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 */
@@ -441,7 +473,7 @@
initialize_server_options(&options);
/* Parse command-line arguments. */
- while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) {
+ while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:diqQ46")) != EOF) {
switch (opt) {
case '4':
IPv4or6 = AF_INET;
@@ -488,6 +520,9 @@
/* only makes sense with inetd_flag, i.e. no listen() */
inetd_flag = 1;
break;
+ case 'u':
+ utmp_len = atoi(optarg);
+ break;
case '?':
default:
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
@@ -503,6 +538,7 @@
fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
HOST_KEY_FILE);
+ fprintf(stderr, " -u len Maximum hostname length for utmp recording\n");
fprintf(stderr, " -4 Use IPv4 only\n");
fprintf(stderr, " -6 Use IPv6 only\n");
exit(1);
@@ -823,7 +859,8 @@
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;
}