aboutsummaryrefslogtreecommitdiff
path: root/crypto/kerberosIV/server/kerberos.c
diff options
context:
space:
mode:
authorAssar Westerlund <assar@FreeBSD.org>2000-12-29 21:16:01 +0000
committerAssar Westerlund <assar@FreeBSD.org>2000-12-29 21:16:01 +0000
commit6e3caa083303aae41395c7ff038ab93ff203208b (patch)
tree564e6def471523fb64196a9e9a3ea2cd510fd4d8 /crypto/kerberosIV/server/kerberos.c
parent2a9bc9996cc1964214c65198c735d1caeba63b74 (diff)
downloadsrc-6e3caa083303aae41395c7ff038ab93ff203208b.tar.gz
src-6e3caa083303aae41395c7ff038ab93ff203208b.zip
fix conflicts from merge
Notes
Notes: svn path=/head/; revision=70497
Diffstat (limited to 'crypto/kerberosIV/server/kerberos.c')
-rw-r--r--crypto/kerberosIV/server/kerberos.c67
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;