diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /innbbsd/rfc931.c | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'innbbsd/rfc931.c')
-rw-r--r-- | innbbsd/rfc931.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/innbbsd/rfc931.c b/innbbsd/rfc931.c new file mode 100644 index 00000000..0d59d771 --- /dev/null +++ b/innbbsd/rfc931.c @@ -0,0 +1,144 @@ + /* + * rfc931_user() speaks a common subset of the RFC 931, AUTH, TAP and IDENT + * protocols. It consults an RFC 931 etc. compatible daemon on the client + * host to look up the remote user name. The information should not be used + * for authentication purposes. + * + * Diagnostics are reported through syslog(3). + * + * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + * + * Inspired by the authutil package (comp.sources.unix volume 22) by Dan + * Bernstein (brnstnd@kramden.acf.nyu.edu). + */ + +#ifndef lint +static char sccsid[] = "@(#) rfc931.c 1.4 93/03/07 22:47:52"; +#endif + +#include <stdio.h> +#include <syslog.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <setjmp.h> +#include <signal.h> + +/*#include "log_tcp.h"*/ + +#define RFC931_PORT 113 /* Semi-well-known port */ + +#ifndef RFC931_TIMEOUT +#define RFC931_TIMEOUT 30 /* wait for at most 30 seconds */ +#endif + +extern char *strchr(); +extern char *inet_ntoa(); + +static jmp_buf timebuf; + +/* timeout - handle timeouts */ + +static void timeout(sig) +int sig; +{ + longjmp(timebuf, sig); +} + +/* rfc931_name - return remote user name */ + +char *my_rfc931_name(herefd,there) +int herefd; +struct sockaddr_in *there; /* remote link information */ +{ + struct sockaddr_in here; /* local link information */ + struct sockaddr_in sin; /* for talking to RFC931 daemon */ + int length; + int s; + unsigned remote; + unsigned local; + static char user[256]; /* XXX */ + char buffer[512]; /* YYY */ + FILE *fp; + char *cp; + char *result = "unknown"; + + /* Find out local address and port number of stdin. */ + + length = sizeof(here); + if (getsockname(herefd, (struct sockaddr *) & here, &length) == -1) { + syslog(LOG_ERR, "getsockname: %m"); + return (result); + } + + /* + * The socket that will be used for user name lookups should be bound to + * the same local IP address as stdin. This will automagically happen on + * hosts that have only one IP network address. When the local host has + * more than one IP network address, we must do an explicit bind() call. + */ + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return (result); + + sin = here; + sin.sin_port = 0; + if (bind(s, (struct sockaddr *) & sin, sizeof sin) < 0) { + syslog(LOG_ERR, "bind: %s: %m", inet_ntoa(here.sin_addr)); + return (result); + } + /* Set up timer so we won't get stuck. */ + + signal(SIGALRM, timeout); + if (setjmp(timebuf)) { + close(s); /* not: fclose(fp) */ + return (result); + } + alarm(RFC931_TIMEOUT); + + /* Connect to the RFC931 daemon. */ + + sin = *there; + sin.sin_port = htons(RFC931_PORT); + if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) == -1 + || (fp = fdopen(s, "w+")) == 0) { + close(s); + alarm(0); + return (result); + } + + /* + * Use unbuffered I/O or we may read back our own query. setbuf() must be + * called before doing any I/O on the stream. Thanks for the reminder, + * Paul Kranenburg <pk@cs.few.eur.nl>! + */ + + setbuf(fp, (char *) 0); + + /* Query the RFC 931 server. Would 13-byte writes ever be broken up? */ + + fprintf(fp, "%u,%u\r\n", ntohs(there->sin_port), ntohs(here.sin_port)); + fflush(fp); + + /* + * Read response from server. Use fgets()/sscanf() instead of fscanf() + * because there is no buffer for pushback. Thanks, Chris Turbeville + * <turbo@cse.uta.edu>. + */ + + if (fgets(buffer, sizeof(buffer), fp) != 0 + && ferror(fp) == 0 && feof(fp) == 0 + && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s", + &remote, &local, user) == 3 + && ntohs(there->sin_port) == remote + && ntohs(here.sin_port) == local) { + /* Strip trailing carriage return. */ + + if (cp = strchr(user, '\r')) + *cp = 0; + result = user; + } + alarm(0); + fclose(fp); + return (result); +} |