diff -Nru ORIGINAL-3.8.1p1/Makefile.in openssh-3.8.1p1-alptpatch/Makefile.in --- ORIGINAL-3.8.1p1/Makefile.in 2004-02-18 04:35:11.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/Makefile.in 2004-09-05 19:51:11.000000000 +0200 @@ -77,6 +77,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sshpty.o sshlogin.o servconf.o serverloop.o uidswap.o \ + inet.o accept.o \ auth.o auth1.o auth2.o auth-options.o session.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ diff -Nru ORIGINAL-3.8.1p1/accept.c openssh-3.8.1p1-alptpatch/accept.c --- ORIGINAL-3.8.1p1/accept.c 1970-01-01 01:00:00.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/accept.c 2004-09-07 15:52:03.941042280 +0200 @@ -0,0 +1,231 @@ +/* This file is part of Netsukuku + * (c) Copyright 2004 Andrea Lo Pumo aka AlpT + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /* accept.c: This is how it works: + * When a new accept is made add_accept is called. It first updates the accept + * table and then, if the accept_tbl isn't full add the new accept in the tbl. + * If the accept_tbl is full the connection is dropped. + * Each accept in the table last for free_accept_time after the close of that + * connection, so if an host has fulled the accept_tbl has to wait + * free_accept_time of seconds to be able reconnect again. + */ + +#include +#include +#include +#include +#include + +#include "accept.h" +#include "xmalloc.h" +#include "log.h" + + +void init_accept_tbl(int startups, int accepts, int time) +{ + int i; + + max_connections=startups; + max_accepts_per_host=accepts; + free_accept_time=time; + accept_idx=accept_sidx=0; + + accept_tbl=(struct accept_table *)xmalloc(sizeof(struct accept_table)*max_connections); + memset(accept_tbl, '\0', sizeof(struct accept_table)*max_connections); + + for(i=0; i max_accepts_per_host) + return -1; + + *index=idx; + return 0; +} + +int find_free_acp_t(int idx) +{ + int e; + + for(e=0; e < max_accepts_per_host; e++) { + if(!accept_tbl[idx].acp_t[e]) + return e; + } + + return -1; /*This happens if the rq_tbl is full for the "rq" request*/ +} + +int add_accept(inet_prefix ip) +{ + int err, idx, cl; + time_t cur_t; + + if((err=is_ip_acpt_free(ip, &idx))) + return err; + + time(&cur_t); + + if((cl=find_free_acp_t(idx))==-1) + return -1; + accept_tbl[idx].accepts++; + accept_tbl[idx].acp_t[cl]=cur_t; + accept_tbl[idx].closed[cl]=0; + memcpy(&accept_tbl[idx].ip, &ip, sizeof(inet_prefix)); + + /*This global var will be given to the thread*/ + accept_idx=idx; + accept_sidx=cl; + + return 0; +} + +void del_accept(int idx) +{ + if(!accept_tbl[idx].accepts) + return; + + if(accept_tbl[idx].acp_t[accept_sidx]) { + accept_tbl[idx].accepts--; + accept_tbl[idx].acp_t[accept_sidx]=0; + accept_tbl[idx].closed[accept_sidx]=0; + if(!accept_tbl[idx].accepts) + memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix)); + accept_sidx--; + } +} + +int close_accept(void) +{ + if(!accept_tbl[accept_idx].accepts) + return -1; + + accept_tbl[accept_idx].closed[accept_sidx]=0; + + update_accept_tbl(); + + return 0; +} + +void add_accept_pid(pid_t pid) +{ + accept_tbl[accept_idx].pid[accept_sidx]=pid; + debug("ACPT: Added pig %d in accept_tbl[%d].pid[%d]", accept_tbl[accept_idx].pid[accept_sidx], accept_idx, accept_sidx); +} diff -Nru ORIGINAL-3.8.1p1/accept.h openssh-3.8.1p1-alptpatch/accept.h --- ORIGINAL-3.8.1p1/accept.h 1970-01-01 01:00:00.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/accept.h 2004-09-07 15:52:25.986690832 +0200 @@ -0,0 +1,73 @@ +/* This file is part of Netsukuku + * (c) Copyright 2004 Andrea Lo Pumo aka AlpT + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "inet.h" + +#define MAX_CONNECTIONS 500 +#define MAX_ACCEPTS 50 +#define FREE_ACCEPT_TIME 5 /*in seconds*/ + +/*This struct keep tracks of single connection to the server. + * The thread_daemon who handle the connection knows the connection + * position in the accept_tbl + */ +struct accept_table +{ + inet_prefix ip; /*Ip of the node connected*/ + unsigned char accepts; /*Number of connection from this node*/ + pid_t *pid; /*The pid of each child that have accepted the conn*/ + unsigned char *closed; /*Each element of this array is 1 or 0. It indicates if the connection has + been closed*/ + time_t *acp_t; /*The time when the connection was accepted. The "accepts" counter + will decrement when one of the acp_t+FREE_ACCEPT_TIME will + be <= current_time AND (the relative pid will be non existent OR + the relative closed element will be == 1) + */ +}; + +/*This struct keeps all the info regarding each node connected*/ +struct accept_table *accept_tbl; + +/*accept_idx it the position of the accept_tbl of a thread. + *accept_sidx is the second index, it is used for example in pid[accept_sidx] + *note: this var are used only in the child and the child doesn't need to modify them! + */ +int accept_idx, accept_sidx; + +int update_accept_tbl_mutex; + +int max_connections, max_accepts_per_host, free_accept_time; + +void init_accept_tbl(int startups, int accepts, int time); +void destroy_accept_tbl(void); +void update_accept_tbl(void); +int find_ip_acpt(inet_prefix ip); +int find_first_free(void); +int is_ip_acpt_free(inet_prefix ip, int *index); +int find_free_acp_t(int idx); +int add_accept(inet_prefix ip); +void del_accept(int idx); +int close_accept(void); +void add_accept_pid(pid_t pid); diff -Nru ORIGINAL-3.8.1p1/inet.c openssh-3.8.1p1-alptpatch/inet.c --- ORIGINAL-3.8.1p1/inet.c 1970-01-01 01:00:00.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/inet.c 2004-09-07 16:05:00.921923232 +0200 @@ -0,0 +1,100 @@ +/* This file is part of Netsukuku + * (c) Copyright 2004 Andrea Lo Pumo aka AlpT + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "inet.h" +#include "xmalloc.h" + +char *inet_to_str(inet_prefix *ip) +{ + char *dst; + + if(ip->family==AF_INET) { + struct in_addr src; + + memcpy(&src, ip->data, ip->len); + dst=xmalloc(INET_ADDRSTRLEN); + inet_ntop(ip->family, &src, dst, INET_ADDRSTRLEN); + } + else if(ip->family==AF_INET6) { + struct in6_addr src; + + memcpy(&src, ip->data, ip->len); + dst=xmalloc(INET6_ADDRSTRLEN); + inet_ntop(ip->family, &src, dst, INET6_ADDRSTRLEN); + } + + return dst; +} + +int inet_to_sockaddr(inet_prefix *ip, u_short port, struct sockaddr *dst, socklen_t *dstlen) +{ + memset(dst, '\0', sizeof(struct sockaddr)); + + dst->sa_family=ip->family; + port=htons(port); + memcpy(dst->sa_data, &port, sizeof(u_short)); + + if(ip->family==AF_INET) + memcpy(dst->sa_data+sizeof(u_short), ip->data, ip->len); + else if(ip->family==AF_INET6) + memcpy(dst->sa_data+sizeof(u_short)+sizeof(u_int), ip->data, ip->len); + else + return -1; + + if(!dstlen) + return 0; + + *dstlen=ip->len; + + return 0; +} + +int sockaddr_to_inet(struct sockaddr *ip, inet_prefix *dst, u_short *port) +{ + u_short po; + + memset(dst, '\0', sizeof(inet_prefix)); + + dst->family=ip->sa_family; + memcpy(&po, &ip->sa_data, sizeof(u_short)); + if(port) + *port=ntohs(po); + + if(ip->sa_family==AF_INET) { + memcpy(dst->data, &ip->sa_data+sizeof(u_short), sizeof(struct in_addr)); + dst->data[0]=ntohl(dst->data[0]); + dst->len=sizeof(struct in_addr); + } else if(ip->sa_family==AF_INET6) { + memcpy(dst->data, &ip->sa_data+sizeof(u_short)+sizeof(int), sizeof(struct in6_addr)); + dst->len=sizeof(struct in6_addr); + } else + return -1; + + return 0; +} diff -Nru ORIGINAL-3.8.1p1/inet.h openssh-3.8.1p1-alptpatch/inet.h --- ORIGINAL-3.8.1p1/inet.h 1970-01-01 01:00:00.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/inet.h 2004-09-07 15:51:40.199651520 +0200 @@ -0,0 +1,37 @@ +/* This file is part of Netsukuku + * (c) Copyright 2004 Andrea Lo Pumo aka AlpT + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +typedef struct +{ + __u8 family; + __u16 len; + __u32 data[4]; +} inet_prefix; + +char *inet_to_str(inet_prefix *ip); +int inet_to_sockaddr(inet_prefix *ip, u_short port, struct sockaddr *dst, socklen_t *dstlen); +int sockaddr_to_inet(struct sockaddr *ip, inet_prefix *dst, u_short *port); diff -Nru ORIGINAL-3.8.1p1/log.h openssh-3.8.1p1-alptpatch/log.h --- ORIGINAL-3.8.1p1/log.h 2003-10-02 08:12:37.000000000 +0200 +++ openssh-3.8.1p1-alptpatch/log.h 2004-09-05 20:58:08.000000000 +0200 @@ -16,7 +16,7 @@ #define SSH_LOG_H #include /* Needed for LOG_AUTHPRIV (if present) */ - +#include /* Supported syslog facilities and levels. */ typedef enum { SYSLOG_FACILITY_DAEMON, diff -Nru ORIGINAL-3.8.1p1/servconf.c openssh-3.8.1p1-alptpatch/servconf.c --- ORIGINAL-3.8.1p1/servconf.c 2004-01-23 12:03:10.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/servconf.c 2004-09-07 13:17:36.658883312 +0200 @@ -23,6 +23,7 @@ #include "cipher.h" #include "kex.h" #include "mac.h" +#include "accept.h" static void add_listen_addr(ServerOptions *, char *, u_short); static void add_one_listen_addr(ServerOptions *, char *, u_short); @@ -92,9 +93,14 @@ 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_begin = -1; + *options->max_startups_rate = -1; + */ options->max_startups = -1; + options->max_connections = -1; + options->max_accepts_per_host = -1; + options->max_accepts_per_host_time = -1; options->banner = NULL; options->use_dns = -1; options->client_alive_interval = -1; @@ -206,12 +212,19 @@ options->allow_tcp_forwarding = 1; if (options->gateway_ports == -1) 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_rate == -1) + options->max_startups_rate = 100; // 100 % if (options->max_startups_begin == -1) options->max_startups_begin = options->max_startups; +*/ + if (options->max_connections == -1) + options->max_connections = MAX_CONNECTIONS; + if (options->max_accepts_per_host == -1) + options->max_accepts_per_host = 10; + if (options->max_accepts_per_host_time == -1) + options->max_accepts_per_host_time = FREE_ACCEPT_TIME; + if (options->max_startups == -1) + options->max_startups = options->max_connections*options->max_accepts_per_host; if (options->use_dns == -1) options->use_dns = 1; if (options->client_alive_interval == -1) @@ -262,8 +275,8 @@ sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, - sBanner, sUseDNS, sHostbasedAuthentication, + sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, + sMaxAcceptsPerHost, sMaxConnections, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, @@ -356,7 +369,11 @@ { "protocol", sProtocol }, { "gatewayports", sGatewayPorts }, { "subsystem", sSubsystem }, - { "maxstartups", sMaxStartups }, + /*It's useless now, because max_startups=max_connections*max_accepts_per_host + *{ "maxstartups", sMaxStartups }, + */ + { "maxconnections", sMaxConnections }, + { "maxacceptsperhost", sMaxAcceptsPerHost }, { "banner", sBanner }, { "usedns", sUseDNS }, { "verifyreversemapping", sDeprecated }, @@ -846,6 +863,7 @@ options->num_subsystems++; break; + /*It's useless now, because max_startups=max_connections*max_accepts_per_host case sMaxStartups: arg = strdelim(&cp); if (!arg || *arg == '\0') @@ -868,6 +886,36 @@ options->max_startups = options->max_startups_begin; break; + */ + case sMaxAcceptsPerHost: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing MaxAcceptsPerHost spec.", + filename, linenum); + if ((n = sscanf(arg, "%d:%d", + &options->max_accepts_per_host, + &options->max_accepts_per_host_time)) != 2 && n != 1) + fatal("%s line %d: Illegal MaxAcceptsPerHost spec.", + filename, linenum); + else if(n == 1) { + options->max_accepts_per_host_time = FREE_ACCEPT_TIME; + debug("Default sMaxAcceptsPerHost time: %d", options->max_accepts_per_host_time); + } + + if(options->max_accepts_per_host > MAX_ACCEPTS) + fatal("%s line %d: MaxAcceptsPerHost is > of MAX_ACCEPTS (%d).", + filename, linenum, MAX_ACCEPTS); + debug("sMaxAcceptsPerHost: %d", options->max_accepts_per_host); + if(options->max_accepts_per_host_time < 0) + fatal("%s line %d: MaxAcceptsPerHost time is < of 0.", + filename, linenum); + debug("sMaxAcceptsPerHost time: %d", options->max_accepts_per_host_time); + break; + + case sMaxConnections: + intptr = &options->max_connections; + goto parse_int; + case sBanner: charptr = &options->banner; goto parse_filename; diff -Nru ORIGINAL-3.8.1p1/servconf.h openssh-3.8.1p1-alptpatch/servconf.h --- ORIGINAL-3.8.1p1/servconf.h 2003-12-31 01:37:34.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/servconf.h 2004-09-07 13:23:40.303600912 +0200 @@ -107,9 +107,10 @@ char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; - int max_startups_begin; - int max_startups_rate; int max_startups; + int max_connections; + int max_accepts_per_host; + int max_accepts_per_host_time; char *banner; /* SSH-2 banner message */ int use_dns; int client_alive_interval; /* diff -Nru ORIGINAL-3.8.1p1/session.c openssh-3.8.1p1-alptpatch/session.c --- ORIGINAL-3.8.1p1/session.c 2004-04-16 14:47:55.000000000 +0200 +++ openssh-3.8.1p1-alptpatch/session.c 2004-09-06 22:10:35.000000000 +0200 @@ -57,6 +57,7 @@ #include "canohost.h" #include "session.h" #include "monitor_wrap.h" +#include "accept.h" #if defined(KRB5) && defined(USE_AFS) #include @@ -2257,4 +2258,7 @@ */ if (!use_privsep || mm_is_monitor()) session_destroy_all(session_pty_cleanup2); + + debug("ACPT: do_cleanup: Destroying the accept_tbl"); + destroy_accept_tbl(); } diff -Nru ORIGINAL-3.8.1p1/sshd.c openssh-3.8.1p1-alptpatch/sshd.c --- ORIGINAL-3.8.1p1/sshd.c 2004-03-21 23:36:01.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/sshd.c 2004-09-07 16:05:43.680422952 +0200 @@ -85,6 +85,7 @@ #include "monitor_wrap.h" #include "monitor_fdpass.h" +#include "accept.h" #ifdef LIBWRAP #include #include @@ -737,6 +738,7 @@ * of (max_startups_rate/100). the probability increases linearly until * all connections are dropped for startups > max_startups */ +/* Now it's useless, accept.c does the dirty job static int drop_connection(int startups) { @@ -759,6 +761,7 @@ debug("drop_connection: p %g, r %g", p, r); return (r < p) ? 1 : 0; } +*/ static void usage(void) @@ -785,6 +788,7 @@ socklen_t fromlen; fd_set *fdset; struct sockaddr_storage from; + struct sockaddr from_tmp; const char *remote_ip; int remote_port; FILE *f; @@ -792,6 +796,7 @@ char ntop[NI_MAXHOST], strport[NI_MAXSERV]; char *line; int listen_sock, maxfd; + inet_prefix ip; int startup_p[2]; int startups = 0; Key *key; @@ -950,6 +955,12 @@ /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); + debug("ACPT: Initializing the accept_tbl: max_startups: %d, max_connections: %d, " + "max_accepts_per_host: %d, max_accept_per_host_time: %d", + options.max_startups, options.max_connections, options.max_accepts_per_host, + options.max_accepts_per_host_time); + init_accept_tbl(options.max_connections, options.max_accepts_per_host, options.max_accepts_per_host_time); + /* Check that there are no remaining arguments. */ if (optind < ac) { fprintf(stderr, "Extra argument %s.\n", av[optind]); @@ -1278,7 +1289,7 @@ if (!FD_ISSET(listen_socks[i], fdset)) continue; fromlen = sizeof(from); - newsock = accept(listen_socks[i], (struct sockaddr *)&from, + newsock = accept(listen_socks[i], (struct sockaddr *)&from_tmp, &fromlen); if (newsock < 0) { if (errno != EINTR && errno != EWOULDBLOCK) @@ -1290,15 +1301,33 @@ close(newsock); continue; } + /*Drop connection now is useless if (drop_connection(startups) == 1) { debug("drop connection #%d", startups); close(newsock); continue; } + */ if (pipe(startup_p) == -1) { close(newsock); continue; } + + sockaddr_to_inet(&from_tmp, &ip, 0); + if(add_accept(ip)) { + char *ntop; + ntop=get_peer_ipaddr(newsock); + debug("ACPT: drop connection with %s: Accept table full.", ntop); + xfree(ntop); + close(newsock); + continue; + } else { + char *ntop; + ntop=get_peer_ipaddr(newsock); + debug("ACPT: Accept_tbl ok! accept_idx: %d from %s", accept_idx, ntop); + xfree(ntop); + } + for (j = 0; j < options.max_startups; j++) if (startup_pipes[j] == -1) { @@ -1309,6 +1338,7 @@ break; } + /* * Got connection. Fork a child to handle it, unless * we are in debugging mode. @@ -1327,6 +1357,7 @@ pid = getpid(); break; } else { + /* * Normal production daemon. Fork, and have * the child process the connection. The @@ -1351,10 +1382,13 @@ } /* Parent. Stay in the loop. */ - if (pid < 0) + if (pid < 0) { error("fork: %.100s", strerror(errno)); - else + del_accept(accept_idx); + } else { debug("Forked child %ld.", (long)pid); + add_accept_pid(pid); + } close(startup_p[1]); @@ -1489,6 +1523,8 @@ */ if (use_privsep) { mm_send_keystate(pmonitor); + debug("ACPT: privsep: Destroying the accept_tbl"); + destroy_accept_tbl(); exit(0); } @@ -1520,6 +1556,8 @@ if (use_privsep) mm_terminate(); + debug("ACPT: child exit: Destroying the accept_tbl"); + destroy_accept_tbl(); exit(0); } diff -Nru ORIGINAL-3.8.1p1/sshd_config openssh-3.8.1p1-alptpatch/sshd_config --- ORIGINAL-3.8.1p1/sshd_config 2003-12-31 01:38:32.000000000 +0100 +++ openssh-3.8.1p1-alptpatch/sshd_config 2004-09-07 13:24:49.433091632 +0200 @@ -88,7 +88,8 @@ #ClientAliveCountMax 3 #UseDNS yes #PidFile /var/run/sshd.pid -#MaxStartups 10 +#MaxConnections 500 +#MaxAcceptsPerHost 10 # no default banner path #Banner /some/path diff -Nru ORIGINAL-3.8.1p1/sshd_config.0 openssh-3.8.1p1-alptpatch/sshd_config.0 --- ORIGINAL-3.8.1p1/sshd_config.0 2004-04-18 14:52:00.000000000 +0200 +++ openssh-3.8.1p1-alptpatch/sshd_config.0 2004-09-07 13:24:03.425085912 +0200 @@ -224,20 +224,27 @@ ed. The default is ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac- sha1-96,hmac-md5-96''. - MaxStartups - Specifies the maximum number of concurrent unauthenticated con- - nections to the sshd daemon. Additional connections will be - dropped until authentication succeeds or the LoginGraceTime ex- - pires for a connection. The default is 10. - - Alternatively, random early drop can be enabled by specifying the - three colon separated values ``start:rate:full'' (e.g., - "10:30:60"). sshd will refuse connection attempts with a proba- - bility of ``rate/100'' (30%) if there are currently ``start'' - (10) unauthenticated connections. The probability increases lin- - early and all connection attempts are refused if the number of - unauthenticated connections reaches ``full'' (60). - + MaxConnections + Specifies the maximum number of concurrent connections of authen- + ticated/unauthenticated hosts wich the server will accept. + The default is 500. + The number of total connections is MaxConnections*MaxAcceptsPerHost. + For MaxAcceptsPerHost see below. + + MaxAcceptsPerHost + Specifies the maximum number of concurrent authenticated/unauthenticated + connections from the same host to the sshd daemon. Additional con- + nections will be dropped until the host close one or more client. + The default is 10. + + Each accept is kept for free_accept_time (default is 5)seconds + after the close of the relative connection, thus if the accepts + have reached MaxAcceptPerHost then the host has to wait + free_accept_time seconds to reconnect again. + The free_accept_time can be modified by speficying the two colon + separeted values ``max_accepts_per_host:free_accept_time'' (e.g., + "25:3"). + PasswordAuthentication Specifies whether password authentication is allowed. The de- fault is ``yes''. diff -Nru ORIGINAL-3.8.1p1/sshd_config.5 openssh-3.8.1p1-alptpatch/sshd_config.5 --- ORIGINAL-3.8.1p1/sshd_config.5 2004-04-14 05:04:36.000000000 +0200 +++ openssh-3.8.1p1-alptpatch/sshd_config.5 2004-09-07 13:24:20.684462088 +0200 @@ -386,31 +386,30 @@ Multiple algorithms must be comma-separated. The default is .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . -.It Cm MaxStartups -Specifies the maximum number of concurrent unauthenticated connections to the -.Nm sshd -daemon. -Additional connections will be dropped until authentication succeeds or the -.Cm LoginGraceTime -expires for a connection. +.It Cm MaxConnections +Specifies the maximum number of concurrent connections of +authenticated/unauthenticated hosts wich the server will accept. +The default is 500. +The number of total connections is +.Dq MaxConnections*MaxAcceptsPerHost +For MaxAcceptsPerHost see below. +.It Cm MaxAcceptPerHost +Specifies the maximum number of concurrent authenticated/unauthenticated +connections from the same hsot to the sshd daemon. Additional connections +will be dropped until the host close one or more client. 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 sshd -will refuse connection attempts with a probability of -.Dq rate/100 -(30%) -if there are currently -.Dq start -(10) -unauthenticated connections. -The probability increases linearly and all connection attempts -are refused if the number of unauthenticated connections reaches -.Dq full -(60). +Each accept is kept for +.Dq free_accept_time +(default is 5)seconds +after the close of the relative connection, thus if the accepts +have reached +.Dq MaxAcceptPerHost +then the host has to wait free_accept_time seconds to reconnect again. +The free_accept_time can be modified by speficying the two colon +separeted values +.Dq max_accept_per_host:free_accept_time +(e.g., "25:3"). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is