home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2684 / authd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-07  |  7.7 KB  |  246 lines

  1. #define KMEM "/dev/kmem"
  2. #define VMUNIX "/vmunix"
  3. #define NETSTAT "/usr/ucb/netstat -n -A -f inet"
  4. #define NETSTATBUF 200 /* 80 would suffice */
  5. #define NETSTATREMOTE 49
  6. #define NETSTATWIDTH 17
  7. #define REMOTESIZE 100 /* guaranteed to be enough */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #ifdef USE_SYSLOG
  12. #include <syslog.h>
  13. #endif
  14. #include <sys/types.h>
  15. #include <sys/param.h>
  16. #include <sys/dir.h>
  17. #include <sys/user.h>
  18. #ifdef convex
  19. #include <sys/ucred.h> /* dorks */
  20. #define FCRED_ISNOT_POINTER
  21. #endif
  22. #define KERNEL
  23. #include <sys/file.h>
  24. #undef KERNEL
  25. #ifdef BSD
  26. #include <limits.h>
  27. #endif
  28. #include <nlist.h>
  29. #include <sys/socket.h>
  30. #include <sys/socketvar.h>
  31. #ifdef convex
  32. #include <sys/mbuf.h>
  33. #endif
  34. #include <net/route.h>
  35. #include <netinet/in.h>
  36. #include <netinet/in_pcb.h>
  37. #include <netinet/tcp.h>
  38. #include <netinet/tcp_fsm.h>
  39. #include <netinet/tcp_timer.h>
  40. #include <netinet/tcp_var.h>
  41. #include <arpa/inet.h>
  42. #include <pwd.h>
  43. extern char *calloc();
  44. extern long lseek();
  45.  
  46. #define ZAP(x,err) if (x) if (flagauthd) \
  47. {printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);exit(37);} \
  48. else { fprintf(stderr,"%s: fatal: %s\n",argv[0],err); exit(37); }
  49. /* Reporting errors honestly to a remote host could damage security. */
  50.  
  51. static struct nlist nl[] = { { "_file" }, { "_nfile" }, { "" } };
  52. #define SFIL 0
  53. #define SNFILE 1
  54.  
  55. static char s[NETSTATBUF];
  56. static char remote[REMOTESIZE];
  57.  
  58. main(argc,argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.  register struct file *xfile;
  63.  register struct file *fp;
  64.  register char *sockloc;
  65.  int nfile;
  66.  struct tcpcb tcp;
  67.  struct inpcb inp;
  68.  struct socket sock;
  69.  struct ucred uc;
  70.  struct file *ftp;
  71.  FILE *fi;
  72.  int fd;
  73.  unsigned long pcbl;
  74.  int pcb;
  75.  int r1; int r2; int r3; int r4; int rp;
  76.  int l1; int l2; int l3; int l4; int lp;
  77.  int uid;
  78.  struct passwd *pw;
  79.  int flagpwnam = 0;
  80.  int flagauthd = 0;
  81.  char localport[10];
  82.  char remoteport[10];
  83.  
  84.  if ((!strcmp(argv[0],"authd"))
  85.   || ((strlen(argv[0]) >= 6)
  86.    && (!strcmp(argv[0] + strlen(argv[0]) - 6,"/authd"))))
  87.    flagauthd = flagpwnam = 1;
  88.  else
  89.    if ((!strcmp(argv[0],"tcpuname"))
  90.     || ((strlen(argv[0]) >= 9)
  91.      && (!strcmp(argv[0] + strlen(argv[0]) - 9,"/tcpuname"))))
  92.      flagpwnam = 1;
  93.  
  94.  if (flagauthd)
  95.   {
  96.    int ch;
  97.    int localportlen;
  98.    int remoteportlen;
  99.    int loop;
  100.    struct sockaddr_in sa;
  101.    int salen;
  102.  
  103.    localportlen = remoteportlen = loop = 0;
  104.  
  105.    while ((ch = getchar()) != ',')
  106.     {
  107.      if (isascii(ch) && isdigit(ch)) localport[localportlen++] = ch;
  108.      if (localportlen == 6) /* tough luck! */ exit(2);
  109.      if ((++loop) > 1000) /* tough luck! */ exit(3);
  110.     }
  111.    while ((ch = getchar()) != '\n')
  112.     {
  113.      if (isascii(ch) && isdigit(ch)) remoteport[remoteportlen++] = ch;
  114.      if (remoteportlen == 6) /* tough luck! */ exit(4);
  115.      if ((++loop) > 1000) /* tough luck! */ exit(5);
  116.     }
  117.  
  118.    localport[localportlen] = remoteport[remoteportlen] = 0;
  119.    lp = atoi(localport);
  120.    rp = atoi(remoteport);
  121.  
  122.    salen = sizeof(sa);
  123.    if (getpeername(0,&sa,&salen) == -1)
  124.     {
  125.      printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
  126.      exit(6);
  127.     }
  128.    r1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
  129.    r2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
  130.    r3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
  131.    r4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
  132.  
  133.    salen = sizeof(sa);
  134.    if (getsockname(0,&sa,&salen) == -1)
  135.     {
  136.      printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
  137.      exit(6);
  138.     }
  139.    l1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
  140.    l2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
  141.    l3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
  142.    l4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
  143.   }
  144.  else
  145.   {
  146.    ZAP(argc < 4,"need four arguments")
  147.    ZAP(sscanf(argv[1],"%d.%d.%d.%d",&r1,&r2,&r3,&r4)<4,"arg 1 must be a.b.c.d")
  148.    ZAP(sscanf(argv[2],"%d",&rp) < 1,"arg 2 must be integer")
  149.    ZAP(sscanf(argv[3],"%d.%d.%d.%d",&l1,&l2,&l3,&l4)<4,"arg 3 must be a.b.c.d")
  150.    ZAP(sscanf(argv[4],"%d",&lp) < 1,"arg 4 must be integer")
  151.   }
  152.  
  153.  (void) sprintf(remote,"%d.%d.%d.%d.%d                    ",r1,r2,r3,r4,rp);
  154.  
  155. #ifdef USE_SYSLOG
  156.  /* This isn't worth the time for the procedure call, but if you want... */
  157.  syslog(LOG_DEBUG,"authd: checking up on %d.%d.%d.%d %d %d.%d.%d.%d %d\n",
  158.    r1,r2,r3,r4,rp,l1,l2,l3,l4,lp);
  159. #endif
  160.  
  161.  nlist(VMUNIX,nl);
  162.  ZAP(!(nl[SNFILE].n_value),"cannot nlist _nfile")
  163.  ZAP(!(nl[SFIL].n_value),"cannot nlist _file")
  164.  fd = open(KMEM,O_RDONLY);
  165.  ZAP(fd == -1,"cannot open kernel memory")
  166.  ZAP(lseek(fd,(long) (nl[SNFILE].n_value),0) == -1,"cannot seek to _nfile")
  167.  ZAP(read(fd,(char *) &nfile,sizeof(nfile)) < sizeof(nfile),"cannot read _nfile")
  168.  
  169.  ZAP(lseek(fd,(long) nl[SFIL].n_value,0) == 1,"cannot seek to _file")
  170.  ZAP(read(fd,(char *) &ftp,sizeof(ftp)) < sizeof(ftp),"cannot read _file")
  171.  ZAP(lseek(fd,(long) ftp,0),"cannot lseek to file table")
  172.  xfile = (struct file *) calloc((unsigned) nfile,sizeof(struct file));
  173.  ZAP(!xfile,"cannot allocate space for copy of file table")
  174.  ZAP(read(fd,(char *) xfile,nfile * sizeof(struct file)) < nfile * sizeof(struct file),"cannot read file table")
  175.  
  176.  fi = popen(NETSTAT,"r");
  177.  ZAP(!fi,"cannot execute netstat")
  178.  ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 1")
  179.  ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 2")
  180.  while (fgets(s,sizeof(s),fi))
  181.   {
  182.    ZAP(sscanf(s,"%8x",&pcb) != 1,"cannot scan netstat pcb address")
  183.    pcbl = pcb;
  184.    if (!strncmp(s + NETSTATREMOTE,remote,NETSTATWIDTH))
  185.     {
  186.      ZAP(lseek(fd,(long) pcbl,0) == -1,"cannot seek to pcb address")
  187.      ZAP(read(fd,(char *) &tcp,sizeof(tcp)) < sizeof(tcp),"cannot read tcp buffer")
  188.      ZAP(!tcp.t_inpcb,"tcp buffer unlinked")
  189.      ZAP(lseek(fd,(long) tcp.t_inpcb,0) == -1,"cannot seek to inpcb address")
  190.      ZAP(read(fd,(char *) &inp,sizeof(inp)) < sizeof(inp),"cannot read inpcb buffer")
  191.      ZAP(inp.inp_ppcb != (char *) pcbl,"inpcb not linked to pcb")
  192.  
  193. /* Cursed be Convex and the other manufacturers who make this code */
  194. /* nearly impossible to write with any pretense of portability. */
  195.      if((((char *) &inp.inp_faddr)[0] == (char) r1)
  196.       &&(((char *) &inp.inp_faddr)[1] == (char) r2)
  197.       &&(((char *) &inp.inp_faddr)[2] == (char) r3)
  198.       &&(((char *) &inp.inp_faddr)[3] == (char) r4)
  199.       &&(inp.inp_fport == htons((unsigned short) rp))
  200.       &&(((char *) &inp.inp_laddr)[0] == (char) l1)
  201.       &&(((char *) &inp.inp_laddr)[1] == (char) l2)
  202.       &&(((char *) &inp.inp_laddr)[2] == (char) l3)
  203.       &&(((char *) &inp.inp_laddr)[3] == (char) l4)
  204.       &&(inp.inp_lport == htons((unsigned short) lp))
  205.      )
  206.       {
  207.        sockloc = (char *) inp.inp_socket;
  208.        ZAP(!sockloc,"inp not linked to socket")
  209.        ZAP(lseek(fd,(long) sockloc,0) == -1,"cannot seek to socket address")
  210.        ZAP(read(fd,(char *) &sock,sizeof(sock)) < sizeof(sock),"cannot read socket buffer")
  211.        ZAP(sock.so_pcb != (char *) tcp.t_inpcb,"socket not linked to inpcb")
  212.        for (fp = xfile;fp < xfile + nfile;++fp)
  213.      if (fp->f_count && (fp->f_type == DTYPE_SOCKET))
  214.        if (fp->f_data == sockloc)
  215.          break;
  216.        if (fp != xfile + nfile)
  217.     {
  218. #ifdef FCRED_ISNOT_POINTER
  219.          uid = (int) fp->f_cred.cr_ruid;
  220. #else
  221.          ZAP(lseek(fd,(long) (fp->f_cred),0) == -1,"cannot seek to credentials")
  222.          ZAP(read(fd,(char *) &uc,sizeof(uc)) < sizeof(uc),"cannot read credentials")
  223.          uid = (int) uc.cr_ruid;
  224. #endif
  225.      if (flagpwnam)
  226.       {
  227.        pw = getpwuid(uid);
  228.        ZAP(!pw,"cannot get password entry")
  229.        if (flagauthd)
  230.          /* UNIX is a trademark of AT&T. :-) */
  231.              printf("%s, %s: USERID: UNIX: %s\r\n"
  232.             ,localport,remoteport,pw->pw_name);
  233.        else
  234.          printf("%s\n",pw->pw_name);
  235.       }
  236.      else
  237.        printf("%d\n",uid);
  238.          exit(0);
  239.     }
  240.       }
  241.     }
  242.   }
  243.  ZAP(1,"no such TCP connection")
  244.  exit(1);
  245. }
  246.