services1.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:7k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /* 
  2.  * Copyright (C) 2002 Michel Arboi
  3.  *
  4.  * Some modifications (C) Tenable Network Security
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * TCP/IP service functions (getservent enhancement)
  21.  */ 
  22. #define EXPORTING
  23. #include "includes.h"
  24. #include <stdarg.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <unistd.h>
  28. #include "services.h"
  29. #ifndef MAP_FAILED
  30. #define MAP_FAILED (void*)(-1)
  31. #endif
  32. /*
  33.  * This file contains initialisation functions.
  34.  * IMPORTANT ! Some options are defined in services.h
  35.  */
  36. struct my_svc {
  37.   FILE *fp;
  38.   int port; /* 2 * port + proto_idx (0 = tcp, 1 = udp) */
  39.   char name[128];
  40.   /* Debug */
  41.   char *filename;
  42.   int line;
  43. };
  44. static int
  45. get_next_svc(struct my_svc *psvc)
  46. {
  47.   char line[256], proto[32], *p;
  48.  for (;;)
  49.    {
  50.      do
  51.        {
  52.  if (fgets(line, sizeof(line), psvc->fp) == NULL)
  53.    {
  54.        fclose(psvc->fp);
  55.      return 0;
  56.    }
  57.  psvc->line ++;
  58.        }
  59.      while (line[0] == '#' || isspace(line[0]));
  60.      for (p = line; ! isspace(*p) && *p != ''; p ++)
  61.        ;
  62.      if (*p == '')
  63.        continue;
  64.      *p = '';
  65.      if (sscanf(p+1, "%d/%s", &psvc->port, proto) == 2
  66.  )
  67.        {
  68.  psvc->port *= 2;
  69.  if (strcmp(proto, "udp") == 0)
  70.    psvc->port ++;
  71.  else if (strcmp(proto, "tcp") != 0)
  72.    continue;
  73.  psvc->name[sizeof(psvc->name) - 1] = '';
  74.  strncpy(psvc->name, line, sizeof(psvc->name) - 1);
  75.  return 1;
  76.        }
  77.    }
  78. }
  79. /*
  80.  * Note: we do not take any lock, so this function should only be called
  81.  * at Nessus startup
  82.  */
  83. ExtFunc int
  84. nessus_init_svc()
  85. {
  86.   static int flag = 0;
  87.   int l, error_flag = 0, rebuild = 0;
  88. #define N_SVC_F 5
  89.   struct my_svc svc[N_SVC_F];
  90.   int nf = 0, i, j, prev_p, prev_p_udp;
  91.   FILE *fpT = NULL, *fpU = NULL, *fpTXT = NULL;
  92.   struct nessus_service ness_svc;
  93.   struct stat st;
  94.   time_t t;
  95.   bzero(&ness_svc, sizeof(ness_svc));
  96.   if (flag)
  97.     return 0;
  98.   /* Verify files date */
  99.   
  100.   if (stat(NESSUS_SERVICES_TCP, &st) < 0)
  101.     t = 0;
  102.   else
  103.     {
  104.       int fd;
  105.       char * buf;
  106.      
  107.       fd = open(NESSUS_SERVICES_TCP, O_RDONLY);
  108.       if ( fd < 0 ) { perror("open "); rebuild ++; }
  109.       else
  110.        {
  111.    int len;
  112. len = (int)st.st_size;
  113.         buf = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
  114.         if ( buf == MAP_FAILED || buf == NULL ){ perror("mmap "); rebuild ++; }
  115.         else {
  116.             struct nessus_service * s;
  117.             s = (struct nessus_service*)(buf);
  118.             if ( s->magic != SERVICES_MAGIC ) rebuild ++;
  119.             munmap(buf, len);
  120.            }
  121.          close(fd);
  122.  fd = -1;
  123.        }
  124.       t = st.st_mtime;
  125.       if (stat(NESSUS_SERVICES_UDP, & st) < 0)
  126. t = 0;
  127.       else if ((unsigned)st.st_mtime < (unsigned)t)
  128. t = st.st_mtime;
  129.     }
  130.       
  131.  if ( stat(NESSUS_SERVICES, &st) < 0 )
  132. {
  133.  fprintf(stderr, "**** %s could not be found. Install it and try againn", NESSUS_SERVICES);
  134.  exit(1);
  135. }
  136.   if (stat(NESSUS_SERVICES, &st) >= 0 && (unsigned)st.st_mtime > (unsigned)t)
  137.     rebuild ++;
  138.   
  139.   if (! rebuild)
  140.     return 0;
  141.   /* fputs("Rebuilding Nessus services listn", stderr); */
  142.   for (i = 0; i < N_SVC_F; i ++)
  143.     svc[i].line = 1;
  144.   nf = 0;
  145.   (void) mkdir(NESSUS_STATE_DIR, 0755);
  146.   /*
  147.    * Although our code is all right to parse /etc/services, we also
  148.    * call getservent because the system may implement yellow pages or 
  149.    * some other kind of database. getservent() is supposed to walk through it.
  150.    */
  151.   /* nessus-services file is supposed to be sorted */
  152.   if ((svc[nf].fp = fopen(NESSUS_SERVICES, "r")) != NULL)
  153.   {
  154.     if (get_next_svc(&svc[nf]))
  155.     {
  156.       svc[nf].filename = NESSUS_SERVICES;
  157.       nf ++;
  158.     }
  159.   }
  160.   if (nf > 0)
  161.     {
  162.       if ((fpT = fopen(NESSUS_SERVICES_TCP, "w")) == NULL)
  163. {
  164.   perror(NESSUS_SERVICES_TCP);
  165.   error_flag ++;
  166. }
  167.       else if ((fpU = fopen(NESSUS_SERVICES_UDP, "w")) == NULL)
  168. {
  169.   perror(NESSUS_SERVICES_UDP);
  170.   error_flag ++;
  171. }
  172.       else if ((fpTXT = fopen(NESSUS_SERVICES_TXT, "w")) == NULL)
  173. {
  174.   perror(NESSUS_SERVICES_TXT);
  175.   error_flag ++;
  176. }
  177.     }
  178.   prev_p = prev_p_udp = -1;
  179.   while (nf > 0 && ! error_flag)
  180.     {
  181.       for (j = 0, i = 1; i < nf; i ++)
  182. {
  183.   if (svc[i].port < svc[j].port)
  184.     j = i;
  185. }
  186.       if ( ( svc[j].port % 2 == 0 && svc[j].port < prev_p     ) ||
  187.            ( svc[j].port % 2 != 0 && svc[j].port < prev_p_udp ) ) 
  188. {
  189. #if PANIC_THE_USER
  190.   if (*svc[j].filename == '/') /* No warning on system base */
  191.   fprintf(stderr, "nessus_init_svc: %s is not sorted! Found %d/%s at the wrong place (line %d)n",
  192.   svc[j].filename,
  193.   svc[j].port / 2, svc[j].port % 2 ? "udp" : "tcp",
  194.   svc[j].line);
  195. #endif   
  196. }
  197.       else if ( (svc[j].port % 2 == 0 && svc[j].port != prev_p) || 
  198.                 (svc[j].port % 2 != 0 && svc[j].port != prev_p_udp) )
  199. {
  200.   if ( svc[j].port % 2 == 0 )
  201.      prev_p = svc[j].port;
  202.   else
  203.    prev_p_udp = svc[j].port;
  204.   ness_svc.ns_port = svc[j].port / 2;
  205.   l = strlen(svc[j].name);
  206.   if (l > sizeof(ness_svc.ns_name) - 1)
  207.     l = sizeof(ness_svc.ns_name) - 1;
  208.           ness_svc.magic = SERVICES_MAGIC;
  209.   memcpy(ness_svc.ns_name, svc[j].name, l);
  210.   memset(ness_svc.ns_name + l, 0, sizeof(ness_svc.ns_name) - l);
  211. #ifdef ULTRA_VERBOSE_DEBUG
  212.   fprintf(stderr, "From %d: name=%s port=%d => %dn",
  213.   j, ness_svc.ns_name, svc[j].port, ness_svc.ns_port);
  214. #endif
  215.   if (svc[j].port % 2)
  216.     {
  217.       fprintf(fpTXT, "%st%d/udpn", ness_svc.ns_name, ness_svc.ns_port);
  218.       if (fwrite(&ness_svc, sizeof(ness_svc), 1, fpU) < 1)
  219. {
  220.   perror("fwrite");
  221.   error_flag ++;
  222. }
  223.     }
  224.   else
  225.     {
  226.       fprintf(fpTXT, "%st%d/tcpn", ness_svc.ns_name, ness_svc.ns_port);
  227.       if (fwrite(&ness_svc, sizeof(ness_svc), 1, fpT) < 1)
  228. {
  229.   perror("fwrite");
  230.   error_flag ++;
  231. }
  232.     }
  233. }
  234.       if (! get_next_svc(&svc[j]))
  235. {
  236.   for (i = j; i < nf - 1; i ++)
  237.     svc[i] = svc[i+1];
  238.   nf --;
  239. }
  240.     }
  241.   if( fpTXT != NULL )(void) fclose(fpTXT);
  242.   if ((fpT != NULL && fclose(fpT) < 0) || (fpU != NULL && fclose(fpU) < 0))
  243.     {
  244.       perror("fclose");
  245.       error_flag ++;
  246.     }
  247.   if (error_flag)
  248.     {
  249.       for (i = 0; i < nf; i ++)
  250. if (svc[i].fp != NULL && svc[i].fp != (void*) 1)
  251.     fclose(svc[i].fp);
  252.       unlink(NESSUS_SERVICES_TCP);
  253.       unlink(NESSUS_SERVICES_UDP);
  254.       unlink(NESSUS_SERVICES_TXT);
  255.     }
  256.   return error_flag ? -1 : 0;
  257. }