diff options
author | dwmalone <dwmalone@FreeBSD.org> | 2000-07-12 20:49:06 +0000 |
---|---|---|
committer | dwmalone <dwmalone@FreeBSD.org> | 2000-07-12 20:49:06 +0000 |
commit | 6d86be7d4fb098feb16675d649d381aab8e40d75 (patch) | |
tree | 1b51c4dabafbc6f65c397aa51c774e6ec2d14d28 /usr.sbin/inetd | |
parent | 05d38117c267baccd4a5ed92d395ec4587e42775 (diff) | |
download | FreeBSD-src-6d86be7d4fb098feb16675d649d381aab8e40d75.zip FreeBSD-src-6d86be7d4fb098feb16675d649d381aab8e40d75.tar.gz |
Make builtin ident service work if the request arrives in more than
one packet. Also check that the whole request has been recieved
before processing it.
The patch isn't the exact one from the PR, but a slight varient
suggested by Brian.
PR: 16086
Submitted by: Hajimu UMEMOTO <ume@mahoroba.org>
Reviewed by: green
Diffstat (limited to 'usr.sbin/inetd')
-rw-r--r-- | usr.sbin/inetd/builtins.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/usr.sbin/inetd/builtins.c b/usr.sbin/inetd/builtins.c index 7516ed0..c32a98d 100644 --- a/usr.sbin/inetd/builtins.c +++ b/usr.sbin/inetd/builtins.c @@ -343,14 +343,14 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */ struct timeval tv = { 10, 0 - }; + }, to; struct passwd *pw = NULL; fd_set fdset; - char buf[BUFSIZE], *cp = NULL, *p, **av, *osname = NULL, garbage[7]; + char buf[BUFSIZE], *cp = NULL, *p, **av, *osname = NULL, garbage[7], e; char *fallback = NULL; socklen_t socklen; ssize_t ssize; - size_t size; + size_t size, bufsiz; int c, fflag = 0, nflag = 0, rflag = 0, argc = 0, usedfallback = 0; int gflag = 0, getcredfail = 0, onreadlen; u_short lport, fport; @@ -450,19 +450,42 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */ * "local_port , foreign_port\r\n" (with local being the * server's port and foreign being the client's.) */ + gettimeofday(&to, NULL); + to.tv_sec += tv.tv_sec; + if ((to.tv_usec += tv.tv_usec) >= 1000000) { + to.tv_usec -= 1000000; + to.tv_sec++; + } + + size = 0; + bufsiz = sizeof(buf) - 1; FD_ZERO(&fdset); - FD_SET(s, &fdset); - if (select(s + 1, &fdset, NULL, NULL, &tv) == -1) - iderror(0, 0, s, errno); - if (ioctl(s, FIONREAD, &onreadlen) == -1) - iderror(0, 0, s, errno); - if (onreadlen >= sizeof(buf)) - onreadlen = sizeof(buf) - 1; - ssize = read(s, buf, (size_t)onreadlen); - if (ssize == -1) - iderror(0, 0, s, errno); - buf[ssize] = '\0'; - if (sscanf(buf, "%hu , %hu", &lport, &fport) != 2) + while (bufsiz > 0 && (size == 0 || buf[size - 1] != '\n')) { + gettimeofday(&tv, NULL); + tv.tv_sec = to.tv_sec - tv.tv_sec; + tv.tv_usec = to.tv_usec - tv.tv_usec; + if (tv.tv_usec < 0) { + tv.tv_usec += 1000000; + tv.tv_sec--; + } + if (tv.tv_sec < 0) + break; + FD_SET(s, &fdset); + if (select(s + 1, &fdset, NULL, NULL, &tv) == -1) + iderror(0, 0, s, errno); + if (ioctl(s, FIONREAD, &onreadlen) == -1) + iderror(0, 0, s, errno); + if (onreadlen > bufsiz) + onreadlen = bufsiz; + ssize = read(s, &buf[size], (size_t)onreadlen); + if (ssize == -1) + iderror(0, 0, s, errno); + bufsiz -= ssize; + size += ssize; + } + buf[size] = '\0'; + /* Read two characters, and check for a delimiting character */ + if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e)) iderror(0, 0, s, 0); if (gflag) { cp = garbage; |