wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
/*
 ** authuser.c
 **
 ** 2/2/93: Added auth_setreadtimeout() call.
 ** 7/21/92: Fixed SIGPIPE bug in auth_tcpuser3(). <pen@lysator.liu.se>
 ** 2/9/92: authuser 4.0. Public domain.
 ** 2/9/92: added bunches of zeroing just in case.
 ** 2/9/92: added auth_tcpuser3. uses bsd 4.3 select interface.
 ** 2/9/92: added auth_tcpsock, auth_sockuser.
 ** 2/9/92: added auth_fd2, auth_tcpuser2, simplified some of the code.
 ** 12/27/91: fixed up usercmp to deal with restricted tolower XXX
 ** 5/6/91 DJB baseline authuser 3.1. Public domain.
 */

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/file.h>
#include <fcntl.h> /*XXX*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
extern int errno;

#define _AUTHUSER_C
#include "authuser.h"

#ifndef FNDELAY
#  define FNDELAY O_NDELAY
#endif

unsigned short auth_tcpport = 113;
int            auth_rtimeout = 60;	/* 1 minute */

#define SIZ 500 /* various buffers */

static void clearsa(struct sockaddr_in *sa) {
    register char *x;
    for (x = (char *) sa;x < sizeof(*sa) + (char *) sa;++x)
	*x = 0;
}

static int usercmp( register char *u, register char *v) {
    register char uc = '\0';
    register char vc = '\0';
    register char ucvc = '\0';
    /* is it correct to consider Foo and fOo the same user? yes */
    /* but the function of this routine may change later */
    while ((uc = *u) && (vc = *v))
    {
	ucvc = (isupper(uc) ? tolower(uc) : uc) - (isupper(vc) ? tolower(vc) : vc);
	if (ucvc)
	    return ucvc;
	else
	    ++u,++v;
    }
    return uc || vc;
}

static char authline[SIZ];

char *auth_xline(register char *user, register int fd, register unsigned long *in)
{
    unsigned short local;
    unsigned short remote;
    register char *ruser;
    
    if (auth_fd(fd,in,&local,&remote) == -1)
	return 0;
    ruser = auth_tcpuser(*in,local,remote);
    if (!ruser)
	return 0;
    if (!user)
	user = ruser; /* forces X-Auth-User */
    sprintf(authline,
	    (usercmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
	    ruser);
    return authline;
}

int auth_fd( register int fd, register unsigned long *in,
    register unsigned short *local, register unsigned short *remote)
{
    unsigned long inlocal;
    return auth_fd2(fd,&inlocal,in,local,remote);
}

int auth_fd2( register int fd, register unsigned long *inlocal,
    register unsigned long *inremote, register unsigned short *local,
    register unsigned short *remote)
{
    struct sockaddr_in sa;
    int dummy;
    
    dummy = sizeof(sa);
    if (getsockname(fd,(struct sockaddr *)&sa,&dummy) == -1)
	return -1;
    if (sa.sin_family != AF_INET)
    {
	errno = EAFNOSUPPORT;
	return -1;
    }
    *local = ntohs(sa.sin_port);
    *inlocal = sa.sin_addr.s_addr;
    dummy = sizeof(sa);
    if (getpeername(fd,(struct sockaddr *)&sa,&dummy) == -1)
	return -1;
    *remote = ntohs(sa.sin_port);
    *inremote = sa.sin_addr.s_addr;
    return 0;
}

static char ruser[SIZ];
static char realbuf[SIZ];
static char *buf;

char *auth_tcpuser( register unsigned long in, register unsigned short local,
    register unsigned short remote)
{
    return auth_tcpuser2(0,in,local,remote);
}

#define CLORETS(e) { saveerrno = errno; close(s); errno = saveerrno; return e; }

int auth_tcpsock( register unsigned long inlocal,
    register unsigned long inremote)
{
    struct sockaddr_in sa;
    register int s;
    register int fl;
    register int saveerrno;
    
    if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
	return -1;
    if (inlocal)
    {
	clearsa(&sa);
	sa.sin_family = AF_INET;
	sa.sin_port = 0;
	sa.sin_addr.s_addr = inlocal;
	if (bind(s,(struct sockaddr *)&sa,sizeof(sa)) == -1)
	    CLORETS(-1)
	    }
    if ((fl = fcntl(s,F_GETFL,0)) == -1)
	CLORETS(-1);
    if (fcntl(s,F_SETFL,FNDELAY | fl) == -1)
	CLORETS(-1);
    clearsa(&sa);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(auth_tcpport);
    sa.sin_addr.s_addr = inremote;
    if (connect(s,(struct sockaddr *)&sa,sizeof(sa)) == -1)
	if (errno != EINPROGRESS)
	    CLORETS(-1)
		return s;
}

char *auth_tcpuser2( register unsigned long inlocal,
    register unsigned long inremote,
    register unsigned short local,
    register unsigned short remote)
{
    register int s;
    
    s = auth_tcpsock(inlocal,inremote);
    if (s == -1)
	return 0;
    return auth_sockuser(s,local,remote);
}

char *auth_tcpuser3( register unsigned long inlocal,
    register unsigned long inremote,
    register unsigned short local,
    register unsigned short remote,
    register int ctimeout)
{
    return auth_tcpuser4(inlocal,
			 inremote,
			 local,
			 remote,
			 ctimeout,
			 auth_rtimeout);
}


char *auth_tcpuser4( register unsigned long inlocal,
    register unsigned long inremote,
    register unsigned short local,
    register unsigned short remote,
    register int ctimeout,
    register int rtimeout)
{
    register int s;
    struct timeval ctv;
    fd_set wfds;
    register int r;
    register int saveerrno;
    void *old_sig;
    char *retval;
    
    
    old_sig = signal(SIGPIPE, SIG_IGN);
    
    s = auth_tcpsock(inlocal,inremote);
    if (s == -1)
    {
	signal(SIGPIPE, old_sig);
	return 0;
    }
    ctv.tv_sec = ctimeout;
    ctv.tv_usec = 0;
    FD_ZERO(&wfds);
    FD_SET(s,&wfds);
    r = select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&ctv);
    /* XXX: how to handle EINTR? */
    if (r == -1)
    {
	signal(SIGPIPE, old_sig);
	CLORETS(0);
    }
    if (!FD_ISSET(s,&wfds))
    {
	close(s);
	errno = ETIMEDOUT;
	signal(SIGPIPE, old_sig);
	return 0;
    }
    retval = auth_sockuser2(s,local,remote,rtimeout);
    signal(SIGPIPE, old_sig);
    
    return retval;
}

