]> andersk Git - openssh.git/blobdiff - sshd.c
- (djm) OpenBSD CVS changes:
[openssh.git] / sshd.c
diff --git a/sshd.c b/sshd.c
index b6db074c8c61a30d96eafb8391e9bdc1d8515249..ae02f2c401629cc72fe2123dc985176fe80ff880 100644 (file)
--- 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_id[16];
 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 @@ 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 */
 
@@ -441,7 +473,7 @@ main(int ac, char **av)
        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 @@ main(int ac, char **av)
                        /* 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 @@ main(int ac, char **av)
                        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 @@ 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;
                                }
This page took 0.044689 seconds and 4 git commands to generate.