home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersclub / km / downloads / c_scripts / identdsp.c < prev    next >
C/C++ Source or Header  |  1998-03-25  |  6KB  |  242 lines

  1. /* $Id: identd.c,v 0.1 1994/05/22 21:41:23 qpliu Exp $
  2.  * identd.c by qpliu 1994 -- this program is in the public domain.
  3.  * RFC 1413 ident server using the linux /proc fs.
  4.  * This probably could be done much more simply with perl.
  5.  */
  6.  
  7. /* Aug. 95 - modded by VectorX to accept a file of no more
  8.    then 14 characters on one line, called .fakeid, in the 
  9.    users home directory, which will be substituted for the
  10.    actual identity of the user being looked up. Re-define 
  11.    USERIDFILE and recompile to change he default lookup.
  12.  
  13.    To install just compile, rename /usr/sbin/in.identd to a 
  14.     backup, and replace w/this file.
  15. */
  16.  
  17.  
  18. #include <sys/types.h>
  19. #include <sys/fcntl.h>
  20. #include <sys/socket.h>
  21. #include <sys/time.h>
  22. #include <ctype.h>
  23. #include <netinet/in.h>
  24. #include <pwd.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <unistd.h>
  29.  
  30. /* TIMEOUT is the number of seconds to wait before closing the connection if
  31.  * the client doesn't provide the port pairs.
  32.  */
  33. #define    TIMEOUT    120
  34.  
  35. /* PROCINFO_PATH is where the /proc tcp information is found */
  36. #define    PROCINFO_PATH    "/proc/net/tcp"
  37.  
  38. /* USERIDFILE is the file that can spoof the identd information */
  39. #define USERIDFILE    "/.fakeid"
  40.  
  41. /* PROCINFO_BUFFER_SIZE must be bigger than 80 */
  42. #define    PROCINFO_BUFFER_SIZE    2048
  43. #define    SOCKET_BUFFER_SIZE    100
  44.  
  45. unsigned short lport = 0, rport = 0;
  46.  
  47. #define    INVALID_PORT    0
  48. #define    NO_USER        1
  49. #define    HIDDEN_USER    2
  50. #define    UNKNOWN_ERROR    3
  51.  
  52. char *errors[] = {
  53.     "INVALID-PORT", "NO-USER", "HIDDEN-USER", "UNKNOWN-ERROR"
  54. };
  55.  
  56. void
  57. error (int c)
  58. {
  59.     char str[80];
  60.  
  61.     sprintf (str, "%u , %u : ERROR : %s\r\n", lport, rport, errors[c]);
  62.     write (1, str, strlen (str));
  63.     exit (0);
  64. }
  65.  
  66. void
  67. main ()
  68. {
  69.     struct sockaddr_in sin;
  70.     unsigned long here, there;
  71.     int len = sizeof (sin);
  72.     struct fd_set fdset;
  73.     struct timeval timeout;
  74.     char buffer[PROCINFO_BUFFER_SIZE > SOCKET_BUFFER_SIZE ?
  75.         PROCINFO_BUFFER_SIZE : SOCKET_BUFFER_SIZE];
  76.         char *spoofdir;
  77.     char *spoofid;
  78.     char spoofbuf[14];
  79.  
  80.     int index;
  81.     enum {
  82.     have_neither, have_lport_start, have_lport,
  83.     have_comma, have_rport_start, have_both
  84.     } read_state;
  85.     int fd, spooffd, spooflen;
  86.  
  87.     if (getsockname (0, (struct sockaddr *) &sin, &len) < 0) exit (0);
  88.     here = sin.sin_addr.s_addr;
  89.     if (getpeername (0, (struct sockaddr *) &sin, &len) < 0) exit (0);
  90.     there = sin.sin_addr.s_addr;
  91.  
  92.     /* prepare to read ports */
  93.     FD_ZERO (&fdset);
  94.     FD_SET (0, &fdset);
  95.     timeout.tv_sec = TIMEOUT;
  96.     timeout.tv_usec = 0;
  97.  
  98.     /* read ports from stdin */
  99.     read_state = have_neither;
  100.     index = 0;
  101.     while (read_state != have_both && 1 == select (1, &fdset, NULL, NULL, &timeout)) {
  102.     int i, newindex;
  103.  
  104.     len = read (0, buffer + index, SOCKET_BUFFER_SIZE - index);
  105.     if (len <= 0)
  106.         exit (0);
  107.  
  108.     i = index;
  109.     newindex = 0;
  110.  
  111.     switch (read_state) {
  112.     case have_neither:
  113.         while (i < len + index) {
  114.         if (isdigit (buffer[i])) {
  115.             read_state = have_lport_start;
  116.             break;
  117.         }
  118.         if (!isspace (buffer[i]))
  119.             error (INVALID_PORT);
  120.         i++;
  121.         }
  122.         newindex = i;
  123.         /* fallthrough */
  124.     case have_lport_start:
  125.         while (i < len + index) {
  126.         if (!isdigit (buffer[i])) {
  127.             newindex = atoi (buffer + newindex);
  128.             if (newindex != newindex&0xffff && newindex == 0)
  129.             error (INVALID_PORT);
  130.             lport = newindex;
  131.             read_state = have_lport;
  132.             newindex = i;
  133.             break;
  134.         }
  135.         i++;
  136.         }
  137.         /* fallthrough */
  138.     case have_lport:
  139.         while (i < len + index) {
  140.         if (',' == buffer[i]) {
  141.             read_state = have_comma;
  142.             ++i;
  143.             break;
  144.         }
  145.         if (!isspace (buffer[i]))
  146.             error (INVALID_PORT);
  147.         i++;
  148.         }
  149.         newindex = i;
  150.         /* fallthrough */
  151.     case have_comma:
  152.         while (i < len + index) {
  153.         if (isdigit (buffer[i])) {
  154.             read_state = have_rport_start;
  155.             break;
  156.         }
  157.         if (!isspace (buffer[i]))
  158.             error (INVALID_PORT);
  159.         i++;
  160.         }
  161.         newindex = i;
  162.         /* fallthrough */
  163.     case have_rport_start:
  164.         while (i < len + index) {
  165.         if (!isdigit (buffer[i])) {
  166.             newindex = atoi (buffer + newindex);
  167.             if (newindex != newindex&0xffff && newindex == 0)
  168.             error (INVALID_PORT);
  169.             rport = newindex;
  170.             read_state = have_both;
  171.             newindex = i;
  172.             break;
  173.         }
  174.         i++;
  175.         }
  176.         /* fallthrough */
  177.     }
  178.     index = i - newindex;
  179.     memmove (buffer, buffer + newindex, index);
  180.     FD_SET (0, &fdset);
  181.     }
  182.     if (read_state != have_both) exit (0);
  183.  
  184.     /* get info from /proc/net/tcp */
  185.     fd = open (PROCINFO_PATH, O_RDONLY);
  186.     if (fd < 0)
  187.     error (UNKNOWN_ERROR);
  188.     index = 0;
  189.  
  190.     /* linear search for matching addresses and ports */
  191.     while (0 < (len = read (fd, buffer + index, PROCINFO_BUFFER_SIZE - index))) {
  192.     int i, newindex;
  193.     unsigned long l_here, l_there;
  194.     unsigned short l_rport, l_lport;
  195.     int uid;
  196.  
  197.     newindex = i = 0;
  198.     while (i < len + index) {
  199.         if (sscanf (buffer + i, "%*d: %lx:%hx %lx:%hx %*x %*x:%*x %*x:%*x %*x %d",
  200.             &l_here, &l_lport, &l_there, &l_rport, &uid) == 5) {
  201.         /* /proc/net/tcp displays addresses in net order and
  202.          * ports in host order--how convenient.
  203.          */
  204.         if (here == l_here && lport == l_lport && there == l_there && rport == l_rport) {
  205.             struct passwd *p = getpwuid (uid);
  206.  
  207.             if (NULL == p) error (UNKNOWN_ERROR);
  208.                 
  209.             spoofdir = p->pw_dir;
  210.             strcat(spoofdir, USERIDFILE);
  211.                 spooffd = open(spoofdir, O_RDONLY);
  212.                  if (spooffd < 0) {
  213.                 sprintf (buffer, "%u , %u : USERID : UNIX : %s\r\n",
  214.                  lport, rport, p->pw_name);
  215.             }
  216.             else
  217.             {    
  218.             spooflen = read(spooffd, spoofbuf, sizeof(spoofbuf));
  219.             spoofid = strtok(spoofbuf, "\r\n");
  220.                 sprintf (buffer, "%u , %u : USERID : UNIX : %s\r\n",
  221.                  lport, rport, spoofid);
  222.             }
  223.             write (1, buffer, strlen (buffer));
  224.             exit (0);
  225.         }
  226.         }
  227.         newindex = i;
  228.         while (buffer[i++] != '\n' && i < len + index)
  229.         ;
  230.     }
  231.     index = PROCINFO_BUFFER_SIZE - newindex;
  232.     memmove (buffer, buffer + newindex, index);
  233.     }
  234.     error (NO_USER);
  235. }
  236.  
  237. /* $Log: identd.c,v $
  238.  * Revision 0.1  1994/05/22  21:41:23  qpliu
  239.  * Seems to work.
  240.  *
  241.  */
  242.