Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v29i127: pidentd-2.7 - Portable Ident Daemon, V2.7, Part04/09

5 views
Skip to first unread message

Peter Eriksson

unread,
Sep 8, 1996, 3:00:00 AM9/8/96
to

Submitted-By: pe...@ifm.liu.se (Peter Eriksson)
Posting-Number: Volume 29, Issue 127
Archive-Name: pidentd-2.7/part04

#!/bin/sh
# This is part 04 of a multipart archive.
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh08724; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= pidentd-2.7/src/crypto.c ==============
if test ! -d 'pidentd-2.7'; then
$echo 'x -' 'creating directory' 'pidentd-2.7'
mkdir 'pidentd-2.7'
fi
if test ! -d 'pidentd-2.7/src'; then
$echo 'x -' 'creating directory' 'pidentd-2.7/src'
mkdir 'pidentd-2.7/src'
fi
if test -f 'pidentd-2.7/src/crypto.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/crypto.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/crypto.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/crypto.c' &&
/*
** crypto.c Crypto extension to pidentd.
**
** This file is in the public domain. -- Planar 1994.02.21
**
** Crypto routines.
*/
X
#ifdef INCLUDE_CRYPT
X
#ifdef NeXT31
# include <libc.h>
#endif
X
#include <stdio.h>
X
#include <sys/types.h>
#include <netinet/in.h>
X
#ifndef HPUX7
# include <arpa/inet.h>
#endif
X
#include <sys/stat.h>
#include <sys/time.h>
X
#include <des.h>
X
typedef unsigned short int_16;
typedef unsigned int int_32;
X
struct info
{
X int_32 checksum;
X int_16 random;
X int_16 uid;
X int_32 date;
X int_32 ip_local;
X int_32 ip_remote;
X int_16 port_local;
X int_16 port_remote;
};
X
typedef union data
{
X struct info fields;
X int_32 longs[6];
X unsigned char chars[24];
} data;
X
static char result[33];
des_key_schedule sched;
X
char to_asc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
X
char to_bin[] =
{
X 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x80, 0x80, 0x3e, 0x80, 0x80, 0x80, 0x3f,
X 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
X 0x3c, 0x3d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
X 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
X 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
X 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,
X 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
X 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
X 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
X 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,
};
X
X
void init_encryption(key_text)
X char *key_text;
{
X des_cblock key_bin;
X
X des_string_to_key(key_text, key_bin);
X des_set_key(key_bin, sched);
}
X
char *make_packet(uid, laddr, lport, faddr, fport)
X int uid;
X struct in_addr *laddr, *faddr;
X int lport, fport;
{
X struct timeval tv;
X union data r;
X int res, i, j;
X
X res = gettimeofday(&tv, NULL);
X srand(tv.tv_usec);
X
X r.fields.random = rand();
X r.fields.uid = htons(uid);
X if (res == 0)
X {
X r.fields.date = htonl(tv.tv_sec);
X }
X else
X {
X r.fields.date = htonl(0);
X }
X
X r.fields.ip_local = laddr->s_addr;
X r.fields.ip_remote = faddr->s_addr;
X r.fields.port_local = htons(lport);
X r.fields.port_remote = htons(fport);
X
X r.fields.checksum = 0;
X for (i = 1; i < 6; i++)
X {
X r.longs[0] ^= r.longs[i];
X }
X
X des_ecb_encrypt((des_cblock *)&(r.longs[0]), (des_cblock *)&(r.longs[0]),
X sched, DES_ENCRYPT);
X r.longs[2] ^= r.longs[0];
X r.longs[3] ^= r.longs[1];
X
X des_ecb_encrypt((des_cblock *)&(r.longs[2]), (des_cblock *)&(r.longs[2]),
X sched, DES_ENCRYPT);
X r.longs[4] ^= r.longs[2];
X r.longs[5] ^= r.longs[3];
X
X des_ecb_encrypt((des_cblock *)&(r.longs[4]), (des_cblock *)&(r.longs[4]),
X sched, DES_ENCRYPT);
X
X for (i = 0, j = 0; i < 24; i+=3, j+=4)
X {
X result[j ] = to_asc[63 & (r.chars[i ] >> 2)];
X result[j+1] = to_asc[63 & ((r.chars[i ] << 4) + (r.chars[i+1] >> 4))];
X result[j+2] = to_asc[63 & ((r.chars[i+1] << 2) + (r.chars[i+2] >> 6))];
X result[j+3] = to_asc[63 & (r.chars[i+2])];
X }
X result[32] = '\0';
X
X return result;
}
X
#define MAX_KEYS 1024
X
static des_cblock keys[MAX_KEYS];
static int num_keys;
X
void init_decryption(key_file)
X FILE *key_file;
{
X char buf[1024];
X
X num_keys = 0;
X
X while (fgets(buf, 1024, key_file) != NULL && num_keys < MAX_KEYS)
X {
X des_string_to_key(buf, keys[num_keys++]);
X }
X
X des_set_key (keys [0], sched);
}
X
X
static char readable[75];
X
char *decrypt_packet(packet)
X char *packet;
{
X union data r;
X int i, j, k;
X time_t date_in_sec;
X char *date_in_ascii;
X
X for (k = -1; k < num_keys; k++)
X {
X if (k >= 0)
X des_set_key(keys [k], sched);
X
X for(i = 0, j = 0; i < 24; i+=3, j+=4)
X {
X r.chars[i ] = (to_bin[packet[j ]]<<2)+(to_bin[packet[j+1]]>>4);
X r.chars[i+1] = (to_bin[packet[j+1]]<<4)+(to_bin[packet[j+2]]>>2);
X r.chars[i+2] = (to_bin[packet[j+2]] << 6) + (to_bin[packet[j+3]]);
X }
X
X des_ecb_encrypt((des_cblock *)&(r.longs[4]),
X (des_cblock *)&(r.longs[4]),
X sched, DES_DECRYPT);
X r.longs[4] ^= r.longs[2];
X r.longs[5] ^= r.longs[3];
X
X des_ecb_encrypt((des_cblock *)&(r.longs[2]),
X (des_cblock *)&(r.longs[2]),
X sched, DES_DECRYPT);
X
X r.longs[2] ^= r.longs[0];
X r.longs[3] ^= r.longs[1];
X des_ecb_encrypt((des_cblock *)&(r.longs[0]),
X (des_cblock *)&(r.longs[0]),
X sched, DES_DECRYPT);
X
X for (i = 1; i < 6; i++)
X {
X r.longs[0] ^= r.longs[i];
X }
X
X if (r.fields.checksum == 0)
X goto GoodKey;
X }
X return NULL;
X
X GoodKey:
X date_in_sec = ntohl(r.fields.date);
X date_in_ascii = ctime(&date_in_sec);
X
X sprintf(readable, "%24.24s %u %u.%u.%u.%u %u %u.%u.%u.%u %u",
X date_in_ascii, ntohs(r.fields.uid),
X ((unsigned char *) &r.fields.ip_local)[0],
X ((unsigned char *) &r.fields.ip_local)[1],
X ((unsigned char *) &r.fields.ip_local)[2],
X ((unsigned char *) &r.fields.ip_local)[3],
X (unsigned) ntohs(r.fields.port_local),
X ((unsigned char *) &r.fields.ip_remote)[0],
X ((unsigned char *) &r.fields.ip_remote)[1],
X ((unsigned char *) &r.fields.ip_remote)[2],
X ((unsigned char *) &r.fields.ip_remote)[3],
X (unsigned) ntohs(r.fields.port_remote));
X
X return readable;
}
X
#else
X
#ifndef NeXT31
int dummy = 0; /* Just here to make some compilers shut up :-) */
#endif
X
#endif
SHAR_EOF
$shar_touch -am 0811212996 'pidentd-2.7/src/crypto.c' &&
chmod 0644 'pidentd-2.7/src/crypto.c' ||
$echo 'restore of' 'pidentd-2.7/src/crypto.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/crypto.c:' 'MD5 check failed'
9c200c9560b564b49094a3b9bd4755b9 pidentd-2.7/src/crypto.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/crypto.c'`"
test 5598 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/crypto.c:' 'original size' '5598,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/crypto.h ==============
if test -f 'pidentd-2.7/src/crypto.h' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/crypto.h' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/crypto.h' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/crypto.h' &&
/* Crypto extension to pidentd.
X This file is in the public domain. -- Planar 1994.02.22
X
X Description of the crypto routines.
*/
X
extern void init_encryption ();
extern char *make_packet ();
extern void init_decryption ();
extern char *decrypt_packet ();
SHAR_EOF
$shar_touch -am 0223221794 'pidentd-2.7/src/crypto.h' &&
chmod 0644 'pidentd-2.7/src/crypto.h' ||
$echo 'restore of' 'pidentd-2.7/src/crypto.h' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/crypto.h:' 'MD5 check failed'
53095ade43dc44c261109819928193c1 pidentd-2.7/src/crypto.h
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/crypto.h'`"
test 260 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/crypto.h:' 'original size' '260,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/error.h ==============
if test -f 'pidentd-2.7/src/error.h' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/error.h' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/error.h' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/error.h' &&
/*
** error.h Error handling macros
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 19 Aug 1992
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#ifndef __ERROR_H__
#define __ERROR_H__
X
#include <syslog.h>
X
#define ERROR(fmt) \
X ((syslog_flag ? (syslog(LOG_ERR, fmt),0) : 0), \
X (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
X lport, fport), \
X fprintf(stderr, fmt), perror(": "), 0) : \
X (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
X fflush(stdout), fflush(stderr), exit(1), 0)
X
X
#define ERROR1(fmt,v1) \
X ((syslog_flag ? (syslog(LOG_ERR, fmt, v1),0) : 0), \
X (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
X lport, fport), \
X fprintf(stderr, fmt, v1), perror(": "), 0) : \
X (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
X fflush(stdout), fflush(stderr), exit(1), 0)
X
#define ERROR2(fmt,v1,v2) \
X ((syslog_flag ? (syslog(LOG_ERR, fmt, v1, v2),0) : 0), \
X (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
X lport, fport), \
X fprintf(stderr, fmt, v1, v2), perror(": "), 0) : \
X (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
X fflush(stdout), fflush(stderr), exit(1), 0)
X
#endif
SHAR_EOF
$shar_touch -am 1020144692 'pidentd-2.7/src/error.h' &&
chmod 0644 'pidentd-2.7/src/error.h' ||
$echo 'restore of' 'pidentd-2.7/src/error.h' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/error.h:' 'MD5 check failed'
0061f9794335c5301ab7c0e3f0747e88 pidentd-2.7/src/error.h
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/error.h'`"
test 1416 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/error.h:' 'original size' '1416,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/idecrypt.c ==============
if test -f 'pidentd-2.7/src/idecrypt.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/idecrypt.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/idecrypt.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/idecrypt.c' &&
/*
** idecrypt.c Crypto extension to pidentd.
**
** This file is in the public domain. -- Planar 1994.02.22
**
** Decryption utility.
*/
X
#ifdef INCLUDE_CRYPT
X
#include <stdio.h>
#include "paths.h"
#include "crypto.h"
X
char is_base_64 [] =
{
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
X 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
X 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
};
X
X
void decrypt_file (f)
X FILE *f;
{
X int c;
X int i;
X char buf[32];
X char *cleartext;
X
X while (1)
X {
X c = getc(f);
X
X Same:
X if (c == EOF)
X return;
X
X if (c != '[')
X {
X putchar(c);
X continue;
X }
X
X for (i = 0; i < 32; i++)
X {
X c = getc(f);
X if (c == EOF)
X break;
X if (!is_base_64[c])
X break;
X buf [i] = c;
X }
X
X if (i == 32)
X c = getc(f);
X
X if (i < 32 || c != ']')
X {
X putchar('[');
X fwrite(buf, 1, i, stdout);
X goto Same;
X }
X
X cleartext = decrypt_packet(buf);
X if (cleartext == NULL)
X {
X putchar('[');
X fwrite(buf, 1, 32, stdout);
X putchar(']');
X }
X else
X {
X printf("%s", cleartext);
X }
X }
}
X
main (argc, argv)
X int argc;
X char **argv;
{
X int i;
X FILE *f;
X FILE *key_file;
X
X key_file = fopen(PATH_DESKEY, "r");
X if (key_file == NULL)
X {
X fprintf(stderr, "idecrypt: cannot open key file: ");
X perror(PATH_DESKEY);
X exit (3);
X }
X
X init_decryption(key_file);
X close(key_file);
X
X if (argc < 2)
X {
X decrypt_file(stdin);
X }
X else
X {
X for (i = 1; i < argc; i++)
X {
X if (!strcmp(argv [i], "-"))
X {
X decrypt_file(stdin);
X continue;
X }
X
X f = fopen(argv [i], "r");
X if (f == NULL)
X {
X perror(argv [i]);
X continue;
X }
X
X decrypt_file(f);
X fclose(f);
X }
X }
X
X exit(0);
}
X
#else /* no INCLUDE_CRYPT */
X
#include <stdio.h>
X
int main ()
{
X fprintf(stderr, "idecrypt: compiled without encryption\n");
X exit(2);
}
X
#endif
SHAR_EOF
$shar_touch -am 1103091994 'pidentd-2.7/src/idecrypt.c' &&
chmod 0644 'pidentd-2.7/src/idecrypt.c' ||
$echo 'restore of' 'pidentd-2.7/src/idecrypt.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/idecrypt.c:' 'MD5 check failed'
472bbd6e8e746c2f6ee9364bd82ccd12 pidentd-2.7/src/idecrypt.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/idecrypt.c'`"
test 2220 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/idecrypt.c:' 'original size' '2220,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/identd.c ==============
if test -f 'pidentd-2.7/src/identd.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/identd.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/identd.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/identd.c' &&
/*
** identd.c A TCP/IP link identification protocol server
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 7 Oct 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#if defined(IRIX) || defined(SVR4) || defined(NeXT) || (defined(sco) && sco >= 42) || defined(_AIX4) || defined(__FreeBSD__)
# define SIGRETURN_TYPE void
# define SIGRETURN_TYPE_IS_VOID
#else
# define SIGRETURN_TYPE int
#endif
X
#ifdef SVR4
# define STRNET
#endif
X
#ifdef NeXT31
# include <libc.h>
#endif
X
#ifdef sco
# define USE_SIGALARM
#endif
X
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <fcntl.h>
X
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifndef _AUX_SOURCE
# include <sys/file.h>
#endif
#include <sys/time.h>
#include <sys/wait.h>
X
#include <pwd.h>
#include <grp.h>
X
#include <netinet/in.h>
X
#ifndef HPUX7
# include <arpa/inet.h>
#endif
X
#ifdef _AIX32
# include <sys/select.h>
#endif
X
#if defined(MIPS) || defined(BSD43)
extern int errno;
#endif
X
#if defined(SOLARIS) || defined(__FreeBSD__)
# include <unistd.h>
# include <stdlib.h>
# include <string.h>
#endif
X
#include "identd.h"
#include "error.h"
#include "paths.h"
#include "crypto.h"
X
/* Antique unixes do not have these things defined... */
#ifndef FD_SETSIZE
# define FD_SETSIZE 256
#endif
X
#ifndef FD_SET
# ifndef NFDBITS
# define NFDBITS (sizeof(int) * NBBY) /* bits per mask */
# endif
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#endif
X
#ifndef FD_ZERO
# define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
#endif
X
X
extern void *calloc();
extern void *malloc();
X
X
char *path_unix = NULL;
char *path_kmem = NULL;
X
int verbose_flag = 0;
int debug_flag = 0;
int syslog_flag = 0;
int multi_flag = 0;
int other_flag = 0;
int unknown_flag = 0;
int noident_flag = 0;
int crypto_flag = 0;
X
int lport = 0;
int fport = 0;
X
char *charset_name = NULL;
char *indirect_host = NULL;
char *indirect_password = NULL;
X
#ifdef ALLOW_FORMAT
X int format_flag = 0;
X char *format = "%u";
#endif
X
static int child_pid;
X
#ifdef LOG_DAEMON
static int syslog_facility = LOG_DAEMON;
#endif
X
/*
** The structure passing convention for GCC is incompatible with
** Suns own C compiler, so we define our own inet_ntoa() function.
** (This should only affect GCC version 1 I think, a well, this works
** for version 2 also so why bother.. :-)
*/
#if defined(__GNUC__) && defined(__sparc__) && !defined(NeXT)
X
#ifdef inet_ntoa
#undef inet_ntoa
#endif
X
char *inet_ntoa(ad)
X struct in_addr ad;
{
X unsigned long int s_ad;
X int a, b, c, d;
X static char addr[20];
X
X s_ad = ad.s_addr;
X d = s_ad % 256;
X s_ad /= 256;
X c = s_ad % 256;
X s_ad /= 256;
X b = s_ad % 256;
X a = s_ad / 256;
X sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
X
X return addr;
}
#endif
X
static int comparemem(p1, p2, len)
X unsigned char *p1;
X unsigned char *p2;
X int len;
{
X int c;
X
X while (len-- > 0)
X if ((c = (int) *p1++ - (int) *p2++) != 0)
X return c;
X
X return 0;
}
X
/*
** Return the name of the connecting host, or the IP number as a string.
*/
char *gethost(addr)
X struct in_addr *addr;
{
X int i;
X struct hostent *hp;
X
X
X hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET);
X if (hp)
X {
X /* Found a IP -> Name match, now try the reverse for security reasons */
X hp = gethostbyname(hp->h_name);
X if (hp)
#ifdef h_addr
X for (i = 0; hp->h_addr_list[i]; i++)
X if (comparemem(hp->h_addr_list[i],
X (unsigned char *) addr,
X sizeof(struct in_addr)) == 0)
X return (char *) hp->h_name;
#else
X if (comparemem(hp->h_addr, addr, sizeof(struct in_addr)) == 0)
X return hp->h_name;
#endif
X }
X
X return inet_ntoa(*addr);
}
X
#ifdef USE_SIGALARM
/*
** Exit cleanly after our time's up.
*/
static SIGRETURN_TYPE
alarm_handler(int s)
{
X if (syslog_flag)
X syslog(LOG_DEBUG, "SIGALRM triggered, exiting");
X
X exit(0);
}
#endif
X
X
#if !defined(hpux) && !defined(__hpux) && !defined(SVR4) && \
X !defined(_CRAY) && !defined(sco) && !defined(LINUX)
/*
** This is used to clean up zombie child processes
** if the -w or -b options are used.
*/
static SIGRETURN_TYPE
child_handler()
{
#if defined(NeXT) || (defined(__sgi) && defined(__SVR3))
X union wait status;
#else
X int status;
#endif
X
X while (wait3(&status, WNOHANG, NULL) > 0)
X ;
X
#ifndef SIGRETURN_TYPE_IS_VOID
X return 0;
#endif
}
#endif
X
X
char *clearmem(bp, len)
X char *bp;
X int len;
{
X char *cp;
X
X cp = bp;
X while (len-- > 0)
X *cp++ = 0;
X
X return bp;
}
X
X
/*
** Main entry point into this daemon
*/
int main(argc,argv)
X int argc;
X char *argv[];
{
X int i, len;
X struct sockaddr_in sin;
X struct in_addr laddr, faddr;
#ifndef USE_SIGALARM
X struct timeval tv;
#endif
X int one = 1;
X
X int background_flag = 0;
X int timeout = 0;
X char *portno = "113";
X char *bind_address = NULL;
X int set_uid = 0;
X int set_gid = 0;
X int inhibit_default_config = 0;
X int opt_count = 0; /* Count of option flags */
X
#ifdef __convex__
X argc--; /* get rid of extra argument passed by inetd */
#endif
X
X
X if (isatty(0))
X background_flag = 1;
X
X /*
X ** Prescan the arguments for "-f<config-file>" switches
X */
X inhibit_default_config = 0;
X for (i = 1; i < argc && argv[i][0] == '-'; i++)
X if (argv[i][1] == 'f')
X inhibit_default_config = 1;
X
X /*
X ** Parse the default config file - if it exists
X */
X if (!inhibit_default_config)
X parse_config(NULL, 1);
X
X /*
X ** Parse the command line arguments
X */
X for (i = 1; i < argc && argv[i][0] == '-'; i++) {
X opt_count++;
X switch (argv[i][1])
X {
X case 'b': /* Start as standalone daemon */
X background_flag = 1;
X break;
X
X case 'w': /* Start from Inetd, wait mode */
X background_flag = 2;
X break;
X
X case 'i': /* Start from Inetd, nowait mode */
X background_flag = 0;
X break;
X
X case 't':
X timeout = atoi(argv[i]+2);
X break;
X
X case 'p':
X portno = argv[i]+2;
X break;
X
X case 'a':
X bind_address = argv[i]+2;
X break;
X
X case 'u':
X if (isdigit(argv[i][2]))
X set_uid = atoi(argv[i]+2);
X else
X {
X struct passwd *pwd;
X
X pwd = getpwnam(argv[i]+2);
X if (!pwd)
X ERROR1("no such user (%s) for -u option", argv[i]+2);
X else
X {
X set_uid = pwd->pw_uid;
X set_gid = pwd->pw_gid;
X }
X }
X break;
X
X case 'g':
X if (isdigit(argv[i][2]))
X set_gid = atoi(argv[i]+2);
X else
X {
X struct group *grp;
X
X grp = getgrnam(argv[i]+2);
X if (!grp)
X ERROR1("no such group (%s) for -g option", argv[i]+2);
X else
X set_gid = grp->gr_gid;
X }
X break;
X
X case 'c':
X charset_name = argv[i]+2;
X break;
X
X case 'r':
X indirect_host = argv[i]+2;
X break;
X
X case 'l': /* Use the Syslog daemon for logging */
X syslog_flag++;
X break;
X
X case 'o':
X other_flag = 1;
X break;
X
X case 'e':
X unknown_flag = 1;
X break;
X
X case 'V': /* Give version of this daemon */
X printf("[in.identd, version %s]\r\n", version);
X exit(0);
X break;
X
X case 'v': /* Be verbose */
X verbose_flag++;
X break;
X
X case 'd': /* Enable debugging */
X debug_flag++;
X break;
X
X case 'm': /* Enable multiline queries */
X multi_flag++;
X break;
X
X case 'N': /* Enable users ".noident" files */
X noident_flag++;
X break;
X
#ifdef INCLUDE_CRYPT
X case 'C': /* Enable encryption. */
X {
X FILE *keyfile;
X
X if (argv[i][2])
X keyfile = fopen(argv[i]+2, "r");
X else
X keyfile = fopen(PATH_DESKEY, "r");
X
X if (keyfile == NULL)
X {
X ERROR("cannot open key file for option -C");
X }
X else
X {
X char buf[1024];
X
X if (fgets(buf, 1024, keyfile) == NULL)
X {
X ERROR("cannot read key file for option -C");
X }
X else
X {
X init_encryption(buf);
X crypto_flag++;
X }
X fclose(keyfile);
X }
X }
X break;
#endif
X
#ifdef ALLOW_FORMAT
X case 'n': /* Compatibility flag - just send the user number */
X format_flag = 1;
X format = "%U";
X break;
X
X case 'F': /* Output format */
X format_flag = 1;
X format = argv[i]+2;
X break;
#endif
X
X default:
X ERROR1("Bad option %s", argv[i]);
X break;
X }
X }
X
#if defined(_AUX_SOURCE) || defined (SUNOS35)
X /* A/UX 2.0* & SunOS 3.5 calls us with an argument XXXXXXXX.YYYY
X ** where XXXXXXXXX is the hexadecimal version of the callers
X ** IP number, and YYYY is the port/socket or something.
X ** It seems to be impossible to pass arguments to a daemon started
X ** by inetd.
X **
X ** Just in case it is started from something else, then we only
X ** skip the argument if no option flags have been seen.
X */
X if (opt_count == 0)
X argc--;
#endif
X
X /*
X ** Path to kernel namelist file specified on command line
X */
X if (i < argc)
X path_unix = argv[i++];
X
X /*
X ** Path to kernel memory device specified on command line
X */
X if (i < argc)
X path_kmem = argv[i++];
X
X
X if (i < argc)
X ERROR1("Too many arguments: ignored from %s", argv[i]);
X
X
X /*
X ** We used to call k_open here. But then the file descriptor
X ** kd->fd open on /dev/kmem is shared by all child processes.
X ** From the fork(2) man page:
X ** o The child process has its own copy of the parent's descriptors. These
X ** descriptors reference the same underlying objects. For instance, file
X ** pointers in file objects are shared between the child and the parent
X ** so that an lseek(2) on a descriptor in the child process can affect a
X ** subsequent read(2) or write(2) by the parent.
X ** Thus with concurrent (simultaneous) identd client processes,
X ** they step on each other's toes when they use kvm_read.
X **
X ** Calling k_open here was a mistake for another reason too: we
X ** did not yet honor -u and -g options. Presumably we are
X ** running as root (unless the in.identd file is setuid), and
X ** then we can open kmem regardless of -u and -g values.
X **
X **
X ** Open the kernel memory device and read the nlist table
X **
X ** if (k_open() < 0)
X ** ERROR("main: k_open");
X */
X
X /*
X ** Do the special handling needed for the "-b" flag
X */
X if (background_flag == 1)
X {
X struct sockaddr_in addr;
X struct servent *sp;
X int fd;
X
X
X if (!debug_flag)
X {
X if (fork())
X exit(0);
X
X close(0);
X close(1);
X close(2);
X
X if (fork())
X exit(0);
X }
X
X fd = socket(AF_INET, SOCK_STREAM, 0);
X if (fd == -1)
X ERROR("main: socket");
X
X if (fd != 0)
X dup2(fd, 0);
X
X clearmem((unsigned char *) &addr, sizeof(addr));
X
X addr.sin_family = AF_INET;
X if (bind_address == NULL)
X addr.sin_addr.s_addr = htonl(INADDR_ANY);
X else
X {
X if (isdigit(bind_address[0]))
X addr.sin_addr.s_addr = inet_addr(bind_address);
X else
X {
X struct hostent *hp;
X
X hp = gethostbyname(bind_address);
X if (!hp)
X ERROR1("no such address (%s) for -a switch", bind_address);
X
X /* This is ugly, should use memcpy() or bcopy() but... */
X addr.sin_addr.s_addr = * (unsigned long *) (hp->h_addr);
X }
X }
X
X if (isdigit(portno[0]))
X addr.sin_port = htons(atoi(portno));
X else
X {
X sp = getservbyname(portno, "tcp");
X if (sp == NULL)
X ERROR1("main: getservbyname: %s", portno);
X addr.sin_port = sp->s_port;
X }
X
#ifdef SO_REUSEADDR
X setsockopt(0, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
#endif
X
X if (bind(0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
X ERROR("main: bind");
X
X if (listen(0, 3) < 0)
X ERROR("main: listen");
X }
X
X if (set_gid)
X {
X if (setgid(set_gid) == -1)
X ERROR("main: setgid");
X /* Call me paranoid... PSz */
X if (getgid() != set_gid)
X ERROR2("main: setgid failed: wanted %d, got GID %d", set_gid, getgid());
X if (getegid() != set_gid)
X ERROR2("main: setgid failed: wanted %d, got EGID %d", set_gid, getegid());
X }
X
X if (set_uid)
X {
X if (setuid(set_uid) == -1)
X ERROR("main: setuid");
X /* Call me paranoid... PSz */
X if (getuid() != set_uid)
X ERROR2("main: setuid failed: wanted %d, got UID %d", set_uid, getuid());
X if (geteuid() != set_uid)
X ERROR2("main: setuid failed: wanted %d, got EUID %d", set_uid, geteuid());
X }
X
X /*
X ** Do some special handling if the "-b" or "-w" flags are used
X */
X if (background_flag)
X {
X int nfds, fd;
X fd_set read_set;
X struct sockaddr sad;
X int sadlen;
X
X
X /*
X ** Set up the SIGCHLD signal child termination handler so
X ** that we can avoid zombie processes hanging around and
X ** handle childs terminating before being able to complete the
X ** handshake.
X */
#if (defined(SVR4) || defined(hpux) || defined(__hpux) || defined(IRIX) || \
X defined(_CRAY) || defined(_AUX_SOURCE)) || defined(sco) || defined(LINUX)
X signal(SIGCHLD, SIG_IGN);
#else
X signal(SIGCHLD, (SIGRETURN_TYPE (*)()) child_handler);
#endif
X
X /*
X ** Loop and dispatch client handling processes
X */
X do
X {
#ifdef USE_SIGALARM
X /*
X ** Terminate if we've been idle for 'timeout' seconds
X */
X if (background_flag == 2 && timeout)
X {
X signal(SIGALRM, alarm_handler);
X alarm(timeout);
X }
#endif
X
X /*
X ** Wait for a connection request to occur.
X ** Ignore EINTR (Interrupted System Call).
X */
X do
X {
X FD_ZERO(&read_set);
X FD_SET(0, &read_set);
X
#ifndef USE_SIGALARM
X if (timeout)
X {
X tv.tv_sec = timeout;
X tv.tv_usec = 0;
#ifdef __hpux
X nfds = select(FD_SETSIZE,
X (int *) &read_set, NULL, NULL, &tv);
#else
X nfds = select(FD_SETSIZE, &read_set, NULL, NULL, &tv);
#endif
X }
X else
#endif
X
#ifdef __hpux
X nfds = select(FD_SETSIZE, (int *) &read_set, NULL, NULL, NULL);
#else
X nfds = select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
#endif
X } while (nfds < 0 && errno == EINTR);
X
X /*
X ** An error occured in select? Just die
X */
X if (nfds < 0)
X ERROR("main: select");
X
X /*
X ** Timeout limit reached. Exit nicely
X */
X if (nfds == 0)
X exit(0);
X
#ifdef USE_SIGALARM
X /*
X ** Disable the alarm timeout
X */
X alarm(0);
#endif
X
X /*
X ** Accept the new client
X */
X sadlen = sizeof(sad);
X errno = 0;
X fd = accept(0, &sad, &sadlen);
X if (fd == -1)
X ERROR1("main: accept. errno = %d", errno);
X
X /*
X ** And fork, then close the fd if we are the parent.
X */
X child_pid = fork();
X } while (child_pid && (close(fd), 1));
X
X /*
X ** We are now in child, the parent has returned to "do" above.
X */
X if (dup2(fd, 0) == -1)
X ERROR("main: dup2: failed fd 0");
X
X if (dup2(fd, 1) == -1)
X ERROR("main: dup2: failed fd 1");
X
X if (dup2(fd, 2) == -1)
X ERROR("main: dup2: failed fd 2");
X }
X
X /*
X ** Get foreign internet address
X */
X len = sizeof(sin);
X if (getpeername(0, (struct sockaddr *) &sin, &len) == -1)
X {
X /*
X ** A user has tried to start us from the command line or
X ** the network link died, in which case this message won't
X ** reach to other end anyway, so lets give the poor user some
X ** errors.
X */
X perror("in.identd: getpeername()");
X exit(1);
X }
X
X faddr = sin.sin_addr;
X
X
X /*
X ** Open the connection to the Syslog daemon if requested
X */
X if (syslog_flag)
X {
#ifdef LOG_DAEMON
X openlog("identd", LOG_PID, syslog_facility);
#else
X openlog("identd", LOG_PID);
#endif
X
#ifndef STRONG_LOG
X syslog(LOG_INFO, "Connection from %s", gethost(&faddr));
#endif
X }
X
X
X /*
X ** Get local internet address
X */
X len = sizeof(sin);
#ifdef ATTSVR4
X if (t_getsockname(0, (struct sockaddr *) &sin, &len) == -1)
#else
X if (getsockname(0, (struct sockaddr *) &sin, &len) == -1)
#endif
X {
X /*
X ** We can just die here, because if this fails then the
X ** network has died and we haven't got anyone to return
X ** errors to.
X */
X exit(1);
X }
X laddr = sin.sin_addr;
X
X
X /*
X ** Get the local/foreign port pair from the luser
X */
X parse(stdin, &laddr, &faddr);
X
X exit(0);
}
SHAR_EOF
$shar_touch -am 0527153496 'pidentd-2.7/src/identd.c' &&
chmod 0644 'pidentd-2.7/src/identd.c' ||
$echo 'restore of' 'pidentd-2.7/src/identd.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/identd.c:' 'MD5 check failed'
9b8790698ae70162721b4dc327050059 pidentd-2.7/src/identd.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/identd.c'`"
test 16394 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/identd.c:' 'original size' '16394,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/parse.c ==============
if test -f 'pidentd-2.7/src/parse.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/parse.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/parse.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/parse.c' &&
/*
** parse.c This file contains the protocol parser
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 23 Feb 1994
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#ifdef NeXT31
# include <libc.h>
#endif
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <pwd.h>
#ifdef ALLOW_FORMAT
# include <grp.h>
#endif
X
#include <sys/types.h>
#include <netinet/in.h>
X
#ifndef HPUX7
# include <arpa/inet.h>
#endif
X
#ifdef HAVE_KVM
# include <kvm.h>
#else
# include "kernel/kvm.h"
#endif
X
#include <sys/types.h>
#include <sys/stat.h>
X
#if defined(MIPS) || defined(BSD43)
extern int errno;
#endif
X
#ifdef SOLARIS
# include <string.h>
# include <stdlib.h>
#endif
X
#include "identd.h"
#include "error.h"
#include "crypto.h"
X
extern void *malloc();
X
/*
** This function will eat whitespace characters until
** either a non-whitespace character is read, or EOF
** occurs. This function is only used if the "-m" option
** is enabled.
*/
static int eat_whitespace()
{
X int c;
X
X
X while ((c = getchar()) != EOF &&
X !(c == '\r' || c == '\n'))
X ;
X
X if (c != EOF)
X while ((c = getchar()) != EOF &&
X (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
X ;
X
X if (c != EOF)
X ungetc(c, stdin);
X
X return (c != EOF);
}
X
X
#ifdef INCLUDE_EXTENSIONS
/*
** Validate an indirect request
*/
static int valid_fhost(faddr, password)
X struct in_addr *faddr;
X char *password;
{
X if (indirect_host == NULL)
X return 0;
X
X if (strcmp(indirect_host, "*") != 0)
X {
X if (isdigit(indirect_host[0]))
X {
X if (strcmp(inet_ntoa(*faddr), indirect_host))
X {
X syslog(LOG_NOTICE, "valid_fhost: Access Denied for: %s",
X gethost(faddr));
X return 0;
X }
X }
X else
X {
X if (strcmp(gethost(faddr), indirect_host))
X {
X syslog(LOG_NOTICE, "valid_fhost: Access Denied for: %s",
X gethost(faddr));
X return 0;
X }
X }
X }
X
X if (indirect_password == NULL)
X return 1;
X
X if (strcmp(password, indirect_password))
X {
X syslog(LOG_NOTICE, "valid_fhost: Invalid password from: %s",
X gethost(faddr));
X return 0;
X }
X
X return 1;
}
#endif
X
/*
** A small routine to check for the existance of the ".noident"
** file in a users home directory.
*/
static int check_noident(homedir)
X char *homedir;
{
X char *tmp_path;
X struct stat sbuf;
X int rcode;
X
X
X if (!homedir)
X return 0;
X
X tmp_path = (char *) malloc(strlen(homedir) + sizeof("/.noident") + 1);
X if (!tmp_path)
X return 0;
X
X strcpy(tmp_path, homedir);
X strcat(tmp_path, "/.noident");
X
X rcode = stat(tmp_path, &sbuf);
X free(tmp_path);
X
X return (rcode == 0);
}
X
X
int parse(fp, laddr, faddr)
X FILE *fp;
X struct in_addr *laddr, *faddr;
{
X int uid, try, rcode;
X struct passwd *pwp;
#ifdef ALLOW_FORMAT
X int pid;
X char *cmd, *cmd_and_args;
X struct group *grp;
X char grname[128];
#endif
X char lhostaddr[16];
X char fhostaddr[16];
X char password[33];
#if defined(INCLUDE_EXTENSIONS) || defined(STRONG_LOG)
X char arg[33];
#endif
#ifdef INCLUDE_EXTENSIONS
X extern int proxy();
X int c;
#endif
X struct in_addr laddr2;
X struct in_addr faddr2;
X int k_opened;
X
X k_opened = 0;
X
X
X if (debug_flag && syslog_flag)
X syslog(LOG_DEBUG, "In function parse()");
X
X
X /*
X ** Get the local/foreign port pair from the luser
X */
X do
X {
X if (debug_flag && syslog_flag)
X syslog(LOG_DEBUG, " Before fscanf()");
X
X faddr2 = *faddr;
X laddr2 = *laddr;
X lport = fport = 0;
X lhostaddr[0] = fhostaddr[0] = password[0] = '\0';
X
X
X /* Read query from client */
X rcode = fscanf(fp, " %d , %d", &lport, &fport);
X
#ifdef INCLUDE_EXTENSIONS
X /*
X ** Do additional parsing in case of extended request
X */
X if (rcode == 0)
X {
X rcode = fscanf(fp, "%32[^ \t\n\r:]", arg);
X
X /* Skip leading space up to EOF, EOL or non-space char */
X while ((c = getc(fp)) == ' ' || c == '\t')
X ;
X
X if (rcode <= 0)
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE, "from: %s (%s) INVALID REQUEST",
X inet_ntoa(*faddr), gethost(faddr));
#endif
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
X continue;
X }
X
X /*
X ** Non-standard extended request, returns with Pidentd
X ** version information
X */
X if (strcmp(arg, "VERSION") == 0)
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE, "from: %s (%s) VERSION REQUEST",
X inet_ntoa(*faddr), gethost(faddr));
#endif
#if defined(__TIME__) && defined(__DATE__)
X printf("%d , %d : X-VERSION : %s (Compiled: %s %s)\r\n", lport, fport,
X version, __TIME__, __DATE__);
#else
X printf("%d , %d : X-VERSION : %s\r\n", lport, fport,
X version);
#endif
X continue;
X }
X
X /*
X ** Non-standard extended proxy request
X */
X else if (strcmp(arg, "PROXY") == 0 && c == ':')
X {
X /* We have a colon char, check for port numbers */
X rcode = fscanf(fp, " %d , %d : %15[0-9.] , %15[0-9.]",
X &lport, &fport, fhostaddr, lhostaddr);
X
X if (!(rcode == 3 || rcode == 4))
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE, "from: %s (%s) INVALID PROXY REQUEST",
X inet_ntoa(*faddr), gethost(faddr));
#endif
X
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
X continue;
X }
X
X if (rcode == 4)
X laddr2.s_addr = inet_addr(lhostaddr);
X
X faddr2.s_addr = inet_addr(fhostaddr);
X
#ifdef STRONG_LOG
X if (syslog_flag)
X {
X char a1[64], a2[64], a3[64];
X
X strcpy(a1, inet_ntoa(*faddr));
X strcpy(a2, inet_ntoa(faddr2));
X strcpy(a3, inet_ntoa(laddr2));
X
X syslog(LOG_NOTICE,
X "from: %s (%s) PROXY REQUEST for %d, %d between %s and %s",
X a1, gethost(faddr), lport, fport, a2, a3);
X }
#endif
X
X proxy(&laddr2, &faddr2, lport, fport, NULL);
X continue;
X }
X
X /*
X ** Non-standard extended remote indirect request
X */
X else if (strcmp(arg, "REMOTE") == 0 && c == ':')
X {
X /* We have a colon char, check for port numbers */
X rcode = fscanf(fp, " %d , %d", &lport, &fport);
X
X /* Skip leading space up to EOF, EOL or non-space char */
X while ((c = getc(fp)) == ' ' || c == '\t')
X ;
X
X if (rcode != 2 || c != ':')
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE, "from: %s (%s) INVALID REMOTE REQUEST",
X inet_ntoa(*faddr), gethost(faddr));
#endif
X
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
X continue;
X }
X
X /* We have a colon char, check for addr and password */
X rcode = fscanf(fp, " %15[0-9.] , %32[^ \t\r\n]",
X fhostaddr, password);
X if (rcode > 0)
X rcode += 2;
X else
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE,
X "from: %s (%s) INVALID REMOTE REQUEST for %d, %d",
X inet_ntoa(*faddr), gethost(faddr), lport, fport);
#endif
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
X continue;
X }
X
X /*
X ** Verify that the host originating the indirect request
X ** is allowed to do that
X */
X if (!valid_fhost(faddr, password))
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE,
X "from: %s (%s) REJECTED REMOTE REQUEST for %d, %d with password %s",
X inet_ntoa(*faddr), gethost(faddr), lport, fport,
X password);
#endif
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-ACCESS-DENIED");
X continue;
X }
X
X faddr2.s_addr = inet_addr(fhostaddr);
#ifdef STRONG_LOG
X if (syslog_flag)
X {
X char a1[64];
X
X strcpy(a1, inet_ntoa(*faddr));
X
X syslog(LOG_INFO,
X "from: %s (%s) REMOTE REQUEST for %d, %d from %s with password %s",
X a1, gethost(faddr), lport, fport,
X inet_ntoa(faddr2), password);
X }
#endif
X }
X
X else
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X syslog(LOG_NOTICE, "from: %s (%s) UNKNOWN REQUEST: %s",
X inet_ntoa(*faddr), gethost(faddr), arg);
#endif
X
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
X continue;
X }
X }
#endif /* EXTENSIONS */
X
X if (rcode < 2 || lport < 1 || lport > 65535 || fport < 1 || fport > 65535)
X {
#ifdef STRONG_LOG
X if (syslog_flag)
X {
X if (rcode > 0)
X /* we have scanned at least one correct port */
X syslog(LOG_NOTICE,
X "from: %s (%s) for invalid-port(s): %d , %d",
X inet_ntoa(*faddr), gethost(faddr), lport, fport);
X else
X {
X /* we have scanned nothing at all so try to get the rest */
X if (fscanf(fp, "%32[^\n\r]", arg) <= 0)
X syslog(LOG_NOTICE, "from: %s (%s) EMPTY REQUEST",
X inet_ntoa(*faddr), gethost(faddr));
X else
X syslog(LOG_NOTICE, "from: %s (%s) INVALID REQUEST: %s",
X inet_ntoa(*faddr), gethost(faddr), arg);
X }
X }
#else
X if (syslog_flag && rcode > 0)
X syslog(LOG_NOTICE, "scanf: invalid-port(s): %d , %d from %s",
X lport, fport, gethost(faddr));
#endif
X
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "INVALID-PORT");
X continue;
X }
X
#ifdef STRONG_LOG
X if (syslog_flag)
X {
X syslog(LOG_INFO, "from: %s ( %s ) for: %d, %d",
X inet_ntoa(*faddr), gethost(faddr), lport, fport);
X }
#endif
X
X if (debug_flag && syslog_flag)
X syslog(LOG_DEBUG, " After fscanf(), before k_open()");
X
X
X if (! k_opened)
X {
X /*
X ** Open the kernel memory device and read the nlist table
X **
X ** Of course k_open should not call ERROR (which then exits)
X ** but maybe use syslog(LOG_ERR) and return non-zero. But I am
X ** too lazy to change them all ...
X */
X if (k_open() != 0)
X {
X if (syslog_flag) syslog(LOG_ERR, "k_open call failed");
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "X-CANNOT-OPEN-KMEM");
X continue;
X }
X k_opened = 1;
X }
X
X
X if (debug_flag && syslog_flag)
X syslog(LOG_DEBUG, " After k_open(), before k_getuid()");
X
X
X /*
X ** Get the specific TCP connection and return the uid - user number.
X */
X
#ifdef ALLOW_FORMAT
X /* Initialize values, for architectures that do not set it */
X pid = 0;
X cmd = "";
X cmd_and_args = "";
#endif
X
#define MAX_RETRY 20
X /*
X ** Try to fetch the information MAX_RETRY times in case the
X ** kernel changed beneath us and we missed or took a fault.
X **
X ** Why would we ever fail? Is not there a reliable way for the
X ** kernel to identify its sockets? Cannot we use that interface?
X **
X ** Used to be 5 times, but often this is not enough on Alpha OSF.
X */
/* #define SLEEP_BETWEEN_RETRIES 1 */
X /*
X ** If we failed in k_getuid, that is presumably because the OS was
X ** busy creating or destroying processes. We may want to sleep for
X ** a random time between retries, hoping for peace and quiet.
X */
X
/* k_getuid returns 0 on success, any non-zero on failure. */
X
X for (try = 0;
X (try < MAX_RETRY &&
X k_getuid(&faddr2, htons(fport), laddr, htons(lport), &uid
#ifdef ALLOW_FORMAT
X , &pid, &cmd, &cmd_and_args
#endif
X ) != 0);
X try++)
#ifdef SLEEP_BETWEEN_RETRIES
X {
X /* Seed the generator: lport should be unique (among other concurrent identd's) */
X if (try < 1) srandom(lport);
X /* This gives a max sleep of 0xffff = 65535 microsecs, about 32millisec average */
X usleep(random()&0x00ffff);
X }
#else
X ;
#endif
X
X if (try >= MAX_RETRY)
X {
X if (syslog_flag)
X syslog(LOG_INFO, "Returned: %d , %d : NO-USER", lport, fport);
X
X printf("%d , %d : ERROR : %s\r\n",
X lport, fport,
X unknown_flag ? "UNKNOWN-ERROR" : "NO-USER");
X continue;
X }
X
X if (try > 0 && syslog_flag)
X syslog(LOG_NOTICE, "k_getuid retries: %d", try);
X
X if (debug_flag && syslog_flag)
X syslog(LOG_DEBUG, " After k_getuid(), before getpwuid()");
X
X /*
X ** Then we should try to get the username. If that fails we
X ** return it as an OTHER identifier
X */
X pwp = getpwuid(uid);
X
X if (!pwp || uid != pwp->pw_uid)
X {
X if (syslog_flag)
X syslog(LOG_WARNING, "getpwuid() could not map uid (%d) to name",
X uid);
X
X printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
X lport, fport,
X charset_name ? " , " : "",
X charset_name ? charset_name : "",
X uid);
X continue;
X }
X
#ifdef ALLOW_FORMAT
X grp = getgrgid(pwp->pw_gid);
X if (!grp || pwp->pw_gid != grp->gr_gid)
X {
X if (syslog_flag)
X syslog(LOG_WARNING, "getgrgid() could not map gid (%d) to name (for uid %d, name %s)",
X pwp->pw_gid, uid, pwp->pw_name);
X
X printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
X lport, fport,
X charset_name ? " , " : "",
X charset_name ? charset_name : "",
X uid);
X continue;
X }
X sprintf (grname, "%.99s", grp->gr_name);
#endif
X
X /*
X ** Hey! We finally made it!!!
X */
#ifdef ALLOW_FORMAT
X if (syslog_flag)
X syslog(LOG_DEBUG, "Successful lookup: %d , %d : %s.%s\n",
X lport, fport, pwp->pw_name, grname);
#else
X if (syslog_flag)
X syslog(LOG_DEBUG, "Successful lookup: %d , %d : %s\n",
X lport, fport, pwp->pw_name);
#endif
X
X if (noident_flag && check_noident(pwp->pw_dir))
X {
X if (syslog_flag)
X syslog(LOG_NOTICE, "User %s requested HIDDEN-USER for host %s: %d, %d",
X pwp->pw_name,
X gethost(faddr),
X lport, fport);
X
X printf("%d , %d : ERROR : HIDDEN-USER\r\n",
X lport, fport);
X continue;
X }
X
#ifdef INCLUDE_CRYPT
X if (crypto_flag)
X printf("%d , %d : USERID : OTHER%s%s : [%s]\r\n",
X lport, fport,
X charset_name ? " , " : "",
X charset_name ? charset_name : "",
X make_packet (pwp->pw_uid, laddr, lport, faddr, fport));
X else
#endif
#ifdef ALLOW_FORMAT
X if (format_flag)
X {
X char* cp;
X char** gmp;
X long bp;
X char buff[512];
X for (cp = format, bp = 0; *cp != 0; cp++)
X {
X if (*cp == '%')
X {
X cp++;
X if (*cp == 0) break;
X else if (*cp == 'u') sprintf (&buff[bp], "%.*s", 490-bp, pwp->pw_name);
X else if (*cp == 'U') sprintf (&buff[bp], "%d", pwp->pw_uid);
X else if (*cp == 'g') sprintf (&buff[bp], "%.*s", 490-bp, grname);
X else if (*cp == 'G') sprintf (&buff[bp], "%d", pwp->pw_gid);
X else if (*cp == 'c') sprintf (&buff[bp], "%.*s", 490-bp, cmd);
X else if (*cp == 'C') sprintf (&buff[bp], "%.*s", 490-bp, cmd_and_args);
X else if (*cp == 'l') {
X sprintf (&buff[bp], "%.*s", 490-bp, grname);
X bp += strlen(&buff[bp]); if (bp >= 490) break;
X setgrent();
X while (grp = getgrent()) {
X if (grp->gr_gid == pwp->pw_gid) continue;
X for (gmp = grp->gr_mem; *gmp && **gmp; gmp++) {
X if (! strcmp(*gmp, pwp->pw_name)) {
X sprintf (&buff[bp], ",%.*s", 490-bp, grp->gr_name);
X bp += strlen(&buff[bp]);
X break;
X }
X }
X if (bp >= 490) break;
X }
X endgrent();
X }
X else if (*cp == 'L') {
X sprintf (&buff[bp], "%d", pwp->pw_gid);
X bp += strlen(&buff[bp]); if (bp >= 490) break;
X setgrent();
X while (grp = getgrent()) {
X if (grp->gr_gid == pwp->pw_gid) continue;
X for (gmp = grp->gr_mem; *gmp && **gmp; gmp++) {
X if (! strcmp(*gmp, pwp->pw_name)) {
X sprintf (&buff[bp], ",%d", grp->gr_gid);
X bp += strlen(&buff[bp]);
X break;
X }
X }
X if (bp >= 490) break;
X }
X endgrent();
X }
X else if (*cp == 'p') sprintf (&buff[bp], "%d", pid);
X else { buff[bp] = *cp; buff[bp+1] = 0; }
X bp += strlen(&buff[bp]); if (bp >= 490) break;
X }
X else { buff[bp++] = *cp; if (bp >= 490) break; }
X }
X if (bp >= 490) { sprintf(&buff[490], "..."); bp = 493; }
X buff[bp] = 0;
X printf("%d , %d : USERID : %s%s%s :%s\r\n",
X lport, fport,
X other_flag ? "OTHER" : "UNIX",
X charset_name ? " , " : "",
X charset_name ? charset_name : "",
X buff);
X }
X else
#endif
X printf("%d , %d : USERID : %s%s%s :%s\r\n",
X lport, fport,
X other_flag ? "OTHER" : "UNIX",
X charset_name ? " , " : "",
X charset_name ? charset_name : "",
X pwp->pw_name);
X
X } while(fflush(stdout), fflush(stderr), multi_flag && eat_whitespace());
X
X return 0;
}
SHAR_EOF
$shar_touch -am 0811215696 'pidentd-2.7/src/parse.c' &&
chmod 0644 'pidentd-2.7/src/parse.c' ||
$echo 'restore of' 'pidentd-2.7/src/parse.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/parse.c:' 'MD5 check failed'
d747a642aa66f88d432f7548107018cd pidentd-2.7/src/parse.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/parse.c'`"
test 16271 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/parse.c:' 'original size' '16271,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/identd.h ==============
if test -f 'pidentd-2.7/src/identd.h' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/identd.h' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/identd.h' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/identd.h' &&
/*
** identd.h Common variables for the Pidentd daemon
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 6 Dec 1992
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#ifndef __IDENTD_H__
#define __IDENTD_H__
X
extern char version[];
X
extern char *path_unix;
extern char *path_kmem;
X
extern int verbose_flag;
extern int debug_flag;
extern int syslog_flag;
extern int multi_flag;
extern int other_flag;
extern int unknown_flag;
extern int noident_flag;
extern int crypto_flag;
X
extern char *charset_name;
extern char *indirect_host;
extern char *indirect_password;
X
#ifdef ALLOW_FORMAT
extern int format_flag;
extern char *format;
#endif
X
extern int lport;
extern int fport;
X
extern char *gethost();
X
extern int k_open();
extern int k_getuid();
extern int parse();
extern int parse_config();
X
#endif
SHAR_EOF
$shar_touch -am 1127003895 'pidentd-2.7/src/identd.h' &&
chmod 0644 'pidentd-2.7/src/identd.h' ||
$echo 'restore of' 'pidentd-2.7/src/identd.h' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/identd.h:' 'MD5 check failed'
4a88f8d63ea1e6a5342fc4f05c0b394d pidentd-2.7/src/identd.h
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/identd.h'`"
test 910 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/identd.h:' 'original size' '910,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/itest.c ==============
if test -f 'pidentd-2.7/src/itest.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/itest.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/itest.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/itest.c' &&
/*
X * Simple but effective hack to test the kernel.o file.
X * It takes on stdin the output from "netstat -f inet -n | grep ESTAB"
X * in either Solaris 2.x (non-standard formats can easily be converted
X * to this)
X * laddr.lport faddr.fport .....
X * or BSD 4.x (the defacto standard netstat output):
X * tcp <num> <num> laddr.lport faddr.fport
X * format.
X *
X * The output must be numeric, as non-numeric output is truncated when
X * hostnames get too long and ambiguous. And we don't want netstat to
X * first convert numbers to names and then this program to convert
X * names back to numbers.
X *
X * Casper Dik (cas...@fwi.uva.nl)
X */
#include <stdio.h>
#include <ctype.h>
#ifdef sequent
#include <strings.h>
#define strrchr rindex
#else
#include <string.h>
#include <stdlib.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
X
#include "identd.h"
#include "error.h"
X
X
#ifdef LOG_DAEMON
static int syslog_facility = LOG_DAEMON;
#endif
X
/*
X * To resolve external references that are usually resolved
X * from identd.c
X */
char *path_unix = NULL;
char *path_kmem = NULL;
int lport = 0;
int fport = 0;
X
int debug_flag = 1;
int syslog_flag = 1;
X
X
#ifdef sequent
char *strtok(str, dels)
X char *str;
X char *dels;
{
X static char *bufp;
X
X
X if (str)
X bufp = str;
X
X if (!bufp || !*bufp)
X return (char *) 0;;
X
X while (*bufp && index(dels, *bufp) != (char *) 0)
X ++bufp;
X
X str = bufp;
X
X while (*bufp && index(dels, *bufp) == (char *) 0)
X ++bufp;
X
X if (*bufp)
X *bufp++ = '\0';
X
X return str;
}
#endif
X
int
main()
{
X char buf[500];
X
X /*
X ** Open the connection to the Syslog daemon if requested
X */
X if (syslog_flag)
X {
#ifdef LOG_DAEMON
X openlog("identd_test", LOG_PID, syslog_facility);
#else
X openlog("identd_test", LOG_PID);
#endif
X }
X
X
X if (k_open() < 0) {
X fprintf(stderr,"k_open failed\n");
X exit(1);
X }
X while (fgets(buf,sizeof(buf),stdin)) {
X char *loc, *rem, *tmp;
X unsigned short lport, fport;
X struct in_addr faddr, laddr;
X int uid;
#ifdef ALLOW_FORMAT
X int pid;
X char *cmd, *cmd_and_args;
#endif
X struct passwd *pwd;
X char buf2[sizeof(buf)];
X
X strcpy(buf2,buf);
X
X loc = strtok(buf, " \t");
X if (strcmp(loc,"tcp") == 0) {
X int i;
X for (i = 0; i < 3; i++)
X loc = strtok(NULL, " \t");
X }
X rem = strtok(NULL, " \t");
X if (loc == NULL || rem == NULL) {
X fprintf(stderr,"Malformed line: %s\n", buf2);
X continue;
X }
X /* parse remote, local address */
X tmp = strrchr(loc,'.');
X if (tmp == NULL) {
X fprintf(stderr,"Malformed line: %s\n", buf2);
X continue;
X }
X *tmp++ ='\0';
X laddr.s_addr = inet_addr(loc);
X lport = atoi(tmp);
X
X tmp = strrchr(rem,'.');
X if (tmp == NULL) {
X fprintf(stderr,"Malformed line: %s\n", buf2);
X continue;
X }
X *tmp++ ='\0';
X fport = atoi(tmp);
X faddr.s_addr = inet_addr(rem);
X
X uid = -1;
#ifdef ALLOW_FORMAT
X pid = 0;
X cmd = "unknown";
X cmd_and_args = "unknown";
#endif
X
X if (k_getuid(&faddr, htons(fport), &laddr, htons(lport), &uid
#ifdef ALLOW_FORMAT
X , &pid
X , &cmd
X , &cmd_and_args
#endif
X ) != 0) {
X fprintf(stderr,"*unknown*\t%s\t%d\t\t%s\t%d\n", loc, lport, rem, fport);
X continue;
X }
X
X pwd = getpwuid(uid);
X if (pwd)
X printf("%-8.8s", pwd->pw_name);
X else
X printf("%-8.8d", uid);
#ifdef ALLOW_FORMAT
X printf (" \t%-13s\t%-4d\t%-13s\t%-4d\tPID=%d\tCMD=%s\tCMD+ARG=%s\n", loc, lport, rem, fport, pid, cmd, cmd_and_args);
#else
X printf(" \t%s\t%d\t\t%s\t%d\n", loc, lport, rem, fport);
#endif
X }
X
X return 0;
}
SHAR_EOF
$shar_touch -am 0514014196 'pidentd-2.7/src/itest.c' &&
chmod 0644 'pidentd-2.7/src/itest.c' ||
$echo 'restore of' 'pidentd-2.7/src/itest.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/itest.c:' 'MD5 check failed'
39e0f4b60eb8dbeec16e46a6b239f86e pidentd-2.7/src/itest.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/itest.c'`"
test 3541 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/itest.c:' 'original size' '3541,' 'current size' "$shar_count!"
fi
fi
# ============= pidentd-2.7/src/kernel/386bsd.c ==============
if test ! -d 'pidentd-2.7/src/kernel'; then
$echo 'x -' 'creating directory' 'pidentd-2.7/src/kernel'
mkdir 'pidentd-2.7/src/kernel'
fi
if test -f 'pidentd-2.7/src/kernel/386bsd.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'pidentd-2.7/src/kernel/386bsd.c' '(file already exists)'
else
$echo 'x -' extracting 'pidentd-2.7/src/kernel/386bsd.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'pidentd-2.7/src/kernel/386bsd.c' &&
/*
** kernel/386bsd.c Low level kernel access functions for 386BSD
**
** This program is in the public domain and may be used freely by anyone
** who wants to.
**
** Last update: 17 March 1993
**
** Please send bug fixes/bug reports to: Peter Eriksson <p...@lysator.liu.se>
*/
X
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
X
#include "kvm.h"
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
X
#include <sys/socketvar.h>
X
#define KERNEL
X
#include <sys/file.h>
X
#undef KERNEL
#include <sys/kinfo.h>
X
#include <fcntl.h>
X
#include <sys/user.h>
X
#include <sys/wait.h>
X
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
X
#include <netinet/in_systm.h>
#include <netinet/ip.h>
X
#include <netinet/in_pcb.h>
X
#include <netinet/tcp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
X
#include <arpa/inet.h>
X
#include "identd.h"
#include "error.h"
X
X
extern void *calloc();
extern void *malloc();
X
X
struct nlist nl[] =
{
#define N_FILE 0
#define N_NFILE 1
#define N_TCB 2
X
X { "_filehead" },
X { "_nfiles" },
X { "_tcb" },
X { "" }
};
X
X
static struct file *xfile;
static int nfile;
X
static struct inpcb tcb;
X
#ifdef __bsdi__
static kvm_t *kd;
X
int k_open()
{
X
X /*
X ** Open the kernel memory device
X */
X if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY)) == 0)
X ERROR("main: kvm_open");
X
X /*
X ** Extract offsets to the needed variables in the kernel
X */
X if (kvm_nlist(kd, nl) < 0)
X ERROR("main: kvm_nlist");
X
X return 0;
}
#else
int k_open()
{
X int kd;
X
X /*
X ** Open the kernel memory device
X */
X if ((kd = kvm_openfiles(path_unix, path_kmem, NULL)))
X ERROR("main: kvm_open");
X
X /*
X ** Extract offsets to the needed variables in the kernel
X */
X if (kvm_nlist(nl) < 0)
X ERROR("main: kvm_nlist");
X
X return 0;
}
#endif
X
/*
** Get a piece of kernel memory with error handling.
** Returns 1 if call succeeded, else 0 (zero).
*/
static int getbuf(addr, buf, len, what)
X long addr;
X char *buf;
X int len;
X char *what;
{
#ifdef __bsdi__
X if (kvm_read(kd, addr, buf, len) < 0)
#else
X if (kvm_read(addr, buf, len) < 0)
#endif
X {
X if (syslog_flag)
X syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
X addr, len, what);
X
X return 0;
X }
X
X return 1;
}
X
X
X
/*
** Traverse the inpcb list until a match is found.
** Returns NULL if no match.
*/
static struct socket *
X getlist(pcbp, faddr, fport, laddr, lport)
X struct inpcb *pcbp;
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
{
X struct inpcb *head;
X
X if (!pcbp)
X return NULL;
X
X
X head = pcbp->inp_prev;
X do
X {
X if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
X pcbp->inp_laddr.s_addr == laddr->s_addr &&
X pcbp->inp_fport == fport &&
X pcbp->inp_lport == lport )
X return pcbp->inp_socket;
X } while (pcbp->inp_next != head &&
X getbuf((long) pcbp->inp_next,
X pcbp,
X sizeof(struct inpcb),
X "tcblist"));
X
X return NULL;
}
X
X
X
/*
** Return the user number for the connection owner
*/
int k_getuid(faddr, fport, laddr, lport, uid)
X struct in_addr *faddr;
X int fport;
X struct in_addr *laddr;
X int lport;
X int *uid;
{
X long addr;
X struct socket *sockp;
X int i;
X struct ucred ucb;
X
X /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
X if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
X return -1;
X
X if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
X return -1;
X
X {
X int siz = (nfile+10)*sizeof(struct file);
X xfile = (struct file *) calloc(nfile+10, sizeof(struct file));
X if (!xfile)
X ERROR2("k_getuid: calloc(%d,%d)", nfile+10, sizeof(struct file));
X
X if (!getkerninfo(KINFO_FILE, xfile, &siz, 0))
X {
X ERROR("k_getuid: getkerninfo");
X return -1;
X }
X xfile = (struct file *)((char *)xfile + sizeof(filehead));
X }
X
X /* -------------------- TCP PCB LIST -------------------- */
X if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
X return -1;
X
X tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
X sockp = getlist(&tcb, faddr, fport, laddr, lport);
X
X if (!sockp)
X return -1;
X
X /*
X ** Locate the file descriptor that has the socket in question
X ** open so that we can get the 'ucred' information
X */
X for (i = 0; i < nfile; i++)
X {
X if (xfile[i].f_count == 0)
X continue;
X
X if (xfile[i].f_type == DTYPE_SOCKET &&
X (struct socket *) xfile[i].f_data == sockp)
X {
X if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
X return -1;
X
X *uid = ucb.cr_uid;
X return 0;
X }
X }
X
X return -1;
}
X
SHAR_EOF
$shar_touch -am 1119131693 'pidentd-2.7/src/kernel/386bsd.c' &&
chmod 0644 'pidentd-2.7/src/kernel/386bsd.c' ||
$echo 'restore of' 'pidentd-2.7/src/kernel/386bsd.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'pidentd-2.7/src/kernel/386bsd.c:' 'MD5 check failed'
b1f9922b38cc368eee444d683e3deaf5 pidentd-2.7/src/kernel/386bsd.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pidentd-2.7/src/kernel/386bsd.c'`"
test 4742 -eq "$shar_count" ||
$echo 'pidentd-2.7/src/kernel/386bsd.c:' 'original size' '4742,' 'current size' "$shar_count!"
fi
fi
: || $echo 'restore of' 'pidentd-2.7/src/kernel/4.3bsd.c' 'failed'
$echo 'End of part' '4,' 'continue with part' '5'
exit 0

0 new messages