home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / pidentd-2.2 / src / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-11  |  8.5 KB  |  404 lines

  1. /*
  2. ** parse.c                         This file contains the protocol parser
  3. **
  4. ** This program is in the public domain and may be used freely by anyone
  5. ** who wants to. 
  6. **
  7. ** Last update: 6 Dec 1992
  8. **
  9. ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
  10. */
  11.  
  12. #ifdef NeXT31
  13. #  include <libc.h>
  14. #endif
  15.  
  16. #include <stdio.h>
  17. #include <errno.h>
  18. #include <ctype.h>
  19. #include <pwd.h>
  20.  
  21. #include <sys/types.h>
  22. #include <netinet/in.h>
  23.  
  24. #ifndef HPUX7
  25. #  include <arpa/inet.h>
  26. #endif
  27.  
  28. #ifdef HAVE_KVM
  29. #  include <kvm.h>
  30. #else
  31. #  include "kvm.h"
  32. #endif
  33.  
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36.  
  37. #if defined(MIPS) || defined(BSD43)
  38. extern int errno;
  39. #endif
  40.  
  41. #include "identd.h"
  42. #include "error.h"
  43.  
  44. extern void *malloc();
  45.  
  46. /*
  47. ** This function will eat whitespace characters until
  48. ** either a non-whitespace character is read, or EOF
  49. ** occurs. This function is only used if the "-m" option
  50. ** is enabled.
  51. */
  52. static int eat_whitespace()
  53. {
  54.   int c;
  55.  
  56.   
  57.   while ((c = getchar()) != EOF &&
  58.      !(c == '\r' || c == '\n'))
  59.     ;
  60.  
  61.   if (c != EOF)
  62.     while ((c = getchar()) != EOF &&
  63.        (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
  64.       ;
  65.  
  66.   if (c != EOF)
  67.     ungetc(c, stdin);
  68.   
  69.   return (c != EOF);
  70. }
  71.  
  72.  
  73. #ifdef INCLUDE_EXTENSIONS
  74. /*
  75. ** Validate an indirect request
  76. */
  77. static int valid_fhost(faddr, password)
  78.   struct in_addr *faddr;
  79.   char *password;
  80. {
  81.   if (indirect_host == NULL)
  82.     return 0;
  83.  
  84.   if (strcmp(indirect_host, "*") != 0)
  85.   {
  86.     if (isdigit(indirect_host[0]))
  87.     {
  88.       if (strcmp(inet_ntoa(*faddr), indirect_host))
  89.       {
  90.     syslog(LOG_NOTICE, "valid_fhost: Access Denied for: %s",
  91.            gethost(faddr));
  92.     return 0;
  93.       }
  94.     }
  95.     else
  96.     {
  97.       if (strcmp(gethost(faddr), indirect_host))
  98.       {
  99.     syslog(LOG_NOTICE, "valid_fhost: Access Denied for: %s",
  100.            gethost(faddr));
  101.     return 0;
  102.       }
  103.     }
  104.   }
  105.       
  106.   if (indirect_password == NULL)
  107.     return 1;
  108.   
  109.   if (strcmp(password, indirect_password))
  110.   {
  111.     syslog(LOG_NOTICE, "valid_fhost: Invalid password from: %s",
  112.        gethost(faddr));
  113.     return 0;
  114.   }
  115.  
  116.   return 1;
  117. }
  118. #endif
  119.  
  120. /*
  121. ** A small routine to check for the existance of the ".noident"
  122. ** file in a users home directory.
  123. */
  124. static int check_noident(homedir)
  125.   char *homedir;
  126. {
  127.   char *tmp_path;
  128.   struct stat sbuf;
  129.   int rcode;
  130.   
  131.  
  132.   if (!homedir)
  133.     return 0;
  134.   
  135.   tmp_path = (char *) malloc(strlen(homedir) + sizeof("/.noident") + 1);
  136.   if (!tmp_path)
  137.     return 0;
  138.  
  139.   strcpy(tmp_path, homedir);
  140.   strcat(tmp_path, "/.noident");
  141.  
  142.   rcode = stat(tmp_path, &sbuf);
  143.   free(tmp_path);
  144.  
  145.   return (rcode == 0);
  146. }
  147.  
  148.  
  149. int parse(fp, laddr, faddr)
  150.   FILE *fp;
  151.   struct in_addr *laddr, *faddr;
  152. {
  153.   int uid, try, rcode;
  154.   struct passwd *pwp;
  155.   char lhostaddr[16];
  156.   char fhostaddr[16];
  157.   char password[33];
  158. #ifdef INCLUDE_EXTENSIONS  
  159.   char arg[33];
  160.   int c;
  161. #endif
  162.   struct in_addr laddr2;
  163.   struct in_addr faddr2;
  164.   
  165.   
  166.   if (debug_flag && syslog_flag)
  167.     syslog(LOG_DEBUG, "In function parse()");
  168.   
  169.   /*
  170.   ** Get the local/foreign port pair from the luser
  171.   */
  172.   do
  173.   {
  174.     if (debug_flag && syslog_flag)
  175.       syslog(LOG_DEBUG, "  Before fscanf()");
  176.     
  177.     faddr2 = *faddr;
  178.     laddr2 = *laddr;
  179.     lport = fport = 0;
  180.     lhostaddr[0] = fhostaddr[0] = password[0] = '\0';
  181.  
  182.     /* Read query from client */
  183.     rcode = fscanf(fp, " %d , %d", &lport, &fport);
  184.  
  185. #ifdef INCLUDE_EXTENSIONS
  186.     /*
  187.     ** Do additional parsing in case of extended request
  188.     */
  189.     if (rcode == 0)
  190.     {
  191.       rcode = fscanf(fp, "%32[^ \t\n\r:]", arg);
  192.  
  193.       /* Skip leading space up to EOF, EOL or non-space char */
  194.       while ((c = getc(fp)) == ' ' || c == '\t')
  195.     ;
  196.       
  197.       if (rcode <= 0)
  198.       {
  199.     printf("%d , %d : ERROR : %s\r\n",
  200.            lport, fport,
  201.            unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
  202.     continue;
  203.       }
  204.  
  205.       /*
  206.       ** Non-standard extended request, returns with Pidentd
  207.       ** version information
  208.       */
  209.       if (strcmp(arg, "VERSION") == 0)
  210.       {
  211.     printf("%d , %d : ERROR : X-VERSION : %s\r\n", lport, fport,
  212.            version);
  213.     continue;
  214.       }
  215.  
  216.       /*
  217.       ** Non-standard extended proxy request
  218.       */
  219.       else if (strcmp(arg, "PROXY") == 0 && c == ':')
  220.       {
  221.     /* We have a colon char, check for port numbers */
  222.     rcode = fscanf(fp, " %d , %d : %15[0-9.] , %15[0-9.]",
  223.                &lport, &fport, fhostaddr, lhostaddr);
  224.  
  225.     if (!(rcode == 3 || rcode == 4))
  226.     {
  227.       printf("%d , %d : ERROR : %s\r\n",
  228.          lport, fport,
  229.          unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
  230.       continue;
  231.     }
  232.  
  233.     if (rcode == 4)
  234.       laddr2.s_addr = inet_addr(lhostaddr);
  235.     
  236.     faddr2.s_addr = inet_addr(fhostaddr);
  237.  
  238.     proxy(&laddr2, &faddr2, lport, fport, NULL);
  239.     continue;
  240.       }
  241.       
  242.       /*
  243.       ** Non-standard extended remote indirect request
  244.       */
  245.       else if (strcmp(arg, "REMOTE") == 0 && c == ':')
  246.       {
  247.     /* We have a colon char, check for port numbers */
  248.     rcode = fscanf(fp, " %d , %d", &lport, &fport);
  249.     
  250.     /* Skip leading space up to EOF, EOL or non-space char */
  251.     while ((c = getc(fp)) == ' ' || c == '\t')
  252.       ;
  253.  
  254.     if (rcode != 2 || c != ':')
  255.     {
  256.       printf("%d , %d : ERROR : %s\r\n",
  257.          lport, fport,
  258.          unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
  259.       continue;
  260.     }
  261.         
  262.     /* We have a colon char, check for addr and password */
  263.     rcode = fscanf(fp, " %15[0-9.] , %32[^ \t\r\n]",
  264.                fhostaddr, password);
  265.     if (rcode > 0)
  266.       rcode += 2;
  267.     else
  268.     {
  269.       printf("%d , %d : ERROR : %s\r\n",
  270.          lport, fport,
  271.          unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
  272.       continue;
  273.     }
  274.     
  275.     /*
  276.     ** Verify that the host originating the indirect request
  277.     ** is allowed to do that
  278.     */
  279.     if (!valid_fhost(faddr, password))
  280.     {
  281.       printf("%d , %d : ERROR : %s\r\n",
  282.          lport, fport,
  283.          unknown_flag ? "UNKNOWN-ERROR" : "X-ACCESS-DENIED");
  284.       continue;
  285.     }
  286.     
  287.     faddr2.s_addr = inet_addr(fhostaddr);
  288.       }
  289.       
  290.       else
  291.       {
  292.     printf("%d , %d : ERROR : %s\r\n",
  293.            lport, fport,
  294.            unknown_flag ? "UNKNOWN-ERROR" : "X-INVALID-REQUEST");
  295.     continue;
  296.       }
  297.     }
  298. #endif /* EXTENSIONS */
  299.     
  300.     if (rcode < 2 || lport < 1 || lport > 65535 || fport < 1 || fport > 65535)
  301.     {
  302.       if (syslog_flag && rcode > 0)
  303.     syslog(LOG_NOTICE, "scanf: invalid-port(s): %d , %d from %s",
  304.            lport, fport, gethost(faddr));
  305.       
  306.       printf("%d , %d : ERROR : %s\r\n",
  307.          lport, fport,
  308.          unknown_flag ? "UNKNOWN-ERROR" : "INVALID-PORT");
  309.       continue;
  310.     }
  311.  
  312.     if (debug_flag && syslog_flag)
  313.       syslog(LOG_DEBUG, "  After fscanf(), before k_getuid()");
  314.     
  315.     /*
  316.     ** Next - get the specific TCP connection and return the
  317.     ** uid - user number.
  318.     **
  319.     ** Try to fetch the information 5 times incase the
  320.     ** kernel changed beneath us and we missed or took
  321.     ** a fault.
  322.     */
  323.     for (try = 0;
  324.      (try < 5 &&
  325.        k_getuid(&faddr2, htons(fport), laddr, htons(lport), &uid) == -1);
  326.      try++)
  327.       ;
  328.  
  329.     if (try >= 5)
  330.     {
  331.       if (syslog_flag)
  332.     syslog(LOG_DEBUG, "Returned: %d , %d : NO-USER", lport, fport);
  333.       
  334.       printf("%d , %d : ERROR : %s\r\n",
  335.          lport, fport,
  336.          unknown_flag ? "UNKNOWN-ERROR" : "NO-USER");
  337.       continue;
  338.     }
  339.  
  340.     if (try > 0 && syslog_flag)
  341.       syslog(LOG_NOTICE, "k_getuid retries: %d", try);
  342.     
  343.     if (debug_flag && syslog_flag)
  344.       syslog(LOG_DEBUG, "  After k_getuid(), before getpwuid()");
  345.  
  346.     /*
  347.     ** Then we should try to get the username. If that fails we
  348.     ** return it as an OTHER identifier
  349.     */
  350.     pwp = getpwuid(uid);
  351.     
  352.     if (!pwp)
  353.     {
  354.       if (syslog_flag)
  355.     syslog(LOG_WARNING, "getpwuid() could not map uid (%d) to name",
  356.            uid);
  357.  
  358.       printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
  359.          lport, fport,
  360.          charset_name ? " , " : "",
  361.          charset_name ? charset_name : "",
  362.          uid);
  363.       continue;
  364.     }
  365.  
  366.     /*
  367.     ** Hey! We finally made it!!!
  368.     */
  369.     if (syslog_flag)
  370.       syslog(LOG_DEBUG, "Successful lookup: %d , %d : %s\n",
  371.          lport, fport, pwp->pw_name);
  372.  
  373.     if (noident_flag && check_noident(pwp->pw_dir))
  374.     {
  375.       if (syslog_flag)
  376.     syslog(LOG_NOTICE, "User %s requested HIDDEN-USER for host %s: %d, %d",
  377.            pwp->pw_name,
  378.            gethost(faddr),
  379.            lport, fport);
  380.       
  381.       printf("%d , %d : ERROR : HIDDEN-USER\r\n",
  382.        lport, fport);
  383.       continue;
  384.     }
  385.  
  386.     if (number_flag)
  387.       printf("%d , %d : USERID : OTHER%s%s : %d\r\n",
  388.          lport, fport,
  389.          charset_name ? " , " : "",
  390.          charset_name ? charset_name : "",
  391.          uid);
  392.     else
  393.       printf("%d , %d : USERID : %s%s%s : %s\r\n",
  394.          lport, fport,
  395.          other_flag ? "OTHER" : "UNIX",
  396.          charset_name ? " , " : "",
  397.          charset_name ? charset_name : "",
  398.          pwp->pw_name);
  399.     
  400.   } while(fflush(stdout), fflush(stderr), multi_flag && eat_whitespace());
  401.  
  402.   return 0;
  403. }
  404.