/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | *
* -----------------------------------------------------------| \\._.// *
* SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) *
* -----------------------------------------------------------| ).:.( *
* SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} *
* -----------------------------------------------------------| / ' ' \ *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~*
* Scryn, Swordbearer, Rennard, Tricops, and Gorog. | *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. *
* ------------------------------------------------------------------------ *
* IDENT protocol userid lookup module *
****************************************************************************/
/* Donated to Realms of Despair by Tricops, author unknown. */
#include "stdafx.h"
#include "smaug.h"
#include "objects.h"
#include "rooms.h"
#include "descriptor.h"
#include "character.h"
extern int maxdesc;
extern int write (int fd, char *buf, int nbyte);
extern int read (int fd, char *buf, int nbyte);
extern int close (int fd);
void nonblock (int s);
void start_auth (struct descriptor_data *d);
void read_auth (struct descriptor_data *d);
void send_auth (struct descriptor_data *d);
#ifdef XXXX
/*
* Initiate an IDENT commention
*/
void start_auth (struct descriptor_data *d)
{
struct sockaddr_in sock;
struct servent *serv;
int err, tlen;
d->auth_fd = socket (AF_INET, SOCK_STREAM, 0);
err = errno;
if (d->auth_fd < 0 && err == EAGAIN)
bug ("Can't allocate fd for authorization check", 0);
nonblock (d->auth_fd);
tlen = sizeof (sock);
getpeername (d->descriptor, (struct sockaddr *)&sock, &tlen);
serv = getservbyname ("ident", "tcp");
if (!serv)
sock.sin_port = htons (113);
else
sock.sin_port = serv->s_port;
sock.sin_family = AF_INET;
if (connect (d->auth_fd, (struct sockaddr *)&sock, sizeof (sock)) == -1
&& errno != EINPROGRESS)
{
/* Identd Denied */
/* bug ("Unable to verify userid", 9); */
close (d->auth_fd);
d->auth_fd = -1;
d->auth_state = 0;
return;
}
d->auth_state |= (FLAG_WRAUTH|FLAG_AUTH); /* Successful, but not sent */
if (d->auth_fd > maxdesc) maxdesc = d->auth_fd;
return;
}
/* send_auth */
void send_auth (struct descriptor_data *d)
{
struct sockaddr_in us, them;
char authbuf[32];
int ulen, tlen, z;
tlen = ulen = sizeof (us);
if (getsockname (d->descriptor, (struct sockaddr *)&us, &ulen)
|| getpeername (d->descriptor, (struct sockaddr *)&them, &tlen))
{
bug ("auth getsockname error", 0);
goto authsenderr;
}
/* compose request */
sprintf (authbuf, "%u , %u\r\n",
(unsigned int)ntohs (them.sin_port),
(unsigned int)ntohs (us.sin_port));
z = write (d->auth_fd, authbuf, strlen (authbuf));
if (z != strlen (authbuf))
{
if (d->atimes >= 19)
{
/* sprintf (log_buf, "auth request, broken pipe [%d/%d]", z, errno);
gpDoc->LogString (log_buf); */
perror ("send_auth");
}
authsenderr:
close (d->auth_fd);
if (d->auth_fd == maxdesc) maxdesc--;
d->auth_fd = -1;
d->auth_state &= ~FLAG_AUTH; /* Failure/Continue */
d->auth_inc = 0;
if (d->atimes < 20) d->atimes++;
}
d->auth_state &= ~FLAG_WRAUTH; /* Successfully sent request */
return;
}
/* read_auth */
void read_auth (struct descriptor_data *d)
{
char *s, *t;
int len; /* length read */
char ruser[20], system[8]; /* remote userid */
u_short remp = 0, locp = 0; /* remote port, local port */
*system = *ruser = '\0';
/*
* Can't allow any other reads from client fd while waiting on the
* authfd to return a full valid string. Use the client's input buffer
* to buffer the authd reply. May take more than one read.
*/
if ((len = read (d->auth_fd, d->abuf + d->auth_inc,
sizeof (d->abuf) - 1 - d->auth_inc)) >= 0)
{
d->auth_inc += len;
d->abuf[d->auth_inc] = '\0';
}
if ((len > 0) && (d->auth_inc != (sizeof (d->abuf) - 1))
&& (sscanf (d->abuf, "%hd , %hd : USERID : %*[^:]: %10s",
&remp, &locp, ruser) == 3))
{
s = rindex (d->abuf, ':');
*s++ = '\0';
for (t = (rindex (d->abuf, ':') + 1); *t; t++)
if (!isspace (*t))
break;
strncpy (system, t, sizeof (system));
for (t = ruser; *s && (t < ruser + sizeof (ruser)); s++)
if (!isspace (*s) && *s != ':')
*t++ = *s;
*t = '\0';
sprintf (log_buf, "auth reply ok, incoming user: [%s]", ruser);
gpDoc->LogString (log_buf, LOG_COMM, LEVEL_GOD);
/* STRFREE (d->user);
d->user = STRALLOC (ruser);*/
}
else if (len != 0)
{
if (!index (d->abuf, '\n') && !index (d->abuf, '\r')) return;
sprintf (log_buf, "bad auth reply: %s", d->abuf);
gpDoc->LogString (log_buf, LOG_COMM, LEVEL_GOD);
ruser[0] = '\0';
}
close (d->auth_fd);
if (d->auth_fd == maxdesc)
--maxdesc;
d->auth_inc = 0;
*d->abuf = '\0';
d->auth_fd = -1;
d->auth_state = 0;
if (ruser[0] == '\0')
strcpy (ruser, "(no auth)");
STRFREE (d->user);
d->user = STRALLOC (ruser);
return;
}
void nonblock (int s)
{
if (fcntl (s, F_SETFL, FNDELAY) == -1)
{
perror ("Noblock");
exit (2);
}
}
#endif
/*
int workaround (struct descriptor_data *d)
{
BAN_DATA *tmp;
char *nicnamehost;
sprintf (log_buf, "%s!%s@%s", d->name, d->user, d->host);
nicknamehost = str_dup (log_buf);
for (tmp = ncsa_list; tmp; tmp = tmp->next)
{
if (!match (tmp->user, nicknamehost))
{
FREE (nicknamehost);
write_to_descriptor (d->descriptor, "NCSA telnet patch loaded.\n");
return 1;
}
}
FREE (nicknamehost);
return 0;
}
*/