diff options
author | Assar Westerlund <assar@FreeBSD.org> | 2000-12-29 21:16:01 +0000 |
---|---|---|
committer | Assar Westerlund <assar@FreeBSD.org> | 2000-12-29 21:16:01 +0000 |
commit | 6e3caa083303aae41395c7ff038ab93ff203208b (patch) | |
tree | 564e6def471523fb64196a9e9a3ea2cd510fd4d8 /crypto/kerberosIV/server | |
parent | 2a9bc9996cc1964214c65198c735d1caeba63b74 (diff) | |
download | src-6e3caa083303aae41395c7ff038ab93ff203208b.tar.gz src-6e3caa083303aae41395c7ff038ab93ff203208b.zip |
fix conflicts from merge
Notes
Notes:
svn path=/head/; revision=70497
Diffstat (limited to 'crypto/kerberosIV/server')
-rw-r--r-- | crypto/kerberosIV/server/kerberos.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/crypto/kerberosIV/server/kerberos.c b/crypto/kerberosIV/server/kerberos.c index 32f34e2aa5bc..09a65df567e3 100644 --- a/crypto/kerberosIV/server/kerberos.c +++ b/crypto/kerberosIV/server/kerberos.c @@ -10,7 +10,13 @@ #include "config.h" #include "protos.h" -RCSID("$Id: kerberos.c,v 1.87 1999/11/13 06:35:39 assar Exp $"); +RCSID("$Id: kerberos.c,v 1.87.2.3 2000/10/18 20:24:13 assar Exp $"); + +/* + * If support for really large numbers of network interfaces is + * desired, define FD_SETSIZE to some suitable value. + */ +#define FD_SETSIZE (4*1024) #include <stdio.h> #include <stdlib.h> @@ -299,10 +305,13 @@ kerberos(unsigned char *buf, int len, switch(msg_type){ case AUTH_MSG_KDC_REQUEST: /* XXX range check */ - p += krb_get_nir(p, name, inst, realm); + p += krb_get_nir(p, name, sizeof(name), + inst, sizeof(inst), + realm, sizeof(realm)); p += krb_get_int(p, &req_time, 4, lsb); life = *p++; - p += krb_get_nir(p, service, sinst, NULL); + p += krb_get_nir(p, service, sizeof(service), + sinst, sizeof(sinst), NULL, 0); klog(L_INI_REQ, "AS REQ %s.%s@%s for %s.%s from %s (%s/%u)", name, inst, realm, service, sinst, @@ -378,7 +387,8 @@ kerberos(unsigned char *buf, int len, } p += krb_get_int(p, &req_time, 4, lsb); life = *p++; - p += krb_get_nir(p, service, sinst, NULL); + p += krb_get_nir(p, service, sizeof(service), + sinst, sizeof(sinst), NULL, 0); klog(L_APPL_REQ, "APPL REQ %s.%s@%s for %s.%s from %s (%s/%u)", ad.pname, ad.pinst, ad.prealm, @@ -556,6 +566,10 @@ mksocket(struct descr *d, struct in_addr addr, int type, memset(d, 0, sizeof(struct descr)); if ((sock = socket(AF_INET, type, 0)) < 0) err (1, "socket"); + if (sock >= FD_SETSIZE) { + errno = EMFILE; + errx(1, "Aborting: too many descriptors"); + } #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) < 0) @@ -969,13 +983,24 @@ read_socket(struct descr *n) } } +static fd_set readfds; + static void -loop(struct descr *fds, int nfds) +loop(struct descr *fds, int base_nfds) { + int nfds = base_nfds; + int max_tcp = min(FD_SETSIZE, getdtablesize()) - fds[base_nfds - 1].s; + if (max_tcp <= 10) { + errno = EMFILE; + errx(1, "Aborting: too many descriptors"); + } + max_tcp -= 10; /* We need a few extra for DB, logs, etc. */ + if (max_tcp > 100) max_tcp = 100; /* Keep to some sane limit. */ + for (;;) { int ret; - fd_set readfds; struct timeval tv; + int next_timeout = 10; /* In seconds */ int maxfd = 0; struct descr *n, *minfree; int accepted; /* accept at most one socket per `round' */ @@ -998,12 +1023,15 @@ loop(struct descr *fds, int nfds) } FD_SET(n->s, &readfds); maxfd = max(maxfd, n->s); + next_timeout = min(next_timeout, tv.tv_sec - n->timeout); } /* add more space for sockets */ - if(minfree == NULL){ + if (minfree == NULL && nfds < base_nfds + max_tcp) { int i = nfds; struct descr *new; nfds *=2; + if (nfds > base_nfds + max_tcp) + nfds = base_nfds + max_tcp; new = realloc(fds, sizeof(struct descr) * nfds); if(new){ fds = new; @@ -1011,7 +1039,27 @@ loop(struct descr *fds, int nfds) for(; i < nfds; i++) fds[i].s = -1; } } - ret = select(maxfd + 1, &readfds, 0, 0, 0); + if (minfree == NULL) { + /* + * We are possibly the subject of a DOS attack, pick a TCP + * connection at random and drop it. + */ + int r = rand() % (nfds - base_nfds); + r = r + base_nfds; + FD_CLR(fds[r].s, &readfds); + close(fds[r].s); + fds[r].s = -1; + minfree = &fds[r]; + } + if (next_timeout < 0) next_timeout = 0; + tv.tv_sec = next_timeout; + tv.tv_usec = 0; + ret = select(maxfd + 1, &readfds, 0, 0, &tv); + if (ret < 0) { + if (errno != EINTR) + klog(L_KRB_PERR, "select: %s", strerror(errno)); + continue; + } accepted = 0; for (n = fds; n < fds + nfds; n++){ if(n->s < 0) continue; @@ -1023,8 +1071,7 @@ loop(struct descr *fds, int nfds) if(accepted) continue; accepted = 1; s = accept(n->s, NULL, 0); - if(minfree == NULL){ - kerb_err_reply(s, NULL, KFAILURE, "Out of memory"); + if (minfree == NULL || s >= FD_SETSIZE) { close(s); }else{ minfree->s = s; |