Changeset 526 for trunk/src


Ignore:
Timestamp:
Jun 29, 2017, 9:20:32 PM (7 years ago)
Author:
katerina
Message:

Fix for ticket #421 (spurious port detections) and ticket #422 (PortCheckSkip bug).

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_ipvx.c

    r509 r526  
    251251}
    252252
    253 int sh_ipvx_get_port(struct sockaddr * sa, int sa_family)
     253int sh_ipvx_get_port(struct sh_sockaddr * sa)
    254254{
    255255  int port = 0;
    256256#if defined(USE_IPVX)
    257257
    258   switch (sa_family)
     258  switch (sa->ss_family)
    259259    {
    260260    case AF_INET:
    261       port = ntohs(((struct sockaddr_in *)sa)->sin_port);
     261      port = ntohs((sa->sin).sin_port);
    262262      break;
    263263    case AF_INET6:
    264       port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
    265       break;
    266     }
    267 #else
    268   (void) sa_family;
    269   port = ntohs(((struct sockaddr_in *)sa)->sin_port);
     264      port = ntohs((sa->sin6).sin6_port);
     265      break;
     266    }
     267#else
     268  port = ntohs((sa->sin).sin_port);
    270269#endif
    271270  return port;
  • trunk/src/sh_portcheck.c

    r519 r526  
    4646#include <fcntl.h>
    4747
    48 #define PORTCHK_VERSION "1.0"
     48#define PORTCHK_VERSION "1.1"
    4949
    5050#if defined(TEST_ONLY) || (defined(SH_USE_PORTCHECK) && (defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)))
     
    140140#define SH_PORTCHK_INTERVAL 300
    141141
    142 static int sh_portchk_check_udp = 1;
    143 static int sh_portchk_active    = 1;
    144 static int sh_portchk_interval  = SH_PORTCHK_INTERVAL;
     142static int sh_portchk_check_udp  = 1;
     143static int sh_portchk_active     = 1;
     144static int sh_portchk_same_ports = 1;
     145static int sh_portchk_transients = 1;
     146static int sh_portchk_interval   = SH_PORTCHK_INTERVAL;
    145147
    146148static int sh_portchk_minport = -1;
     
    156158static struct sh_port * blacklist_udp = NULL;
    157159
     160static struct sh_port * transient_tcp = NULL;
     161static struct sh_port * transient_udp = NULL;
     162
    158163SH_MUTEX_STATIC(mutex_port_check, PTHREAD_MUTEX_INITIALIZER);
    159164
     
    196201 */
    197202static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * haddr, int proto);
     203
     204/* verify whether port/interface is transient (used as source port hence no check required)
     205 */
     206static int sh_portchk_is_transient(int port, struct sh_sockaddr * haddr, int proto);
     207static int sh_portchk_transient(int port, struct sh_sockaddr * haddr, int proto);
    198208
    199209#ifndef TEST_ONLY
     
    244254
    245255
    246 static int sh_portchk_set_minport   (const char * str)
     256static int sh_portchk_set_minport     (const char * str)
    247257{
    248258  return sh_portchk_set_port_minmax (str, &sh_portchk_minport);
    249259}
    250260
    251 static int sh_portchk_set_maxport   (const char * str)
     261static int sh_portchk_set_maxport     (const char * str)
    252262{
    253263  return sh_portchk_set_port_minmax (str, &sh_portchk_maxport);
    254264}
    255265
    256 static int sh_portchk_set_active   (const char * str)
     266static int sh_portchk_set_active     (const char * str)
    257267{
    258268  return sh_util_flagval(str, &sh_portchk_active);
    259269}
    260270
    261 static int sh_portchk_set_udp      (const char * str)
     271static int sh_portchk_set_udp        (const char * str)
    262272{
    263273  return sh_util_flagval(str, &sh_portchk_check_udp);
    264274}
    265 
    266 static int sh_portchk_set_severity (const char * str)
     275#if defined(SH_ALLOW_RESTORE)
     276static int sh_portchk_set_transients (const char * str)
     277{
     278  return sh_util_flagval(str, &sh_portchk_transients);
     279}
     280
     281static int sh_portchk_set_same_ports (const char * str)
     282{
     283  return sh_util_flagval(str, &sh_portchk_same_ports);
     284}
     285#endif
     286static int sh_portchk_set_severity   (const char * str)
    267287{
    268288  char tmp[32];
     
    323343        sh_portchk_set_udp,
    324344    },
     345#if defined(SH_ALLOW_RESTORE)
     346    {
     347        N_("portchecktransients"),
     348        sh_portchk_set_transients,
     349    },
     350    {
     351        N_("portchecksameports"),
     352        sh_portchk_set_same_ports,
     353    },
     354#endif
    325355    {
    326356        NULL,
     
    534564      if (head->next)
    535565        sh_portchk_kill_blacklist (head->next);
     566
     567      SH_FREE(head->paddr);
     568      SH_FREE(head);
     569    }
     570  return NULL;
     571}
     572 
     573static struct sh_port * sh_portchk_kill_transient (struct sh_port * head)
     574{
     575  if (head)
     576    {
     577      if (head->next)
     578        sh_portchk_kill_transient (head->next);
    536579
    537580      SH_FREE(head->paddr);
     
    647690  char str_addr[SH_IP_BUF];
    648691
     692
    649693  if (proto == IPPROTO_TCP)
    650694    portlist = portlist_tcp;
     
    911955#ifndef TEST_ONLY
    912956  char               errmsg[256];
    913   int                nerr;
     957  volatile int       nerr;
    914958#endif
    915959  char errbuf[SH_ERRBUF_SIZE];
    916960  char ipbuf[SH_IP_BUF];
     961
     962  struct sh_sockaddr    saddr;
     963  socklen_t             slen  = 0;
     964  volatile int          sport = 0;
    917965
    918966  sh_ipvx_set_port(paddr, port);
     
    941989  else
    942990    {
    943       do {
    944         retval = send (fd, buf, 0, 0);
    945       } while (retval < 0 && errno == EINTR);
    946 
    947       if (retval == -1 && errno == ECONNREFUSED)
    948         {
    949           sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    950           if (portchk_debug)
    951             fprintf(stderr, _("check port_udp: %5d/udp on %15s established/time_wait\n"),
    952                     port, ipbuf);
    953         }
    954       else
    955         {
    956           /* Only the second send() may catch the error
    957            */
    958           do {
     991      /* Register the used source port as transient. This will avoid
     992       * the issue of lingering source ports being reported as a spurious
     993       * service. The lingering source port is effectvely a race condition.
     994       *
     995       * Also use this code to obtain the source port. Sometimes Samhain
     996       * reports on a port where it connects back to itself. In that case
     997       * source and destination port are the same.
     998       *
     999       * AGH, 23 Apr 2017 (www.2024sight.com).
     1000       */
     1001
     1002#if defined(USE_IPVX)
     1003      if (paddr->ss_family == AF_INET)
     1004        {
     1005          saddr.ss_family = AF_INET;
     1006          slen = sizeof( struct sockaddr_in );
     1007          retval = getsockname(fd, (struct sockaddr *)&(saddr.sin), &slen);
     1008        }
     1009      else
     1010        {
     1011          saddr.ss_family = AF_INET6;
     1012          slen = sizeof( struct sockaddr_in6 );
     1013          retval = getsockname(fd, (struct sockaddr *)&(saddr.sin6), &slen);
     1014        }
     1015#else
     1016      saddr.ss_family = AF_INET;
     1017      slen = sizeof( struct sockaddr_in );
     1018      retval = getsockname(fd, (struct sockaddr *)&(saddr.sin), &slen);
     1019#endif
     1020
     1021      if ( retval == 0 )
     1022        {
     1023          sport = sh_ipvx_get_port(&saddr);
     1024          sh_portchk_transient(sport, &saddr, IPPROTO_UDP);
     1025        }
     1026      else
     1027        {
     1028#ifdef TEST_ONLY
     1029          if (portchk_debug)
     1030            perror(_("getsockname"));
     1031#else
     1032            sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1033            nerr = errno;
     1034            sl_snprintf(errmsg, sizeof(errmsg), _("source port transient for %15s:%d/udp: %s"),
     1035                            ipbuf, port, sh_error_message(errno, errbuf, sizeof(errbuf)));
     1036            SH_MUTEX_LOCK(mutex_thread_nolog);
     1037            sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN, errmsg, _("getsockname"));
     1038            SH_MUTEX_UNLOCK(mutex_thread_nolog);
     1039#endif
     1040        }
     1041
     1042      if (( sport != port ) || ( sh_portchk_same_ports == S_FALSE ))
     1043        {
     1044          do {
    9591045            retval = send (fd, buf, 0, 0);
    960           } while (retval < 0 && errno == EINTR);
    961 
    962           if (retval == -1 && errno == ECONNREFUSED)
     1046          } while (retval < 0 && errno == EINTR);
     1047
     1048          if (retval == -1 && errno == ECONNREFUSED)
    9631049            {
    9641050              sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    9651051              if (portchk_debug)
    966                 fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
    967                         port, ipbuf);
     1052                fprintf(stderr, _("check port_udp: %5d/udp on %15s established/time_wait\n"),
     1053                        port, ipbuf);
    9681054            }
    969           else if (retval != -1)
     1055          else
    9701056            {
    971               /* Try to get service name from portmap
     1057              /* Only the second send() may catch the error
    9721058               */
    973               if (paddr->ss_family == AF_INET)
    974                 {
    975                   p = check_rpc_list (port,
    976                                       (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
    977                                       IPPROTO_UDP);
    978                 }
    979 
    980               sh_portchk_cmp_to_list (IPPROTO_UDP, port, paddr, p ? p : NULL);
     1059              do {
     1060                retval = send (fd, buf, 0, 0);
     1061              } while (retval < 0 && errno == EINTR);
     1062
     1063              if (retval == -1 && errno == ECONNREFUSED)
     1064                {
     1065                  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1066                  if (portchk_debug)
     1067                    fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
     1068                            port, ipbuf);
     1069                }
     1070              else if (retval != -1)
     1071                {
     1072                  /* Try to get service name from portmap
     1073                   */
     1074                  if (paddr->ss_family == AF_INET)
     1075                    {
     1076                      p = check_rpc_list (port,
     1077                                          (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
     1078                                          IPPROTO_UDP);
     1079                    }
     1080
     1081                  sh_portchk_cmp_to_list (IPPROTO_UDP, port, paddr, p ? p : NULL);
    9811082             
    982               /* If not an RPC service, try to get name from /etc/services
    983                */
    984               if (!p)
    985                 p = check_services(port, IPPROTO_UDP);
     1083                  /* If not an RPC service, try to get name from /etc/services
     1084                   */
     1085                  if (!p)
     1086                    p = check_services(port, IPPROTO_UDP);
    9861087             
    987               if (portchk_debug)
    988                 {
    989                   sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    990                   fprintf(stderr, _("check port_udp: %5d/udp on %15s open %s\n"),
    991                           port, ipbuf, p);
    992                 }
     1088                  if (portchk_debug)
     1089                    {
     1090                      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1091                      fprintf(stderr, _("check port_udp: %5d/udp on %15s open %s\n"),
     1092                              port, ipbuf, p);
     1093                    }
    9931094             
     1095                }
     1096              else
     1097                {
     1098                  if (portchk_debug)
     1099                    {
     1100                      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1101                      fprintf(stderr, _("check port_udp: %5d/udp on %15s ERRNO %d\n"),
     1102                              port, ipbuf, errno);
     1103                    }
     1104                }
    9941105            }
    995           else
    996             {
    997               if (portchk_debug)
    998                 {
    999                   sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    1000                   fprintf(stderr, _("check port_udp: %5d/udp on %15s ERRNO %d\n"),
    1001                           port, ipbuf, errno);
    1002                 }
    1003             }
    1004         }
     1106        }
     1107      else
     1108        {
     1109          if (portchk_debug)
     1110            {
     1111              sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1112              fprintf(stderr, _("check port_udp: %5d/udp on %15s same source and destination port\n"),
     1113                      port, ipbuf);
     1114            }
     1115        }
    10051116    }
    10061117  sl_close_fd (FIL__, __LINE__, fd);
     
    10101121static int check_port_tcp_internal (int fd, int port, struct sh_sockaddr * paddr)
    10111122{
    1012   int                retval;
     1123  volatile int       retval;
    10131124  int                flags;
    10141125  char             * p = NULL;
    10151126#ifndef TEST_ONLY
    10161127  char               errmsg[256];
    1017   int                nerr;
     1128  volatile int       nerr;
    10181129#endif
    10191130  char errbuf[SH_ERRBUF_SIZE];
    10201131  char ipbuf[SH_IP_BUF];
     1132
     1133  struct sh_sockaddr    saddr;
     1134  socklen_t             slen  = 0;
     1135  volatile int          sport = 0;
    10211136
    10221137  sh_ipvx_set_port(paddr, port);
     
    10531168  else
    10541169    {
    1055       /* Try to get service name from portmap
     1170      /* Register the used source port as transient. This will avoid
     1171       * the issue of lingering source ports being reported as a spurious
     1172       * service. The lingering source port is effectively a race condition.
     1173       *
     1174       * Also use this code to obtain the source port. Sometimes Samhain
     1175       * reports on a port where it connects back to itself. In that case
     1176       * source and destination port are the same.
     1177       *
     1178       * AGH, 23 Apr 2017 (www.2024sight.com).
    10561179       */
     1180
     1181#if defined(USE_IPVX)
    10571182      if (paddr->ss_family == AF_INET)
    1058         {
    1059           p = check_rpc_list (port,
    1060                               (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
    1061                               IPPROTO_TCP);
    1062         }
    1063 
    1064       sh_portchk_cmp_to_list (IPPROTO_TCP, port, paddr, p ? p : NULL);
    1065 
    1066       /* If not an RPC service, try to get name from /etc/services
    1067        */
    1068       if (!p)
    1069         p = check_services(port, IPPROTO_TCP);
    1070 
    1071       if (portchk_debug)
    1072         {
    1073           sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    1074           fprintf(stderr, _("check port_tcp: %5d on %15s open %s\n"),
    1075                   port, ipbuf, p);
    1076         }
     1183        {
     1184          saddr.ss_family = AF_INET;
     1185          slen = sizeof( struct sockaddr_in );
     1186          retval = getsockname(fd, (struct sockaddr *)&(saddr.sin), &slen);
     1187        }
     1188      else
     1189        {
     1190          saddr.ss_family = AF_INET6;
     1191          slen = sizeof( struct sockaddr_in6 );
     1192          retval = getsockname(fd, (struct sockaddr *)&(saddr.sin6), &slen);
     1193        }
     1194#else
     1195      saddr.ss_family = AF_INET;
     1196      slen = sizeof( struct sockaddr_in );
     1197      retval = getsockname(fd, (struct sockaddr *)&(saddr.sin), &slen);
     1198#endif
     1199
     1200      if ( retval == 0 )
     1201        {
     1202          sport = sh_ipvx_get_port(&saddr);
     1203          sh_portchk_transient(sport, &saddr, IPPROTO_TCP);
     1204        }
     1205      else
     1206        {
     1207#ifdef TEST_ONLY
     1208          if (portchk_debug)
     1209            perror(_("getsockname"));
     1210#else
     1211            sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1212            nerr = errno;
     1213            sl_snprintf(errmsg, sizeof(errmsg), _("source port transient for %15s:%d/tcp: %s"),
     1214                        ipbuf, port, sh_error_message(errno, errbuf, sizeof(errbuf)));
     1215            SH_MUTEX_LOCK(mutex_thread_nolog);
     1216            sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN,
     1217                            errmsg, _("getsockname"));
     1218            SH_MUTEX_UNLOCK(mutex_thread_nolog);
     1219#endif
     1220        }
     1221
     1222      if (( sport != port ) || ( sh_portchk_same_ports == S_FALSE ))
     1223        {
     1224          /* Try to get service name from portmap
     1225           */
     1226          if (paddr->ss_family == AF_INET)
     1227            {
     1228              p = check_rpc_list (port,
     1229                                  (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
     1230                                  IPPROTO_TCP);
     1231            }
     1232
     1233          sh_portchk_cmp_to_list (IPPROTO_TCP, port, paddr, p ? p : NULL);
     1234
     1235          /* If not an RPC service, try to get name from /etc/services
     1236           */
     1237          if (!p)
     1238            p = check_services(port, IPPROTO_TCP);
     1239
     1240          if (portchk_debug)
     1241            {
     1242              sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1243              fprintf(stderr, _("check port_tcp: %5d on %15s open %s\n"),
     1244                      port, ipbuf, p);
     1245            }
     1246        }
     1247      else
     1248        {
     1249          if (portchk_debug)
     1250            {
     1251              sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     1252              fprintf(stderr, _("check port_udp: %5d/tcp on %15s same source and destination port\n"),
     1253                      port, ipbuf);
     1254            }
     1255        }
    10771256
    10781257#if !defined(O_NONBLOCK)
     
    13851564        }
    13861565
     1566      if (0 != sh_portchk_is_transient(port, &paddr, protocol))
     1567        {
     1568          ++i;
     1569          continue;
     1570        }
     1571
    13871572      if ((sock = socket(paddr.ss_family, type, protocol)) < 0 )
    13881573        {
     
    15741759        }
    15751760    }
     1761
     1762  if (protocol == IPPROTO_TCP)
     1763    transient_tcp=sh_portchk_kill_transient(transient_tcp);
     1764  else
     1765    transient_udp=sh_portchk_kill_transient(transient_udp);
     1766 
    15761767  return 0;
    15771768}
     
    18912082  while (head)
    18922083    {
    1893       if (head->port == port)
    1894         {
    1895           if (sh_ipvx_isany(head->paddr) ||
    1896               0 == sh_ipvx_cmp(head->paddr, saddr))
    1897             return 1;
    1898           else
    1899             return 0;
    1900         }
     2084      if (head->port == port && ( sh_ipvx_isany(head->paddr) ||  0 == sh_ipvx_cmp(head->paddr, saddr) ))
     2085        return 1;
    19012086      head = head->next;
    19022087    }
     
    19442129  return 0;
    19452130}
     2131
     2132
     2133/* verify whether port/interface is transient (used as source port
     2134 *hence no check required)
     2135 */
     2136static int sh_portchk_is_transient(int port, struct sh_sockaddr * saddr,
     2137                                     int proto)
     2138{
     2139  struct sh_port * head;
    19462140 
     2141  if (proto == IPPROTO_TCP)
     2142    head = transient_tcp;
     2143  else
     2144    head = transient_udp;
     2145 
     2146  while (head)
     2147    {
     2148      if (head->port == port && ( sh_ipvx_isany(head->paddr) || 0 == sh_ipvx_cmp(head->paddr, saddr) ))
     2149        return 1;
     2150      head = head->next;
     2151    }
     2152  return 0;
     2153}
     2154
     2155
     2156static int sh_portchk_transient(int port, struct sh_sockaddr * saddr, int proto)
     2157{
     2158  struct sh_port * transient;
     2159  struct sh_port * head;
     2160
     2161  if (sh_portchk_transients == S_FALSE)
     2162    return 0;
     2163
     2164  if (proto == IPPROTO_TCP)
     2165    head = transient_tcp;
     2166  else
     2167    head = transient_udp;
     2168
     2169  transient = head;
     2170
     2171  while (transient)
     2172    {
     2173      if (transient->port == port &&
     2174          0 == sh_ipvx_cmp(head->paddr, saddr))
     2175        return -1;
     2176      transient = transient->next;
     2177    }
     2178
     2179  transient = SH_ALLOC (sizeof(struct sh_port));
     2180  transient->paddr = SH_ALLOC (sizeof(struct sh_sockaddr));
     2181  transient->port  = port;
     2182  memcpy(transient->paddr, saddr, sizeof(struct sh_sockaddr));
     2183  transient->next  = head;
     2184
     2185  if (proto == IPPROTO_TCP)
     2186    transient_tcp = transient;
     2187  else
     2188    transient_udp = transient;
     2189
     2190  if (portchk_debug)
     2191    {
     2192      int checkit = sh_portchk_is_transient(port, saddr, proto);
     2193      fprintf(stderr, _("port transient: %d %s\n"), port,
     2194              (checkit == 1) ? _("ok") : _("fail"));
     2195    }
     2196  return 0;
     2197}
     2198
     2199
    19472200/* Subroutine to add a required or optional port/service
    19482201 */
Note: See TracChangeset for help on using the changeset viewer.