rfc931.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:4k
- /*
- * 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,%urn", 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);
- }