home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / SRS / server / src / sockets.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-12  |  8.6 KB  |  362 lines

  1. #include "headers.h" /* includes all important stuff */
  2.  
  3. /* this binds and listens for a client..  */
  4. void initconn()
  5. {
  6.    curPid = 0;
  7.  
  8.    if (mainfd > 0)
  9.    {
  10.       close(mainfd);
  11.       mainfd = 0;
  12.    }
  13.  
  14.    mainfd = socket(AF_INET, SOCK_STREAM, 0);
  15.    if (mainfd == ERROR)
  16.    {
  17.       error("error with socket(): %s\n\n", strerror(errno));
  18.       quit(ERROR);
  19.    }
  20.  
  21.    setsockopts();
  22.    
  23.    laddr.sin_family = AF_INET;
  24.    laddr.sin_port = htons(locPort); 
  25.    laddr.sin_addr.s_addr = INADDR_ANY;
  26.    memset(&laddr.sin_zero, 0, sizeof(laddr.sin_zero)); 
  27.  
  28.    while(1)
  29.    {
  30.       if (bind(mainfd, (struct sockaddr *) &laddr, 
  31.                sizeof(struct sockaddr)) == ERROR)
  32.       {
  33.          if (errno == EINTR) continue;
  34.          error("error with bind(): %s\n\n", strerror(errno));
  35.  
  36.          (void)sleep(MAXPAUSE * 3);
  37.       } 
  38.  
  39.       else break;
  40.    }
  41.  
  42.    if (listen(mainfd, MAXCONNS) == ERROR) 
  43.    {
  44.       error("error with listen(): %s\n\n", strerror(errno));
  45.       quit(ERROR);
  46.    }
  47. }
  48.  
  49.  
  50. /* ----------------------- */
  51.  
  52.  
  53. /* get the connection, process it, etc. (this most of the work) */
  54. int getconn()
  55. {
  56.    register int i;
  57.  
  58.    int res;
  59.    int ssize; 
  60.  
  61.    int hnamelen = 0;
  62.  
  63.    struct hostent *hent = NULL;  /* client's host entry */
  64.  
  65. /* 
  66.    If we ever implement it to malloc() client space dynamically 
  67.    (rather than all the necessary mem for the clients at once),
  68.    we would need to include this code.  For now, we don't need it
  69.  
  70.    clients[++curClient] = (struct client *)malloc(sizeof(struct client *));
  71.  
  72.    if (clients[curClient] == NULL)
  73.    {
  74.       error("error with malloc(): %s\n\n", strerror(errno));
  75.       quit(ERROR);
  76.    }
  77. */
  78.  
  79.    curClient = ERROR;
  80.  
  81.    for (i = 0; i < MAXCONNS; i++)
  82.    {
  83.       if ((clients[i]).free == 1)
  84.       {
  85.          curClient = i, curPid = 0;
  86.  
  87.          if (debugging == 1) 
  88.          {
  89.             (void)putchar('\n');
  90.             (void)write(dblogfd, "\n", 1);
  91.          }
  92.  
  93.          debug("next client will get clients[%d]\n", i);
  94.  
  95.          memset(&clients[i], 0, sizeof(struct client));  
  96.          clients[i].free = ERROR; 
  97.          clients[i].sockfd = ERROR;
  98.          clients[i].numSubIDs = 0;
  99.  
  100.          break;
  101.       }
  102.    }
  103.  
  104.    if (curClient == ERROR)
  105.    {
  106.       if (nofree != 1)
  107.       {
  108.          nofree = 1;
  109.          error("couldn't find a free structure.. restarting\n\n");
  110.       }
  111.  
  112.       return ERROR;
  113.    }
  114.  
  115.    memset(&clients[curClient].saddr, 0, sizeof(clients[curClient].saddr));
  116.    ssize = sizeof(struct sockaddr_in);
  117.  
  118.    debug("now waiting for a new client to connect..\n\n");
  119.  
  120.    while(1)
  121.    {
  122.       clients[curClient].sockfd = 
  123.            accept(mainfd, (struct sockaddr *) &(clients[curClient]).saddr, 
  124.                        &ssize);
  125.  
  126.       if ((clients[curClient]).sockfd == ERROR)
  127.       {
  128.          if (errno == EINTR) continue;
  129.  
  130.          (void)fputc('\n', stderr);
  131.          error("error with accept(): %s\n\n", strerror(errno));
  132.  
  133.          /* static - dont need this.
  134.          free(clients[curClient--]); */
  135.  
  136.          memset((char *) &clients[curClient], 0, sizeof(struct client));
  137.          clients[curClient].free = 1;
  138.  
  139.          return ERROR;
  140.       }
  141.  
  142.       else break;
  143.    }
  144.  
  145.    /* initiate the SSL parts */
  146. #  ifndef NOSSL
  147.    res = seteuid(0);
  148.    if (res == ERROR)
  149.    {
  150.       error("error with seteuid: %s\n\n", res);
  151.       quit(ERROR);
  152.    }
  153.  
  154.    makeSSLconn(clients[curClient].sockfd);
  155.  
  156.    res = seteuid(pwd->pw_uid);
  157.    if (res == ERROR)
  158.    {
  159.       error("error with seteuid: %s\n\n", res);
  160.       quit(ERROR);
  161.    }
  162. #  endif
  163.  
  164.    errno = 0;
  165.    hent = gethostbyaddr((char *) &(clients[curClient]).saddr.sin_addr, 
  166.              sizeof(struct in_addr), (clients[curClient]).saddr.sin_family);
  167.  
  168.    if (hent == NULL)
  169.    {
  170.       if (h_errno == HOST_NOT_FOUND)
  171.          error("error with gethostbyaddr: host not found\n\n");
  172.     
  173.       else if (h_errno == TRY_AGAIN)
  174.          error("error with gethostbyaddr: non-auth'd host/server failure\n\n");
  175.  
  176.       else if (h_errno == NO_RECOVERY)
  177.          error("error with gethostbyaddr: non-recoverable error\n\n");
  178.        
  179.       else if (h_errno == NO_DATA)
  180.          error("error with gethostbyaddr: no data request for that type\n\n");
  181.  
  182.       else if (h_errno == NO_ADDRESS)
  183.          error("error with gethostbyaddr: no address\n\n");
  184.  
  185.       if (debugging == 1) 
  186.       {
  187.          (void)putchar('\n');
  188.          (void)write(dblogfd, "\n", 1);
  189.       }
  190.    }
  191.  
  192.    if (hent && hent->h_name)
  193.    {
  194.       (void)printf("%connection from %s (%s)...\n\n", 
  195.                    (debugging != 1 ? 'C' : 'c'), hent->h_name,
  196.                    (char *)inet_ntoa((clients[curClient]).saddr.sin_addr));
  197.  
  198.       hnamelen = strlen(hent->h_name) + 1;
  199.  
  200.       clients[curClient].hname = (char *)malloc(hnamelen+1);
  201.       if (clients[curClient].hname == NULL)
  202.       {
  203.          error("error malloc()'ing hostname\n\n");
  204.          quit(ERROR);
  205.       }
  206.  
  207.       memset(clients[curClient].hname, 0, hnamelen+1);
  208.       strcpy(clients[curClient].hname, hent->h_name);
  209.    }
  210.  
  211.    else
  212.    {
  213.       (void)printf("%connection from %s...\n\n", 
  214.                    (debugging != 1 ? 'C' : 'c'),
  215.                    (char *)inet_ntoa((clients[curClient]).saddr.sin_addr));
  216.  
  217.       hnamelen = strlen(inet_ntoa(clients[curClient].saddr.sin_addr)) + 1;
  218.  
  219.       clients[curClient].hname = (char *)malloc(hnamelen+1);
  220.       if (clients[curClient].hname == NULL)
  221.       {
  222.          error("error malloc()'ing hostname\n\n");
  223.          quit(ERROR);
  224.       }
  225.  
  226.       memset(clients[curClient].hname, 0, hnamelen+1);
  227.       (void)strcpy(clients[curClient].hname, 
  228.                    inet_ntoa((clients[curClient]).saddr.sin_addr));
  229.    }
  230.  
  231.    if (hnamelen-1 > 0)
  232.    {
  233.       char lochname[hnamelen+1];
  234.       memset(lochname, 0, sizeof(lochname));
  235.  
  236.       res = gethostname(lochname, sizeof(lochname)-1);
  237.       if (res == ERROR)
  238.       {
  239.          signal(SIGPIPE, SIG_IGN);
  240.  
  241.          error("error with gethostname(): %s\n\n", strerror(errno));
  242.  
  243.          if (debugging == 1) 
  244.          {
  245.            (void)putchar('\n');
  246.             (void)write(dblogfd, "\n", 1);
  247.          }
  248.  
  249.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  250.  
  251.          close(clients[curClient].sockfd);
  252.          clients[curClient].free = 1;
  253.  
  254.          return ERROR;
  255.       }
  256.  
  257. /*
  258.       We're going to allow connections from the localhost in case we
  259.       should ever need to (though to emulate the customer's situation,
  260.       it's better to use different hosts.
  261.  
  262.       if ((strncmp(clients[curClient].hname, "127.0.0.1", 9) == 0) || 
  263.           (strncmp(clients[curClient].hname, "localhost", 9) == 0) ||
  264.           (strncmp(clients[curClient].hname, lochname, 
  265.                    strlen(lochname) == 0) ||
  266.           (strncmp(clients[curClient].hname, 
  267.                    inet_ntoa(laddr.sin_addr), strlen) == 0))
  268.       {
  269.          signal(SIGPIPE, SIG_IGN);
  270.  
  271.          error("warning: received a connection from the localhost\n\n");
  272.          send_data(clients[curClient].sockfd, "ERROR: %s\n", NOLOCERROR);
  273.  
  274.          close(clients[curClient].sockfd);
  275.          clients[curClient].free = 1;
  276.  
  277.          return ERROR;
  278.       }
  279. */
  280.    }
  281.  
  282.    else
  283.    {
  284.       error("(in getconn) hostname length < 0, killing client\n\n");
  285.       return ERROR;
  286.    }
  287.  
  288.    /* ----------------- */
  289.  
  290.    if ((ntohs(clients[curClient].saddr.sin_port) < 512) ||
  291.        (ntohs(clients[curClient].saddr.sin_port) > IPPORT_RESERVED-1))
  292.    {
  293.       send_data(clients[curClient].sockfd, "ERROR: %s\n", PORTERROR);
  294.       return ERROR;
  295.    }
  296.  
  297.    else send_data(clients[curClient].sockfd, "SUCCESSFUL connect\n");
  298.  
  299.    return 0;
  300. }
  301.  
  302.  
  303. /* -------------------------------- */
  304.  
  305.  
  306. /* set socket options */
  307. void setsockopts()
  308. {
  309.    int res;
  310.    int val = 1;
  311.  
  312.    /* probe remote host occasionally to make sure we're still connected */
  313.    /* ----------------------------------------------------------------- */
  314.  
  315.  
  316. #  ifdef SO_KEEPALIVE
  317.    /* val = 1; */
  318.    res = setsockopt(mainfd, SOL_SOCKET, SO_KEEPALIVE, 
  319.                     (char *)&val, sizeof(val));
  320.  
  321.    if (res == ERROR)
  322.    {
  323.       error("error with setsockopt (SO_KEEPALIVE): %s\n\n", strerror(errno));
  324.       quit(ERROR);
  325.    }
  326.  
  327. #  ifdef TCP_KEEPALIVE
  328.    val = PROBETIME; /* PROBETIME */
  329.  
  330.    res = setsockopt(mainfd, IPPROTO_TCP, TCP_KEEPALIVE, 
  331.                     (char *)&val, sizeof(val));
  332.  
  333.    if (res == ERROR)
  334.    {
  335.       error("error with setsockopt (TCP_KEEPALIVE): %s\n\n", strerror(errno));
  336.       quit(ERROR);
  337.    }
  338.  
  339. #  endif
  340. #  endif
  341.  
  342.    /* SO_KEEPALIVE must be set first */
  343.  
  344.  
  345.    /* allow us to reuse the same port with bind */
  346.    /* ----------------------------------------- */
  347.  
  348.    val = 1; /* enable it */
  349.  
  350. #  ifdef SO_REUSEADDR
  351.    res = setsockopt(mainfd, SOL_SOCKET, SO_REUSEADDR, 
  352.                     (char *)&val, sizeof(val));
  353.  
  354.    if (res == ERROR)
  355.    {
  356.       error("error with setsockopt (SO_REUSEADDR): %s\n\n", strerror(errno));
  357.       quit(ERROR);
  358.    }
  359. #  endif
  360. }
  361.  
  362.