home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
auth
/
part01
/
authuser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-29
|
7KB
|
236 lines
char authuserauthor[] =
"authuser was written by Daniel J. Bernstein.\n\
Internet address: brnstnd@acf10.nyu.edu.\n";
char authuserversion[] =
"authuser version 2.0, April 2, 1990.\n\
Copyright (c) 1990, Daniel J. Bernstein.\n\
All rights reserved.\n";
char authusercopyright[] =
"authuser version 2.0, April 2, 1990.\n\
Copyright (c) 1990, Daniel J. Bernstein.\n\
All rights reserved.\n\
\n\
Until January 1, 1993, you are granted the following rights: A. To make\n\
copies of this work in original form, so long as (1) the copies are exact\n\
and complete; (2) the copies include the copyright notice, this paragraph,\n\
and the disclaimer of warranty in their entirety. B. To distribute this\n\
work, or copies made under the provisions above, so long as (1) this is\n\
the original work and not a derivative form; (2) you do not charge a fee\n\
for copying or for distribution; (3) you ensure that the distributed form\n\
includes the copyright notice, this paragraph, and the disclaimer of\n\
warranty in their entirety. These rights are temporary and revocable upon\n\
written, oral, or other notice by Daniel J. Bernstein. These rights are\n\
automatically revoked on January 1, 1993. This copyright notice shall be\n\
governed by the laws of the state of New York.\n\
\n\
If you have questions about authuser or about this copyright notice,\n\
or if you would like additional rights beyond those granted above,\n\
please feel free to contact the author at brnstnd@acf10.nyu.edu\n\
on the Internet.\n";
char authuserwarranty[] =
"To the extent permitted by applicable law, Daniel J. Bernstein disclaims\n\
all warranties, explicit or implied, including but not limited to the\n\
implied warranties of merchantability and fitness for a particular purpose.\n\
Daniel J. Bernstein is not and shall not be liable for any damages,\n\
incidental or consequential, arising from the use of this program, even\n\
if you inform him of the possibility of such damages. This disclaimer\n\
shall be governed by the laws of the state of New York.\n\
\n\
In other words, use this program at your own risk.\n\
\n\
If you have questions about authuser or about this disclaimer of warranty,\n\
please feel free to contact the author at brnstnd@acf10.nyu.edu\n\
on the Internet.\n";
char authuserhelp[] =
"#include \"authuser.h\"\n\
\n\
int auth_casecmp(u,v); char *u; char *v;\n\
Returns 0 if strings are equal, 1 if the first is larger, -1 if the\n\
second is larger. Case is ignored.\n\
\n\
char *auth_xline(user,fd,&in);\n\
Returns line like X-Auth-User: username or X-Forgery-By: username,\n\
depending what the host on the other side of fd thinks of the user.\n\
\n\
int auth_fd(fd,&in,&local,&remote);\n\
Places address information for TCP connection fd into in, local, remote.\n\
\n\
char *auth_tcpuser(in,local,remote);\n\
Returns name of user on remote@in side of local TCP connection.\n\
\n\
char *user; int fd; unsigned long in; unsigned short local, remote;\n\
\n\
If you have questions about or suggestions for authuser, please feel free\n\
to contact the author, Daniel J. Bernstein, at brnstnd@acf10.nyu.edu\n\
on the Internet.\n";
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/errno.h>
extern int errno;
#include <ctype.h>
#include "authuser.h"
#ifndef AUTHTCPPORT
#define AUTHTCPPORT 113
#endif
#define SIZ 500 /* various buffers */
int auth_casecmp(u,v)
char *u;
char *v;
{
/* is it correct to consider Foo and fOo the same user? yes */
while (*u && *v)
if (tolower(*u) != tolower(*v))
return(tolower(*u) - tolower(*v));
else
u++,v++;
return(*u || *v);
}
static char authline[SIZ];
char *auth_xline(user,fd,in)
char *user; /* the supposed name of the user, NULL if unknown */
int fd; /* the file descriptor of the connection */
unsigned long *in;
{
unsigned short local;
unsigned short remote;
char *ruser;
if (auth_fd(fd,in,&local,&remote) == -1)
return NULL;
ruser = auth_tcpuser(*in,local,remote);
if (ruser == NULL)
return(NULL);
if (user == NULL)
user = ruser; /* forces X-Auth-User */
sprintf(authline,
(auth_casecmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
ruser);
return(authline);
}
int auth_fd(fd,in,local,remote)
int fd;
unsigned long *in;
unsigned short *local;
unsigned short *remote;
{
struct sockaddr_in sa;
int dummy;
dummy = sizeof(sa);
if (getsockname(fd,&sa,&dummy) == -1)
return -1;
if (sa.sin_family != AF_INET)
{
errno = EAFNOSUPPORT;
return -1;
}
*local = ntohs(sa.sin_port);
dummy = sizeof(sa);
if (getpeername(fd,&sa,&dummy) == -1)
return -1;
*remote = ntohs(sa.sin_port);
*in = sa.sin_addr.s_addr;
return 0;
}
static char ruser[SIZ];
static char realbuf[SIZ];
static char *buf;
char *auth_tcpuser(in,local,remote)
unsigned long in;
unsigned short local;
unsigned short remote;
{
struct sockaddr_in sa;
int s;
int buflen;
int w;
int saveerrno;
char ch;
unsigned short rlocal;
unsigned short rremote;
if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
return(NULL);
sa.sin_family = AF_INET;
sa.sin_port = htons((unsigned short) AUTHTCPPORT);
sa.sin_addr.s_addr = in;
if (connect(s,&sa,sizeof(sa)) == -1)
{
saveerrno = errno;
(void) close(s);
errno = saveerrno;
return(NULL);
}
buf = realbuf;
(void) sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local);
/* note the reversed order */
buflen = strlen(buf);
while ((w = write(s,buf,buflen)) < buflen)
if (w == -1) /* should we worry about 0 as well? */
{
saveerrno = errno;
(void) close(s);
errno = saveerrno;
return(NULL);
}
else
{
buf += w;
buflen -= w;
}
buf = realbuf;
while ((w = read(s,&ch,1)) == 1)
{
*buf = ch;
if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
buf++;
if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
break;
}
if (w == -1)
{
saveerrno = errno;
(void) close(s);
errno = saveerrno;
return(NULL);
}
*buf = '\0';
if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s",
&rremote,&rlocal,ruser) < 3)
{
(void) 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(NULL);
}
if ((remote != rremote) || (local != rlocal))
{
(void) close(s);
errno = EIO;
return(NULL);
}
/* XXXXXX: we're not going to do any backslash processing */
(void) close(s);
return(ruser);
}