#ifndef lint
static char sccsid[] = "@(#) rfc931.c 1.10 95/01/02 16:11:34";
#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 <string.h>
#include "tcpd.h"
#define RFC931_PORT 113
#define ANY_PORT 0
int rfc931_timeout = RFC931_TIMEOUT;
static jmp_buf timebuf;
static FILE *fsocket(domain, type, protocol)
int domain;
int type;
int protocol;
{
int s;
FILE *fp;
if ((s = socket(domain, type, protocol)) < 0) {
tcpd_warn("socket: %m");
return (0);
} else {
if ((fp = fdopen(s, "r+")) == 0) {
tcpd_warn("fdopen: %m");
close(s);
}
return (fp);
}
}
static void timeout(sig)
int sig;
{
longjmp(timebuf, sig);
}
void rfc931(rmt_sin, our_sin, dest)
struct sockaddr_gen *rmt_sin;
struct sockaddr_gen *our_sin;
char *dest;
{
unsigned rmt_port;
unsigned our_port;
struct sockaddr_gen rmt_query_sin;
struct sockaddr_gen our_query_sin;
char user[256];
char buffer[512];
char *cp;
char *result = unknown;
FILE *fp;
unsigned saved_timeout;
struct sigaction nact, oact;
if ((fp = fsocket(SGFAM(rmt_sin), SOCK_STREAM, 0)) != 0) {
setbuf(fp, (char *) 0);
if (setjmp(timebuf) == 0) {
saved_timeout = alarm(0);
nact.sa_handler = timeout;
nact.sa_flags = 0;
(void) sigemptyset(&nact.sa_mask);
(void) sigaction(SIGALRM, &nact, &oact);
alarm(rfc931_timeout);
our_query_sin = *our_sin;
SGPORT(&our_query_sin) = htons(ANY_PORT);
rmt_query_sin = *rmt_sin;
SGPORT(&rmt_query_sin) = htons(RFC931_PORT);
if (bind(fileno(fp), (struct sockaddr *) &our_query_sin,
SGSOCKADDRSZ(&our_query_sin)) >= 0 &&
connect(fileno(fp), (struct sockaddr *) &rmt_query_sin,
SGSOCKADDRSZ(&rmt_query_sin)) >= 0) {
fprintf(fp, "%u,%u\r\n",
ntohs(SGPORT(rmt_sin)),
ntohs(SGPORT(our_sin)));
fflush(fp);
if (fgets(buffer, sizeof(buffer), fp) != 0
&& ferror(fp) == 0 && feof(fp) == 0
&& sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
&rmt_port, &our_port, user) == 3
&& ntohs(SGPORT(rmt_sin)) == rmt_port
&& ntohs(SGPORT(our_sin)) == our_port) {
if (cp = strchr(user, '\r'))
*cp = 0;
result = user;
}
}
alarm(0);
}
(void) sigaction(SIGALRM, &oact, NULL);
if (saved_timeout > 0)
alarm(saved_timeout);
fclose(fp);
}
STRN_CPY(dest, result, STRING_LENGTH);
}