char *auth_sockuser( register int s,
    register unsigned short local,
    register unsigned short remote)
{
    return auth_sockuser2(s, local, remote, auth_rtimeout);
}

char *auth_sockuser2( register int s,
    register unsigned short local,
    register unsigned short remote,
    int rtimeout)
{
    register int buflen;
    register int w;
    register int saveerrno;
    char ch;
    unsigned short rlocal;
    unsigned short rremote;
    register int fl;
    fd_set wfds;
    void *old_sig;
    struct timeval rtv;
    
    old_sig = signal(SIGPIPE, SIG_IGN);
    
    FD_ZERO(&wfds);
    FD_SET(s,&wfds);
    
    select(s + 1,
	   (fd_set *) 0,
	   &wfds,(fd_set *) 0,
	   (struct timeval *) 0);
    
    /* now s is writable */
    if ((fl = fcntl(s,F_GETFL,0)) == -1)
    {
	signal(SIGPIPE, old_sig);
	CLORETS(0);
    }
    if (fcntl(s,F_SETFL,~FNDELAY & fl) == -1)
    {
	signal(SIGPIPE, old_sig);
	CLORETS(0);
    }
    buf = realbuf;
    sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local);
    /* note the reversed order---the example in RFC 931 is misleading */
    buflen = strlen(buf);
    while ((w = write(s,buf,buflen)) < buflen)
	if (w == -1) /* should we worry about 0 as well? */
	{
	    signal(SIGPIPE, old_sig);
	    CLORETS(0);
	}
	else
	{
	    buf += w;
	    buflen -= w;
	}
    buf = realbuf;
    
    do
    {
	fd_set rd_fds;
	
	rtv.tv_sec = rtimeout;
	rtv.tv_usec = 0;
    
	FD_ZERO(&rd_fds);
	FD_SET(s, &rd_fds);
	if (select(s+1,
		   &rd_fds,
		   (fd_set *) 0,
		   (fd_set *) 0,
		   &rtv) == 0)
	{
	    w = -1;
	    goto END;
	}
	
	if ((w = read(s,&ch,1)) == 1)
	{
	    *buf = ch;
	    if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
		++buf;
	    if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
		break;
	}
    } while (w == 1);
    
    END: 
    signal(SIGPIPE, old_sig);
    if (w == -1)
	CLORETS(0)
	    *buf = 0;
    
    if (sscanf(realbuf, "%hd,%hd: USERID :%*[^:]:%s",
	       &rremote, &rlocal, ruser) < 3)
    {
	close(s);
	errno = EIO;
	/* makes sense, right? well, not when USERID failed to match ERROR */
	/* but there's no good error to return in that case */
	return 0;
    }
    if ((remote != rremote) || (local != rlocal))
    {
	close(s);
	errno = EIO;
	return 0;
    }
    /* we're not going to do any backslash processing */
    close(s);
    return ruser;
}