"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-preprocessors/appid/appInfoTable.c" (16 Oct 2020, 37417 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "appInfoTable.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /*
    2 ** Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    3 ** Copyright (C) 2005-2013 Sourcefire, Inc.
    4 **
    5 ** This program is free software; you can redistribute it and/or modify
    6 ** it under the terms of the GNU General Public License Version 2 as
    7 ** published by the Free Software Foundation.  You may not use, modify or
    8 ** distribute this program under any other version of the GNU General
    9 ** Public License.
   10 **
   11 ** This program 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
   14 ** GNU General Public License for more details.
   15 **
   16 ** You should have received a copy of the GNU General Public License
   17 ** along with this program; if not, write to the Free Software
   18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19 */
   20 
   21 
   22 #include <stdbool.h>
   23 #include <stdint.h>
   24 #include <stdio.h>
   25 #include <stdlib.h>
   26 #include <string.h>
   27 #include <sys/types.h>
   28 #include <sys/stat.h>
   29 #include <stdlib.h>
   30 #include <ctype.h>
   31 #include <syslog.h>
   32 #include <limits.h>
   33 #include "appId.h"
   34 #include "appInfoTable.h"
   35 #include "Unified2_common.h"
   36 
   37 #define APP_MAPPING_FILE "appMapping.data"
   38 #define APP_CONFIG_FILE "appid.conf"
   39 #define USR_CONFIG_FILE "userappid.conf"
   40 
   41 #define MAX_TABLE_LINE_LEN      1024
   42 // Generic delimiter for conf file
   43 #define CONF_SEPARATORS         "\t\n\r"
   44 // Delimiter for appid.conf  and userappid.conf file
   45 #define CONF_SEPARATORS_USR_APPID         " \t\n\r"
   46 #define MIN_MAX_TP_FLOW_DEPTH   1
   47 #define MAX_MAX_TP_FLOW_DEPTH   1000000
   48 #define MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL    1
   49 #define MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL    1000000
   50 #define MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE       1
   51 #define MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE       1000000
   52 #define MIN_MAX_BYTES_BEFORE_SERVICE_FAIL 4096
   53 #define MIN_MAX_PACKET_BEFORE_SERVICE_FAIL 5
   54 #define MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES 15
   55 struct DynamicArray
   56 { 
   57     void **table;
   58     size_t  indexStart;
   59     size_t  indexCurrent;
   60     size_t  usedCount;
   61     size_t  allocatedCount;
   62     size_t  stepSize;
   63 };
   64 typedef struct DynamicArray tDynamicArray;
   65 
   66 static inline struct DynamicArray* dynamicArrayCreate(unsigned indexStart)
   67 {
   68     struct DynamicArray *array;
   69 
   70     if ((array = calloc(1, sizeof(*array))))
   71     {
   72         array->stepSize = 1; 
   73         array->indexStart = indexStart;
   74     }
   75     return array;
   76 }
   77 
   78 static inline void dynamicArrayDestroy(struct DynamicArray *array)
   79 {
   80     unsigned i;
   81     AppInfoTableEntry *entry;
   82 
   83     if (!array)
   84         return;
   85     for (i = 0; i < array->usedCount; i++)
   86     {
   87         entry = array->table[i];
   88         free(entry->appName);
   89         free(entry);
   90     }
   91 
   92     free(array->table);
   93     free(array);
   94 }
   95 
   96 static inline void dynamicArraySetIndex(struct DynamicArray *array, unsigned index, void* data)
   97 {
   98     if (index >= array->indexStart && index < (array->indexStart + array->usedCount))
   99         array->table[index - array->indexStart] = data;
  100 } 
  101 static inline void* dynamicArrayGetIndex(struct DynamicArray *array, unsigned index)
  102 {
  103     if (index >= array->indexStart && index < (array->indexStart + array->usedCount))
  104         return array->table[index - array->indexStart];
  105     return NULL;
  106 } 
  107 static inline bool dynamicArrayCreateIndex(struct DynamicArray *array, unsigned *index)
  108 {
  109     if (array->usedCount == array->allocatedCount)
  110     {
  111         void** tmp = realloc(array->table, (array->allocatedCount + array->stepSize)*sizeof(*tmp));
  112         if (!tmp)
  113         {
  114             return false;
  115         }
  116         array->table = tmp;
  117         array->allocatedCount += array->stepSize;
  118     }
  119     *index = array->indexStart + (array->usedCount++);
  120     return true;
  121 } 
  122 
  123 static inline void* dynamicArrayGetFirst(struct DynamicArray *array)
  124 {
  125     AppInfoTableEntry *entry;
  126     for (array->indexCurrent = 0; array->indexCurrent < array->usedCount; array->indexCurrent++)
  127     {
  128         if ((entry = array->table[array->indexCurrent]))
  129             return entry;
  130     }
  131     return NULL;
  132 }
  133 static inline void* dynamicArrayGetNext(struct DynamicArray *array)
  134 {
  135     AppInfoTableEntry *entry;
  136     for (array->indexCurrent++; array->indexCurrent < array->usedCount; array->indexCurrent++)
  137     {
  138         if ((entry = array->table[array->indexCurrent]))
  139             return entry;
  140     }
  141     return NULL;
  142 }
  143 // End of Dynamic array
  144 SFGHASH*  appNameHashInit()
  145 {
  146     SFGHASH  *appNameHash;
  147     appNameHash = sfghash_new(65, 0, 0 /* alloc copies of lowercased keys */, NULL);
  148     if (!appNameHash)
  149     {
  150         _dpd.fatalMsg("AppNameHash: Failed to Initialize\n");
  151     }
  152     return appNameHash;
  153 }
  154 void  appNameHashFini(SFGHASH *appNameHash)
  155 {
  156     if (appNameHash)
  157     {
  158         sfghash_delete(appNameHash);
  159     }
  160 }
  161 
  162 static inline char *strdupToLower(const char *source)
  163 {
  164     int index;
  165     char *dest = malloc(strlen(source)+1);
  166     
  167     if (dest) 
  168     {
  169         for(index = 0;; index++)
  170         {
  171             if (source[index])
  172             {
  173                 dest[index] = tolower(source[index]);
  174                 continue;
  175             }
  176             else
  177             {
  178                 dest[index] = '\0';
  179                 break;
  180             }
  181         }
  182     }
  183     else
  184         _dpd.errMsg("strdupToLower: Failed to allocate memory for destination\n");
  185 
  186     return dest;
  187 }
  188 
  189 void appNameHashAdd(SFGHASH *appNameHash, const char *appName, void *data)
  190 {
  191     char *searchName;
  192     int errCode;
  193 
  194     if (!appName || !appNameHash)
  195         return;
  196     
  197     searchName = strdupToLower(appName);
  198     if (!searchName)
  199         return;
  200         
  201     if (SFGHASH_OK == (errCode = sfghash_add(appNameHash, searchName, data)))
  202     {
  203         DEBUG_WRAP(DebugMessage(DEBUG_APPID, "App name added for %s\n", appName););
  204     }
  205     else if (SFGHASH_INTABLE == errCode)
  206     {
  207         /* Note that, although this entry is not placed in the hash table, 
  208            being a duplicate, it remains in the list of allocated entries
  209            for cleanup by appInfoTableFini() */
  210         
  211         // Rediscover the existing, hashed entry for the purpose of a complete error message.
  212         AppInfoTableEntry* tableEntry = (AppInfoTableEntry*)sfghash_find(appNameHash, searchName);
  213 
  214         if (tableEntry)
  215         {
  216             _dpd.errMsg("App name, \"%s\", is a duplicate of \"%s\" and has been ignored.\n", 
  217                 appName, tableEntry->appName );
  218         }
  219         else
  220         {
  221             _dpd.errMsg("App name, \"%s\", has been ignored. Hash key \"%s\" is not unique.\n", 
  222                 appName, searchName );
  223         }
  224     }
  225     free(searchName);
  226 }
  227 
  228 void* appNameHashFind(SFGHASH *appNameHash, const char *appName)
  229 {
  230     void *data;
  231     char *searchName;
  232 
  233     if (!appName || !appNameHash)
  234         return NULL;
  235 
  236     searchName = strdupToLower(appName);
  237     if (!searchName)
  238         return NULL;
  239         
  240     data = sfghash_find(appNameHash, searchName);
  241 
  242     free(searchName);
  243 
  244     return data;
  245 }
  246 // End of appName hash
  247 
  248 static void appIdConfLoad (tAppidStaticConfig* appidSC, const char *path);
  249 
  250 static unsigned int getAppIdStaticIndex(tAppId appid)
  251 {
  252     if (appid > 0 && appid < SF_APPID_BUILDIN_MAX) 
  253         return appid;
  254     if (appid >= SF_APPID_CSD_MIN && appid < SF_APPID_CSD_MIN+(SF_APPID_MAX-SF_APPID_BUILDIN_MAX))
  255         return (SF_APPID_BUILDIN_MAX + appid - SF_APPID_CSD_MIN);
  256     return 0;
  257 }
  258 
  259 AppInfoTableEntry* appInfoEntryGet(tAppId appId, const tAppIdConfig *pConfig)
  260 {
  261     tAppId tmp;
  262     if ((tmp = getAppIdStaticIndex(appId)))
  263         return pConfig->AppInfoTable[tmp];
  264     return dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  265 }
  266 
  267 AppInfoTableEntry* appInfoEntryCreate(const char *appName, tAppIdConfig *pConfig)
  268 {
  269     tAppId appId;
  270     AppInfoTableEntry *entry;
  271    
  272     if (!appName || strlen(appName) >= MAX_EVENT_APPNAME_LEN)
  273     {
  274         _dpd.errMsg("Appname invalid\n", appName);
  275         return NULL;
  276     }
  277 
  278     entry = appNameHashFind(pConfig->AppNameHash, appName);
  279     if (!entry)
  280     {
  281         if (!dynamicArrayCreateIndex(pConfig->AppInfoTableDyn, (uint32_t *)&appId))
  282         {
  283             return NULL;
  284         }
  285 
  286         if ((entry = calloc(1, sizeof(*entry))))
  287         {
  288             entry->appId = appId;
  289             entry->serviceId = entry->appId;
  290             entry->clientId = entry->appId;
  291             entry->payloadId = entry->appId;
  292             entry->appName = strdup(appName);
  293             if (!entry->appName)
  294             {
  295                 _dpd.errMsg("failed to allocate appName");
  296                 free(entry);
  297                 return NULL;
  298             }
  299 
  300             dynamicArraySetIndex(pConfig->AppInfoTableDyn, appId, entry);
  301             if (pConfig->AppNameHash != NULL)
  302                 appNameHashAdd(pConfig->AppNameHash, appName, entry);
  303         }
  304         else
  305         {
  306             _dpd.errMsg("calloc failure\n");
  307         }
  308     }
  309     return entry;
  310 }
  311 
  312 void appInfoTableInit(tAppidStaticConfig* appidSC, tAppIdConfig* pConfig)
  313 {
  314     FILE *tableFile;
  315     const char *token;
  316     char buf[MAX_TABLE_LINE_LEN];
  317     AppInfoTableEntry *entry;
  318     tAppId appId;
  319     uint32_t clientId, serviceId, payloadId;
  320     char filepath[PATH_MAX];
  321     char *appName=NULL;
  322     char *snortName=NULL;
  323 
  324     pConfig->AppInfoTableDyn = dynamicArrayCreate(SF_APPID_DYNAMIC_MIN);
  325 
  326     snprintf(filepath, sizeof(filepath), "%s/odp/%s", appidSC->app_id_detector_path, APP_MAPPING_FILE);
  327 
  328     tableFile = fopen(filepath, "r");
  329     if (tableFile == NULL)
  330     {
  331         _dpd.errMsg("Could not open RnaAppMapping Table file: %s\n", filepath);
  332         return;
  333     }
  334 
  335     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "    AppInfo read from %s\n", filepath););
  336 
  337     while (fgets(buf, sizeof(buf), tableFile))
  338     {
  339         token = strtok(buf, CONF_SEPARATORS );
  340         if (!token)
  341         {
  342             _dpd.errMsg("Could not read id for Rna Id\n");
  343             continue;
  344         }
  345 
  346         appId = strtol(token, NULL, 10);
  347 
  348         token = strtok(NULL, CONF_SEPARATORS );
  349         if (!token)
  350         {
  351             _dpd.errMsg("Could not read appName. Line %s\n", buf);
  352             continue;
  353         }
  354 
  355         appName = strdup(token);
  356         if (!appName)
  357         {
  358             _dpd.errMsg("Could not allocate space for appName\n");
  359             continue;
  360         }
  361 
  362         token = strtok(NULL, CONF_SEPARATORS );
  363         if (!token)
  364         {
  365             _dpd.errMsg("Could not read service id for Rna Id\n");
  366             free(appName);
  367             continue;
  368         }
  369 
  370         serviceId = strtol(token, NULL, 10);
  371 
  372         token = strtok(NULL, CONF_SEPARATORS );
  373         if (!token)
  374         {
  375             _dpd.errMsg("Could not read client id for Rna Id\n");
  376             free(appName);
  377             continue;
  378         }
  379 
  380         clientId = strtol(token, NULL, 10);
  381 
  382         token = strtok(NULL, CONF_SEPARATORS );
  383         if (!token)
  384         {
  385             _dpd.errMsg("Could not read payload id for Rna Id\n");
  386             free(appName);
  387             continue;
  388         }
  389 
  390         payloadId = strtol(token, NULL, 10);
  391 
  392         /* snort service key, if it exists */
  393         token = strtok(NULL, CONF_SEPARATORS );
  394         if (token)
  395         {
  396             snortName = strdup(token);
  397             if (!snortName)
  398             {
  399                 _dpd.errMsg("malloc failure\n");
  400                 free(appName);
  401                 continue;
  402             }
  403         }
  404 
  405 
  406         entry = calloc(1, sizeof(*entry));
  407         if (!entry)
  408         {
  409             _dpd.errMsg("AppInfoTable: Memory allocation failure\n");
  410             free(appName);
  411             free(snortName);
  412             continue;
  413         }
  414 
  415         entry->next = pConfig->AppInfoList;
  416         pConfig->AppInfoList = entry;
  417 
  418         if (snortName)
  419         {
  420 #ifdef TARGET_BASED
  421             entry->snortId = _dpd.addProtocolReference(snortName);
  422             free(snortName);
  423             snortName = NULL;
  424 #endif
  425         }
  426 
  427         entry->appName = appName;
  428 
  429         entry->appId = appId;
  430         entry->serviceId = serviceId;
  431         entry->clientId = clientId;
  432         entry->payloadId = payloadId;
  433         entry->priority = APP_PRIORITY_DEFAULT;
  434 
  435         if ((appId = getAppIdStaticIndex(entry->appId)))
  436             pConfig->AppInfoTable[appId] = entry;
  437         if ((appId = getAppIdStaticIndex(entry->serviceId)))
  438             pConfig->AppInfoTableByService[appId] = entry;
  439         if ((appId = getAppIdStaticIndex(entry->clientId)))
  440             pConfig->AppInfoTableByClient[appId] = entry;
  441         if ((appId = getAppIdStaticIndex(entry->payloadId)))
  442             pConfig->AppInfoTableByPayload[appId] = entry;
  443 
  444         if (!pConfig->AppNameHash)
  445         {
  446             pConfig->AppNameHash = appNameHashInit();
  447         }
  448         appNameHashAdd(pConfig->AppNameHash, appName, entry);
  449     }
  450     fclose(tableFile);
  451 
  452     /* Configuration defaults. */
  453     appidSC->rtmp_max_packets = 15;
  454     appidSC->mdns_user_reporting = 1;
  455     appidSC->dns_host_reporting = 1;
  456     appidSC->max_tp_flow_depth = 5;
  457     appidSC->http2_detection_enabled = 0;
  458     appidSC->host_port_app_cache_lookup_interval = 10;
  459     appidSC->host_port_app_cache_lookup_range = 100000;
  460     appidSC->is_host_port_app_cache_runtime = 1;
  461     appidSC->check_host_port_app_cache = 0;
  462     appidSC->check_host_cache_unknown_ssl = 0;
  463     appidSC->recheck_for_unknown_appid = 0;
  464     appidSC->send_state_sharing_updates = 1;
  465     appidSC->allow_port_wildcard_host_cache = 0;
  466     appidSC->recheck_for_portservice_appid = 0;
  467     appidSC->max_packet_before_service_fail = MIN_MAX_PACKET_BEFORE_SERVICE_FAIL;
  468     appidSC->max_bytes_before_service_fail = MIN_MAX_BYTES_BEFORE_SERVICE_FAIL;
  469     appidSC->max_packet_service_fail_ignore_bytes = MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES;
  470     appidSC->http_tunnel_detect = HTTP_TUNNEL_DETECT_RESTART;
  471     snprintf(filepath, sizeof(filepath), "%s/odp/%s", appidSC->app_id_detector_path, APP_CONFIG_FILE);
  472     appIdConfLoad (appidSC, filepath);
  473     snprintf(filepath, sizeof(filepath), "%s/../%s", appidSC->app_id_detector_path, USR_CONFIG_FILE);
  474     appIdConfLoad (appidSC, filepath);
  475 }
  476 
  477 void appInfoTableFini(tAppIdConfig *pConfig)
  478 {
  479     AppInfoTableEntry *entry;
  480 
  481     while ((entry = pConfig->AppInfoList))
  482     {
  483         pConfig->AppInfoList = entry->next;
  484         if (entry->appName) 
  485             free(entry->appName);
  486         free(entry);
  487     }
  488 
  489     dynamicArrayDestroy(pConfig->AppInfoTableDyn);
  490     pConfig->AppInfoTableDyn = NULL;
  491 
  492     appNameHashFini(pConfig->AppNameHash);
  493 }
  494 
  495 void appInfoTableDump(tAppIdConfig *pConfig)
  496 {
  497     AppInfoTableEntry *entry;
  498     tAppId appId;
  499 
  500     _dpd.errMsg("Cisco provided detectors:\n");
  501     for (appId = 1; appId < SF_APPID_MAX; appId++)
  502     {
  503         entry = pConfig->AppInfoTable[appId];
  504         if (entry)
  505             _dpd.errMsg("%s\t%d\t%s\n", entry->appName, entry->appId, (entry->flags & APPINFO_FLAG_ACTIVE)? "active":"inactive");
  506     }
  507     _dpd.errMsg("User provided detectors:\n");
  508     for (entry = dynamicArrayGetFirst(pConfig->AppInfoTableDyn); entry; entry = dynamicArrayGetNext(pConfig->AppInfoTableDyn))
  509     {
  510         _dpd.errMsg("%s\t%d\t%s\n", entry->appName, entry->appId, (entry->flags & APPINFO_FLAG_ACTIVE)? "active":"inactive");
  511     }
  512 }
  513 tAppId appGetAppFromServiceId(uint32_t appId, tAppIdConfig *pConfig)
  514 {
  515     AppInfoTableEntry *entry;
  516     tAppId tmp;
  517 
  518     if ((tmp = getAppIdStaticIndex(appId)))
  519         entry = pConfig->AppInfoTableByService[tmp];
  520     else 
  521         entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  522 
  523     return entry ? entry->appId : APP_ID_NONE;
  524 }
  525 
  526 tAppId appGetAppFromClientId(uint32_t appId, tAppIdConfig *pConfig)
  527 {
  528     AppInfoTableEntry *entry;
  529     tAppId tmp;
  530 
  531     if ((tmp = getAppIdStaticIndex(appId)))
  532         entry = pConfig->AppInfoTableByClient[tmp];
  533     else 
  534         entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  535 
  536     return entry ? entry->appId : APP_ID_NONE;
  537 }
  538 tAppId appGetAppFromPayloadId(uint32_t appId, tAppIdConfig *pConfig)
  539 {
  540     AppInfoTableEntry *entry;
  541     tAppId tmp;
  542 
  543     if ((tmp = getAppIdStaticIndex(appId)))
  544         entry = pConfig->AppInfoTableByPayload[tmp];
  545     else 
  546         entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  547 
  548     return entry ? entry->appId : APP_ID_NONE;
  549 }
  550 const char * appGetAppName(int32_t appId)
  551 {
  552     AppInfoTableEntry *entry;
  553     tAppIdConfig *pConfig = appIdActiveConfigGet();
  554     tAppId tmp;
  555 
  556     if ((tmp = getAppIdStaticIndex(appId)))
  557         entry = pConfig->AppInfoTable[tmp];
  558     else 
  559         entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  560 
  561     return entry ? entry->appName : NULL;
  562 }
  563 
  564 int32_t appGetAppId(const char *appName)
  565 {
  566     AppInfoTableEntry *entry;
  567     tAppIdConfig *pConfig = appIdActiveConfigGet();
  568 
  569     entry = appNameHashFind(pConfig->AppNameHash, appName);
  570     return entry?entry->appId:0;
  571 }
  572 
  573 void appInfoSetActive(tAppId appId, bool active)
  574 {
  575     AppInfoTableEntry *entry = NULL;
  576     tAppIdConfig *pConfig = appIdActiveConfigGet();
  577     tAppId tmp;
  578 
  579     if (appId == APP_ID_NONE)
  580         return;
  581 
  582     if ((tmp = getAppIdStaticIndex(appId)))
  583         entry =  pConfig->AppInfoTable[tmp];
  584     else 
  585         entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
  586 
  587     if (entry)
  588     {
  589         if (active)
  590             entry->flags |= APPINFO_FLAG_ACTIVE;
  591         else
  592             entry->flags &= ~APPINFO_FLAG_ACTIVE;
  593     }
  594     else
  595     {
  596         _dpd.errMsg("AppInfo: AppId %d is UNKNOWN\n", appId);
  597     }
  598 }
  599 
  600 
  601 static void appIdConfLoad (tAppidStaticConfig* appidSC, const char *path)
  602 {
  603     FILE *config_file;
  604     char *token;
  605     char buf[1024];
  606     char referred_app_list[4096];
  607     int  referred_app_index;
  608     char *conf_type;
  609     char *conf_key;
  610     char *conf_val;
  611     unsigned line = 0;
  612     tAppIdConfig *pConfig = appIdNewConfigGet();
  613     int max_tp_flow_depth;
  614     int host_port_app_cache_lookup_interval;
  615     int host_port_app_cache_lookup_range;
  616 
  617     config_file = fopen(path, "r");
  618     if (config_file == NULL)
  619     {
  620         return;
  621     }
  622     else
  623     {
  624         DEBUG_WRAP(DebugMessage(DEBUG_APPID, "Loading configuration file %s\n", path););
  625     }
  626 
  627     while (fgets(buf, sizeof(buf), config_file) != NULL)
  628     {
  629         line++;
  630         token = strtok(buf, CONF_SEPARATORS_USR_APPID);
  631         if (token == NULL)
  632         {
  633             _dpd.errMsg("Could not read configuration at line %s:%u\n", path, line);
  634             continue;
  635         }
  636         conf_type = token;
  637 
  638         token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
  639         if (token == NULL)
  640         {
  641             _dpd.errMsg("Could not read configuration value at line %s:%u\n", path, line);
  642             continue;
  643         }
  644         conf_key = token;
  645 
  646         token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
  647         if (token == NULL)
  648         {
  649             _dpd.errMsg("Could not read configuration value at line %s:%u\n", path, line);
  650             continue;
  651         }
  652         conf_val = token;
  653 
  654         /* APPID configurations are for anything else - currently we only have ssl_reinspect */ 
  655         if (!(strcasecmp(conf_type, "appid")))
  656         {
  657             if (!(strcasecmp(conf_key, "max_tp_flow_depth")))
  658             {
  659                 max_tp_flow_depth = atoi(conf_val);
  660                 if (max_tp_flow_depth < MIN_MAX_TP_FLOW_DEPTH || max_tp_flow_depth > MAX_MAX_TP_FLOW_DEPTH)
  661                 {
  662                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_tp_flow_depth %d, must be between %d and %d\n.", max_tp_flow_depth, MIN_MAX_TP_FLOW_DEPTH, MAX_MAX_TP_FLOW_DEPTH););
  663                 }
  664                 else
  665                 {
  666                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: setting max thirdparty inspection flow depth to %d packets.\n", max_tp_flow_depth););
  667                     appidSC->max_tp_flow_depth = max_tp_flow_depth;
  668                 }
  669             }
  670             else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_interval")))
  671             {
  672                 host_port_app_cache_lookup_interval = atoi(conf_val);
  673                 if (host_port_app_cache_lookup_interval < MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL || host_port_app_cache_lookup_interval > MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL)
  674                 {
  675                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid host_port_app_cache_lookup_interval %d, must be between %d and %d\n.",
  676                                             host_port_app_cache_lookup_interval, MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL, MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL););
  677                 }
  678                 else
  679                 {
  680                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed every %d packet(s).\n", host_port_app_cache_lookup_interval););
  681                     appidSC->host_port_app_cache_lookup_interval = host_port_app_cache_lookup_interval;
  682                 }
  683             }
  684             else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_range")))
  685             {
  686                 host_port_app_cache_lookup_range = atoi(conf_val);
  687                 if (host_port_app_cache_lookup_range < MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE || host_port_app_cache_lookup_range > MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE)
  688                 {
  689                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid host_port_app_cache_lookup_range %d, must be between %d and %d\n.",
  690                                             host_port_app_cache_lookup_range, MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE, MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE););
  691                 }
  692                 else
  693                 {
  694                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed till maximum of %d packet(s) per session.\n", host_port_app_cache_lookup_range););
  695                     appidSC->host_port_app_cache_lookup_range = host_port_app_cache_lookup_range;
  696                 }
  697             }
  698             else if (!(strcasecmp(conf_key, "is_host_port_app_cache_runtime")))
  699             {
  700                 if (!(strcasecmp(conf_val, "disabled")))
  701                 {
  702                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache not configured for runtime modification.\n"););
  703                     appidSC->is_host_port_app_cache_runtime = 0;
  704                 }
  705             }
  706             else if (!(strcasecmp(conf_key, "check_host_port_app_cache")))
  707             {
  708                 if (!(strcasecmp(conf_val, "enabled")))
  709                 {
  710                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed for every flow.\n"););
  711                     appidSC->check_host_port_app_cache = 1;
  712                 }
  713             }
  714             else if (!(strcasecmp(conf_key, "check_host_cache_unknown_ssl")))
  715             {
  716                 if (!(strcasecmp(conf_val, "enabled")))
  717                 {
  718                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed for SSL flows not having either of server name or certificate.\n"););
  719                     appidSC->check_host_cache_unknown_ssl = 1;
  720                 }
  721             }
  722             else if (!(strcasecmp(conf_key, "recheck_for_unknown_appid")))
  723             {
  724                 if (!(strcasecmp(conf_val, "enabled")))
  725                 {
  726                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: Flows with unknown AppID's will not be ignored.\n"););
  727                     appidSC->recheck_for_unknown_appid = 1;
  728                 }
  729             }
  730             else if (!(strcasecmp(conf_key, "recheck_for_portservice_appid")))
  731             {
  732                 if (!(strcasecmp(conf_val, "enabled")))
  733                 {
  734                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: Checking hostPortCache for flows with only port service AppID.\n"););
  735                     appidSC->recheck_for_portservice_appid = 1;
  736                 }
  737             }
  738             else if (!(strcasecmp(conf_key, "tp_allow_probes")))
  739             {
  740                 if (!(strcasecmp(conf_val, "enabled")))
  741                 {
  742                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: TCP probes will be analyzed by NAVL.\n"););
  743                     appidSC->tp_allow_probes = 1;
  744                 }
  745             }
  746             else if (!(strcasecmp(conf_key, "tp_client_app")))
  747             {
  748                 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: if thirdparty reports app %d, we will use it as a client.\n", atoi(conf_val)););
  749                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_TP_CLIENT, pConfig);
  750             }
  751             else if (!(strcasecmp(conf_key, "ssl_reinspect")))
  752             {
  753                 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of SSL apps that get more granular inspection.\n", atoi(conf_val)););
  754                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_SSL_INSPECT, pConfig);
  755             }
  756             else if (!(strcasecmp(conf_key, "disable_safe_search")))
  757             {
  758                 if (!(strcasecmp(conf_val, "disabled")))
  759                 {
  760                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: disabling safe search enforcement.\n"););
  761                     appidSC->disable_safe_search = 1;
  762                 }
  763             }
  764             else if (!(strcasecmp(conf_key, "ssl_squelch")))
  765             {
  766                 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of SSL apps that may open a second SSL connection.\n", atoi(conf_val)););
  767                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_SSL_SQUELCH, pConfig);
  768             }
  769             else if (!(strcasecmp(conf_key, "defer_to_thirdparty")))
  770             {
  771                 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of apps where we should take thirdparty ID over the NDE's.\n", atoi(conf_val)););
  772                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_DEFER, pConfig);
  773             }
  774             else if (!(strcasecmp(conf_key, "defer_payload_to_thirdparty")))
  775             {
  776                 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of apps where we should take thirdparty payload ID over the NDE's.\n", atoi(conf_val)););
  777                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
  778             }
  779             else if (!(strcasecmp(conf_key, "chp_userid")))
  780             {
  781                 if (!(strcasecmp(conf_val, "disabled")))
  782                 {
  783                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP UserID collection disabled.\n"););
  784                     appidSC->chp_userid_disabled = 1;
  785                     continue;
  786                 }
  787             }
  788             else if (!(strcasecmp(conf_key, "chp_body_collection")))
  789             {
  790                 if (!(strcasecmp(conf_val, "disabled")))
  791                 {
  792                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP Body header reading disabled.\n"););
  793                     appidSC->chp_body_collection_disabled = 1;
  794                     continue;
  795                 }
  796             }
  797             else if (!(strcasecmp(conf_key, "chp_fflow")))
  798             {
  799                 if (!(strcasecmp(conf_val, "disabled")))
  800                 {
  801                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP future flow creation disabled.\n"););
  802                     appidSC->chp_fflow_disabled = 1;
  803                     continue;
  804                 }
  805             }
  806             else if (!(strcasecmp(conf_key, "ftp_userid")))
  807             {
  808                 if (!(strcasecmp(conf_val, "disabled")))
  809                 {
  810                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: FTP userID disabled.\n"););
  811                     appidSC->ftp_userid_disabled = 1;
  812                     continue;
  813                 }
  814             }
  815             else if (!(strcasecmp(conf_key, "max_bytes_before_service_fail")))
  816             {
  817                 uint64_t max_bytes_before_service_fail = atoi(conf_val);
  818                 if (max_bytes_before_service_fail < MIN_MAX_BYTES_BEFORE_SERVICE_FAIL)
  819                 {
  820                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_bytes_before_service_fail %"PRIu64" must be greater than %u\n.", max_bytes_before_service_fail, MIN_MAX_BYTES_BEFORE_SERVICE_FAIL ););
  821                 }
  822                 else
  823                     appidSC->max_bytes_before_service_fail = max_bytes_before_service_fail;
  824             }
  825             else if (!(strcasecmp(conf_key, "max_packet_before_service_fail")))
  826             {
  827                 uint16_t max_packet_before_service_fail = atoi(conf_val);
  828                 if (max_packet_before_service_fail < MIN_MAX_PACKET_BEFORE_SERVICE_FAIL)
  829                 {
  830                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_packet_before_service_fail %"PRIu16", must be greater than  %u \n.", max_packet_before_service_fail, MIN_MAX_PACKET_BEFORE_SRV_FAIL););
  831                 }
  832                 else
  833                     appidSC->max_packet_before_service_fail = max_packet_before_service_fail;
  834             }
  835             else if (!(strcasecmp(conf_key, "max_packet_service_fail_ignore_bytes")))
  836             {
  837                 uint16_t max_packet_service_fail_ignore_bytes = atoi(conf_val);
  838                 if (max_packet_service_fail_ignore_bytes < MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES)
  839                 {
  840                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_packet_service_fail_ignore_bytes  %"PRIu16", must be greater than %u\n.", max_packet_service_fail_ignore_bytes, MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES););
  841                 }
  842                 else
  843                     appidSC->max_packet_service_fail_ignore_bytes= max_packet_service_fail_ignore_bytes;
  844             }
  845             else if (!(strcasecmp(conf_key, "http_tunnel_detect")))
  846             {
  847                 if (!(strcasecmp(conf_val, "restart_and_reset")))
  848                 {
  849                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP tunnel detect set to restart and reset.\n"););
  850                     appidSC->http_tunnel_detect = HTTP_TUNNEL_DETECT_RESTART_AND_RESET;
  851                     continue;
  852                 }
  853             }
  854             /* App Priority bit set*/
  855             else if (!(strcasecmp(conf_key, "app_priority")))
  856             {
  857                 int temp_appid;
  858                 temp_appid = strtol(conf_val, NULL, 10 );
  859                 token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
  860                 if (token == NULL)
  861                 {
  862                     _dpd.errMsg("Could not read app_priority at line %u\n", line);
  863                     continue;
  864                 }
  865                 conf_val = token;
  866                 uint8_t temp_val;
  867                 temp_val = strtol(conf_val, NULL, 10 );
  868                 appInfoEntryPrioritySet (temp_appid, temp_val, pConfig);
  869                 DEBUG_WRAP(DebugMessage(DEBUG_APPID,"AppId: %d Setting priority bit %d .\n", temp_appid, temp_val););
  870             }
  871             else if (!(strcasecmp(conf_key, "referred_appId")))
  872             {
  873 
  874                 if (!(strcasecmp(conf_val, "disabled")))
  875                 {
  876                     appidSC->referred_appId_disabled = 1;
  877                     continue;
  878                 }
  879 
  880                 else if (!appidSC->referred_appId_disabled)
  881                 {
  882                     referred_app_index=0;
  883                     referred_app_index += sprintf(referred_app_list, "%d ", atoi(conf_val));
  884                     appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_REFERRED, pConfig);
  885 
  886                     while ((token = strtok(NULL, CONF_SEPARATORS_USR_APPID)) != NULL)
  887                     {
  888                         referred_app_index += sprintf(referred_app_list+referred_app_index, "%d ", atoi(token));
  889                         appInfoEntryFlagSet(atoi(token), APPINFO_FLAG_REFERRED, pConfig);
  890                     }
  891                     DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding appIds to list of referred web apps: %s\n", referred_app_list););
  892                 }
  893             }
  894             else if (!(strcasecmp(conf_key, "rtmp_max_packets")))
  895             {
  896                 appidSC->rtmp_max_packets = atoi(conf_val);
  897             }
  898             else if (!(strcasecmp(conf_key, "mdns_user_report")))
  899             {
  900                 appidSC->mdns_user_reporting = atoi(conf_val);
  901             }
  902             else if (!(strcasecmp(conf_key, "dns_host_report")))
  903             {
  904                 appidSC->dns_host_reporting = atoi(conf_val);
  905             }
  906             else if (!(strcasecmp(conf_key, "chp_body_max_bytes")))
  907             {
  908                 appidSC->chp_body_collection_max = atoi(conf_val);
  909             }
  910             else if (!(strcasecmp(conf_key, "ignore_thirdparty_appid")))
  911             {
  912                 _dpd.logMsg("AppId: adding app %d to list of ignore thirdparty apps.\n", atoi(conf_val));
  913                 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_IGNORE, pConfig);
  914             }
  915             else if (!(strcasecmp(conf_key, "http2_detection")))
  916             {
  917                 // This option will control our own HTTP/2 detection.  We can
  918                 // still be told externally, though, that it's HTTP/2 (either
  919                 // from HTTP Inspect or 3rd Party).  This is intended to be
  920                 // used to ask AppID to detect unencrypted HTTP/2 on non-std
  921                 // ports.
  922                 if (!(strcasecmp(conf_val, "disabled")))
  923                 {
  924                     _dpd.logMsg("AppId: disabling internal HTTP/2 detection.\n");
  925                     appidSC->http2_detection_enabled = 0;
  926                 }
  927                 else if (!(strcasecmp(conf_val, "enabled")))
  928                 {
  929                     _dpd.logMsg("AppId: enabling internal HTTP/2 detection.\n");
  930                     appidSC->http2_detection_enabled = 1;
  931                 }
  932                 else
  933                 {
  934                     _dpd.logMsg("AppId: ignoring invalid option for http2_detection: %s\n", conf_val);
  935                 }
  936             }
  937             else if (!(strcasecmp(conf_key, "send_state_sharing_updates")))
  938             {
  939                 if (!(strcasecmp(conf_val, "disabled")))
  940         {
  941                     _dpd.logMsg("AppId: Disabling state sharing updates.\n");
  942                     appidSC->send_state_sharing_updates = 0;
  943                 }
  944             }
  945             else if (!(strcasecmp(conf_key, "allow_port_wildcard_host_cache")))
  946             {
  947                 if (!(strcasecmp(conf_val, "enabled")))
  948                 {
  949                     _dpd.logMsg("AppId: Enabling wild card for port numbers in hostPortAppCache.\n");
  950                     appidSC->allow_port_wildcard_host_cache = 1;
  951                 }
  952             }
  953             else if (!(strcasecmp(conf_key, "bittorrent_aggressiveness")))
  954             {
  955                 int aggressiveness = atoi(conf_val);
  956                 _dpd.logMsg("AppId: bittorrent_aggressiveness %d\n", aggressiveness);
  957                 if (aggressiveness >= 50)
  958                 {
  959                     appidSC->recheck_for_unknown_appid = 1;
  960                     appidSC->recheck_for_portservice_appid = 1;
  961                     appidSC->host_port_app_cache_lookup_interval = 5;
  962                     appidSC->max_tp_flow_depth = 25;
  963                     appInfoEntryFlagSet(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER, pConfig);
  964                     appInfoEntryFlagSet(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
  965                 }
  966                 if (aggressiveness >= 80)
  967                 {
  968                     appidSC->allow_port_wildcard_host_cache = 1;
  969                 }
  970             }
  971             else if (!(strcasecmp(conf_key, "ultrasurf_aggressiveness")))
  972             {
  973                 int aggressiveness = atoi(conf_val);
  974                 _dpd.logMsg("AppId: ultrasurf_aggressiveness %d\n", aggressiveness);
  975                 if (aggressiveness >= 50)
  976                 {
  977                     appidSC->check_host_cache_unknown_ssl = 1;
  978                     appidSC->max_tp_flow_depth = 25;
  979                     appInfoEntryFlagSet(APP_ID_ULTRASURF, APPINFO_FLAG_DEFER, pConfig);
  980                     appInfoEntryFlagSet(APP_ID_ULTRASURF, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
  981                 }
  982                 if (aggressiveness >= 80)
  983                 {
  984                     appidSC->recheck_for_unknown_appid = 1;
  985                     appidSC->allow_port_wildcard_host_cache = 1;
  986                 }
  987             }
  988             else if (!(strcasecmp(conf_key, "psiphon_aggressiveness")))
  989             {
  990                 int aggressiveness = atoi(conf_val);
  991                 _dpd.logMsg("AppId: psiphon_aggressiveness %d\n", aggressiveness);
  992                 if (aggressiveness >= 50)
  993                 {
  994                     appidSC->check_host_cache_unknown_ssl = 1;
  995                     appidSC->max_tp_flow_depth = 25;
  996                     appInfoEntryFlagSet(APP_ID_PSIPHON, APPINFO_FLAG_DEFER, pConfig);
  997                     appInfoEntryFlagSet(APP_ID_PSIPHON, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
  998                 }
  999                 if (aggressiveness >= 80)
 1000                 {
 1001                     appidSC->recheck_for_unknown_appid = 1;
 1002                     appidSC->allow_port_wildcard_host_cache = 1;
 1003                 }
 1004             }
 1005             else if (!(strcasecmp(conf_key, "multipayload_max_packets")))
 1006             {
 1007                 appidSC->multipayload_max_packets = atoi(conf_val);
 1008                 _dpd.logMsg("AppId: Multipayload feature will scan up to %d packets.\n", 
 1009                     appidSC->multipayload_max_packets);
 1010             }
 1011         }
 1012     }
 1013     fclose(config_file);
 1014 }
 1015