summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sshd.c
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2000-06-26 05:44:23 +0000
committergreen <green@FreeBSD.org>2000-06-26 05:44:23 +0000
commit9bccae4f2e267ca62056b16d55b797317a3060a6 (patch)
treee7fa8720c8c45d3a71b8303040261663e3c13769 /crypto/openssh/sshd.c
parent1f6b02c5a30aeb0ad40e2c490bd13805890ab99c (diff)
downloadFreeBSD-src-9bccae4f2e267ca62056b16d55b797317a3060a6.zip
FreeBSD-src-9bccae4f2e267ca62056b16d55b797317a3060a6.tar.gz
Make rate limiting work per-listening-socket. Log better messages than
before for this, requiring a new function (get_ipaddr()). canohost.c receives a $FreeBSD$ line. Suggested by: Niels Provos <niels@OpenBSD.org>
Diffstat (limited to 'crypto/openssh/sshd.c')
-rw-r--r--crypto/openssh/sshd.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 2fcca59..0821b75 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -143,17 +143,17 @@ unsigned char *session_id2 = NULL;
int session_id2_len = 0;
/* These are used to implement connections_per_period. */
-struct magic_connection {
+struct ratelim_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;
+} *ratelim_connections;
-static __inline int
-magic_hash(struct sockaddr *sa) {
-
- return 0;
+static void
+ratelim_init(void) {
+ ratelim_connections = calloc(num_listen_socks,
+ sizeof(struct ratelim_connection));
+ if (ratelim_connections == NULL)
+ fatal("calloc: %s", strerror(errno));
}
static __inline struct timeval
@@ -440,6 +440,7 @@ main(int ac, char **av)
int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1;
pid_t pid;
socklen_t fromlen;
+ int ratelim_exceeded = 0;
int silent = 0;
fd_set *fdset;
struct sockaddr_storage from;
@@ -450,7 +451,6 @@ main(int ac, char **av)
struct addrinfo *ai;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
int listen_sock, maxfd;
- int connections_per_period_exceeded = 0;
/* Save argv[0]. */
saved_argv = av;
@@ -786,11 +786,7 @@ main(int ac, char **av)
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));
+ ratelim_init();
/*
* Stay listening for connections until the system crashes or
@@ -825,22 +821,23 @@ main(int ac, char **av)
}
if (options.connections_per_period != 0) {
struct timeval diff, connections_end;
- struct magic_connection *mc;
+ struct ratelim_connection *rc;
(void)gettimeofday(&connections_end, NULL);
- mc = &magic_connections[magic_hash((struct sockaddr *)0)];
- diff = timevaldiff(&mc->connections_begin, &connections_end);
+ rc = &ratelim_connections[i];
+ diff = timevaldiff(&rc->connections_begin,
+ &connections_end);
if (diff.tv_sec >= options.connections_period) {
/*
- * Slide the window forward only after completely
- * leaving it.
+ * Slide the window forward only after
+ * completely leaving it.
*/
- mc->connections_begin = connections_end;
- mc->connections_this_period = 1;
+ rc->connections_begin = connections_end;
+ rc->connections_this_period = 1;
} else {
- if (++mc->connections_this_period >
+ if (++rc->connections_this_period >
options.connections_per_period)
- connections_per_period_exceeded = 1;
+ ratelim_exceeded = 1;
}
}
@@ -861,12 +858,18 @@ main(int ac, char **av)
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 if (ratelim_exceeded) {
+ const char *myaddr;
+
+ myaddr = get_ipaddr(newsock);
+ log("rate limit (%u/%u) on %s port %d "
+ "exceeded by %s",
+ options.connections_per_period,
+ options.connections_period, myaddr,
+ get_sock_port(newsock, 1), ntop);
+ free((void *)myaddr);
+ ratelim_exceeded = 0;
+ continue;
} else {
/*
* Normal production daemon. Fork, and have
OpenPOWER on IntegriCloud