diff options
Diffstat (limited to 'security/openssh/files/patch-an')
-rw-r--r-- | security/openssh/files/patch-an | 101 |
1 files changed, 0 insertions, 101 deletions
diff --git a/security/openssh/files/patch-an b/security/openssh/files/patch-an index 47a60fb490e0..b26ba76bfa14 100644 --- a/security/openssh/files/patch-an +++ b/security/openssh/files/patch-an @@ -14,104 +14,3 @@ #ifndef O_NOCTTY #define O_NOCTTY 0 #endif -@@ -134,6 +141,32 @@ - unsigned char *session_id2 = NULL; - int session_id2_len = 0; - -+/* These are used to implement connections_per_period. */ -+struct magic_connection { -+ struct timeval connections_begin; -+ unsigned int connections_this_period; -+} *magic_connections; -+/* Magic number, too! TODO: this doesn't have to be static. */ -+const size_t MAGIC_CONNECTIONS_SIZE = 1; -+ -+static __inline int -+magic_hash(struct sockaddr_storage *sa) { -+ -+ return 0; -+} -+ -+static __inline struct timeval -+timevaldiff(struct timeval *tv1, struct timeval *tv2) { -+ struct timeval diff; -+ int carry; -+ -+ carry = tv1->tv_usec > tv2->tv_usec; -+ diff.tv_sec = tv2->tv_sec - tv1->tv_sec - (carry ? 0 : 1); -+ diff.tv_usec = tv2->tv_usec - tv1->tv_usec + (carry ? 1000000 : 0); -+ -+ return diff; -+} -+ - /* Prototypes for various functions defined later in this file. */ - void do_ssh1_kex(); - void do_ssh2_kex(); -@@ -418,6 +451,7 @@ - int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1; - pid_t pid; - socklen_t fromlen; -+ int connections_per_period_exceeded = 0; - int silent = 0; - fd_set *fdset; - struct sockaddr_storage from; -@@ -763,6 +797,12 @@ - fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - -+ /* Initialize the magic_connections table. It's magical! */ -+ magic_connections = calloc(MAGIC_CONNECTIONS_SIZE, -+ sizeof(struct magic_connection)); -+ if (magic_connections == NULL) -+ fatal("calloc: %s", strerror(errno)); -+ - /* - * Stay listening for connections until the system crashes or - * the daemon is killed with a signal. -@@ -794,9 +834,31 @@ - error("newsock del O_NONBLOCK: %s", strerror(errno)); - continue; - } -+ if (options.connections_per_period != 0) { -+ struct timeval diff, connections_end; -+ struct magic_connection *mc; -+ -+ (void)gettimeofday(&connections_end, NULL); -+ mc = &magic_connections[magic_hash(&from)]; -+ diff = timevaldiff(&mc->connections_begin, &connections_end); -+ if (diff.tv_sec >= options.connections_period) { -+ /* -+ * Slide the window forward only after completely -+ * leaving it. -+ */ -+ mc->connections_begin = connections_end; -+ mc->connections_this_period = 1; -+ } else { -+ if (++mc->connections_this_period > -+ options.connections_per_period) -+ connections_per_period_exceeded = 1; -+ } -+ } -+ - /* -- * Got connection. Fork a child to handle it, unless -- * we are in debugging mode. -+ * Got connection. Fork a child to handle it unless -+ * we are in debugging mode or the maximum number of -+ * connections per period has been exceeded. - */ - if (debug_flag) { - /* -@@ -810,6 +872,12 @@ - sock_out = newsock; - pid = getpid(); - break; -+ } else if (connections_per_period_exceeded) { -+ log("Connection rate limit of %u/%us has been exceeded; " -+ "dropping connection from %s.", -+ options.connections_per_period, options.connections_period, -+ ntop); -+ connections_per_period_exceeded = 0; - } else { - /* - * Normal production daemon. Fork, and have |