home *** CD-ROM | disk | FTP | other *** search
- #define KMEM "/dev/kmem"
- #define VMUNIX "/vmunix"
- #define NETSTAT "/usr/ucb/netstat -n -A -f inet"
- #define NETSTATBUF 200 /* 80 would suffice */
- #define NETSTATREMOTE 49
- #define NETSTATWIDTH 17
- #define REMOTESIZE 100 /* guaranteed to be enough */
-
- #include <stdio.h>
- #include <ctype.h>
- #ifdef USE_SYSLOG
- #include <syslog.h>
- #endif
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #ifdef convex
- #include <sys/ucred.h> /* dorks */
- #define FCRED_ISNOT_POINTER
- #endif
- #define KERNEL
- #include <sys/file.h>
- #undef KERNEL
- #ifdef BSD
- #include <limits.h>
- #endif
- #include <nlist.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #ifdef convex
- #include <sys/mbuf.h>
- #endif
- #include <net/route.h>
- #include <netinet/in.h>
- #include <netinet/in_pcb.h>
- #include <netinet/tcp.h>
- #include <netinet/tcp_fsm.h>
- #include <netinet/tcp_timer.h>
- #include <netinet/tcp_var.h>
- #include <arpa/inet.h>
- #include <pwd.h>
- extern char *calloc();
- extern long lseek();
-
- #define ZAP(x,err) if (x) if (flagauthd) \
- {printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);exit(37);} \
- else { fprintf(stderr,"%s: fatal: %s\n",argv[0],err); exit(37); }
- /* Reporting errors honestly to a remote host could damage security. */
-
- static struct nlist nl[] = { { "_file" }, { "_nfile" }, { "" } };
- #define SFIL 0
- #define SNFILE 1
-
- static char s[NETSTATBUF];
- static char remote[REMOTESIZE];
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- register struct file *xfile;
- register struct file *fp;
- register char *sockloc;
- int nfile;
- struct tcpcb tcp;
- struct inpcb inp;
- struct socket sock;
- struct ucred uc;
- struct file *ftp;
- FILE *fi;
- int fd;
- unsigned long pcbl;
- int pcb;
- int r1; int r2; int r3; int r4; int rp;
- int l1; int l2; int l3; int l4; int lp;
- int uid;
- struct passwd *pw;
- int flagpwnam = 0;
- int flagauthd = 0;
- char localport[10];
- char remoteport[10];
-
- if ((!strcmp(argv[0],"authd"))
- || ((strlen(argv[0]) >= 6)
- && (!strcmp(argv[0] + strlen(argv[0]) - 6,"/authd"))))
- flagauthd = flagpwnam = 1;
- else
- if ((!strcmp(argv[0],"tcpuname"))
- || ((strlen(argv[0]) >= 9)
- && (!strcmp(argv[0] + strlen(argv[0]) - 9,"/tcpuname"))))
- flagpwnam = 1;
-
- if (flagauthd)
- {
- int ch;
- int localportlen;
- int remoteportlen;
- int loop;
- struct sockaddr_in sa;
- int salen;
-
- localportlen = remoteportlen = loop = 0;
-
- while ((ch = getchar()) != ',')
- {
- if (isascii(ch) && isdigit(ch)) localport[localportlen++] = ch;
- if (localportlen == 6) /* tough luck! */ exit(2);
- if ((++loop) > 1000) /* tough luck! */ exit(3);
- }
- while ((ch = getchar()) != '\n')
- {
- if (isascii(ch) && isdigit(ch)) remoteport[remoteportlen++] = ch;
- if (remoteportlen == 6) /* tough luck! */ exit(4);
- if ((++loop) > 1000) /* tough luck! */ exit(5);
- }
-
- localport[localportlen] = remoteport[remoteportlen] = 0;
- lp = atoi(localport);
- rp = atoi(remoteport);
-
- salen = sizeof(sa);
- if (getpeername(0,&sa,&salen) == -1)
- {
- printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
- exit(6);
- }
- r1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
- r2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
- r3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
- r4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
-
- salen = sizeof(sa);
- if (getsockname(0,&sa,&salen) == -1)
- {
- printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
- exit(6);
- }
- l1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
- l2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
- l3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
- l4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
- }
- else
- {
- ZAP(argc < 4,"need four arguments")
- ZAP(sscanf(argv[1],"%d.%d.%d.%d",&r1,&r2,&r3,&r4)<4,"arg 1 must be a.b.c.d")
- ZAP(sscanf(argv[2],"%d",&rp) < 1,"arg 2 must be integer")
- ZAP(sscanf(argv[3],"%d.%d.%d.%d",&l1,&l2,&l3,&l4)<4,"arg 3 must be a.b.c.d")
- ZAP(sscanf(argv[4],"%d",&lp) < 1,"arg 4 must be integer")
- }
-
- (void) sprintf(remote,"%d.%d.%d.%d.%d ",r1,r2,r3,r4,rp);
-
- #ifdef USE_SYSLOG
- /* This isn't worth the time for the procedure call, but if you want... */
- syslog(LOG_DEBUG,"authd: checking up on %d.%d.%d.%d %d %d.%d.%d.%d %d\n",
- r1,r2,r3,r4,rp,l1,l2,l3,l4,lp);
- #endif
-
- nlist(VMUNIX,nl);
- ZAP(!(nl[SNFILE].n_value),"cannot nlist _nfile")
- ZAP(!(nl[SFIL].n_value),"cannot nlist _file")
- fd = open(KMEM,O_RDONLY);
- ZAP(fd == -1,"cannot open kernel memory")
- ZAP(lseek(fd,(long) (nl[SNFILE].n_value),0) == -1,"cannot seek to _nfile")
- ZAP(read(fd,(char *) &nfile,sizeof(nfile)) < sizeof(nfile),"cannot read _nfile")
-
- ZAP(lseek(fd,(long) nl[SFIL].n_value,0) == 1,"cannot seek to _file")
- ZAP(read(fd,(char *) &ftp,sizeof(ftp)) < sizeof(ftp),"cannot read _file")
- ZAP(lseek(fd,(long) ftp,0),"cannot lseek to file table")
- xfile = (struct file *) calloc((unsigned) nfile,sizeof(struct file));
- ZAP(!xfile,"cannot allocate space for copy of file table")
- ZAP(read(fd,(char *) xfile,nfile * sizeof(struct file)) < nfile * sizeof(struct file),"cannot read file table")
-
- fi = popen(NETSTAT,"r");
- ZAP(!fi,"cannot execute netstat")
- ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 1")
- ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 2")
- while (fgets(s,sizeof(s),fi))
- {
- ZAP(sscanf(s,"%8x",&pcb) != 1,"cannot scan netstat pcb address")
- pcbl = pcb;
- if (!strncmp(s + NETSTATREMOTE,remote,NETSTATWIDTH))
- {
- ZAP(lseek(fd,(long) pcbl,0) == -1,"cannot seek to pcb address")
- ZAP(read(fd,(char *) &tcp,sizeof(tcp)) < sizeof(tcp),"cannot read tcp buffer")
- ZAP(!tcp.t_inpcb,"tcp buffer unlinked")
- ZAP(lseek(fd,(long) tcp.t_inpcb,0) == -1,"cannot seek to inpcb address")
- ZAP(read(fd,(char *) &inp,sizeof(inp)) < sizeof(inp),"cannot read inpcb buffer")
- ZAP(inp.inp_ppcb != (char *) pcbl,"inpcb not linked to pcb")
-
- /* Cursed be Convex and the other manufacturers who make this code */
- /* nearly impossible to write with any pretense of portability. */
- if((((char *) &inp.inp_faddr)[0] == (char) r1)
- &&(((char *) &inp.inp_faddr)[1] == (char) r2)
- &&(((char *) &inp.inp_faddr)[2] == (char) r3)
- &&(((char *) &inp.inp_faddr)[3] == (char) r4)
- &&(inp.inp_fport == htons((unsigned short) rp))
- &&(((char *) &inp.inp_laddr)[0] == (char) l1)
- &&(((char *) &inp.inp_laddr)[1] == (char) l2)
- &&(((char *) &inp.inp_laddr)[2] == (char) l3)
- &&(((char *) &inp.inp_laddr)[3] == (char) l4)
- &&(inp.inp_lport == htons((unsigned short) lp))
- )
- {
- sockloc = (char *) inp.inp_socket;
- ZAP(!sockloc,"inp not linked to socket")
- ZAP(lseek(fd,(long) sockloc,0) == -1,"cannot seek to socket address")
- ZAP(read(fd,(char *) &sock,sizeof(sock)) < sizeof(sock),"cannot read socket buffer")
- ZAP(sock.so_pcb != (char *) tcp.t_inpcb,"socket not linked to inpcb")
- for (fp = xfile;fp < xfile + nfile;++fp)
- if (fp->f_count && (fp->f_type == DTYPE_SOCKET))
- if (fp->f_data == sockloc)
- break;
- if (fp != xfile + nfile)
- {
- #ifdef FCRED_ISNOT_POINTER
- uid = (int) fp->f_cred.cr_ruid;
- #else
- ZAP(lseek(fd,(long) (fp->f_cred),0) == -1,"cannot seek to credentials")
- ZAP(read(fd,(char *) &uc,sizeof(uc)) < sizeof(uc),"cannot read credentials")
- uid = (int) uc.cr_ruid;
- #endif
- if (flagpwnam)
- {
- pw = getpwuid(uid);
- ZAP(!pw,"cannot get password entry")
- if (flagauthd)
- /* UNIX is a trademark of AT&T. :-) */
- printf("%s, %s: USERID: UNIX: %s\r\n"
- ,localport,remoteport,pw->pw_name);
- else
- printf("%s\n",pw->pw_name);
- }
- else
- printf("%d\n",uid);
- exit(0);
- }
- }
- }
- }
- ZAP(1,"no such TCP connection")
- exit(1);
- }
-