"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-preprocessors/appid/fw_appid.c" (16 Oct 2020, 222111 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 "fw_appid.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 #include <stdint.h>
   22 #include <stdbool.h>
   23 #include <stdio.h>
   24 #include <stdlib.h>
   25 #include <string.h>
   26 #include <sys/types.h>
   27 #include <sys/stat.h>
   28 #include <stdlib.h>
   29 #include <netinet/in.h>
   30 #include <ctype.h>
   31 #include <dlfcn.h>
   32 #include <fcntl.h>
   33 #include <syslog.h>
   34 #ifndef WIN32
   35 #include <strings.h>
   36 #include <sys/time.h>
   37 #endif
   38 #include <pthread.h>
   39 #include "appIdApi.h"
   40 #include "fw_appid.h"
   41 #include "profiler.h"
   42 #include "client_app_base.h"
   43 #include "httpCommon.h"
   44 #include "luaDetectorApi.h"
   45 #include "http_url_patterns.h"
   46 #include "fw_appid.h"
   47 #include "detector_http.h"
   48 #include "service_ssl.h"
   49 #include "detector_dns.h"
   50 #include "flow.h"
   51 #include "common_util.h"
   52 #include "spp_appid.h"
   53 #include "hostPortAppCache.h"
   54 #include "lengthAppCache.h"
   55 #include "appInfoTable.h"
   56 #include "appIdStats.h"
   57 #include "sf_mlmp.h"
   58 #include "ip_funcs.h"
   59 #include "app_forecast.h"
   60 #include "thirdparty_appid_types.h"
   61 #include "thirdparty_appid_utils.h"
   62 #include "appInfoTable.h"
   63 #include "service_base.h"
   64 
   65 //#define DEBUG_APP_ID_SESSIONS   1
   66 //#define DEBUG_FW_APPID  1
   67 //#define DEBUG_FW_APPID_PORT 80
   68 
   69 #define MAX_ATTR_LEN           1024
   70 #define HTTP_PREFIX "http://"
   71 
   72 #define MULTI_BUF_SIZE 1024
   73 
   74 #define APP_MAPPING_FILE "appMapping.data"
   75 
   76 #ifdef RNA_DEBUG_PE
   77 static const char *MODULE_NAME = "fw_appid";
   78 #endif
   79 
   80 static volatile int app_id_debug_flag;
   81 static FWDebugSessionConstraints app_id_debug_info;
   82 char app_id_debug_session[FW_DEBUG_SESSION_ID_SIZE];
   83 bool app_id_debug_session_flag;
   84 
   85 #ifdef PERF_PROFILING
   86 PreprocStats tpPerfStats;
   87 PreprocStats tpLibPerfStats;
   88 PreprocStats httpPerfStats;
   89 PreprocStats clientMatchPerfStats;
   90 PreprocStats serviceMatchPerfStats;
   91 #endif
   92 
   93 #define HTTP_PATTERN_MAX_LEN    1024
   94 #define PORT_MAX 65535
   95 
   96 unsigned long app_id_ongoing_session = 0;
   97 unsigned long app_id_total_alloc = 0;
   98 unsigned long app_id_raw_packet_count = 0;
   99 unsigned long app_id_processed_packet_count = 0;
  100 unsigned long app_id_ignored_packet_count = 0;
  101 static tAppIdData *app_id_free_list;
  102 static tTmpAppIdData *tmp_app_id_free_list;
  103 static uint32_t snortInstance;
  104 int app_id_debug;
  105 static int ptype_scan_counts[NUMBER_OF_PTYPES];
  106 
  107 static void ProcessThirdPartyResults(SFSnortPacket* p, APPID_SESSION_DIRECTION direction, tAppIdData* appIdSession, int confidence, tAppId* proto_list, ThirdPartyAppIDAttributeData* attribute_data);
  108 static void ExamineRtmpMetadata(SFSnortPacket* p, APPID_SESSION_DIRECTION direction, tAppIdData *appIdSession);
  109 
  110 AppIdDebugHostInfo_t AppIdDebugHostInfo;
  111 
  112 static inline void appSharedDataFree(tAppIdData * sharedData)
  113 {
  114     sharedData->next = app_id_free_list;
  115     app_id_free_list = sharedData;
  116 }
  117 
  118 static inline void appTmpSharedDataFree(tTmpAppIdData * sharedData)
  119 {
  120     sharedData->next = tmp_app_id_free_list;
  121     tmp_app_id_free_list = sharedData;
  122 }
  123 
  124 static inline void appHttpFieldClear (httpSession *hsession)
  125 {
  126     if (hsession == NULL) return;
  127 
  128     if (hsession->referer)
  129     {
  130         free(hsession->referer);
  131         hsession->referer = NULL;
  132     }
  133     if (hsession->cookie)
  134     {
  135         free(hsession->cookie);
  136         hsession->cookie = NULL;
  137     }
  138     if (hsession->url)
  139     {
  140         free(hsession->url);
  141         hsession->url = NULL;
  142     }
  143     if (hsession->useragent)
  144     {
  145         free(hsession->useragent);
  146         hsession->useragent = NULL;
  147     }
  148     if (hsession->host)
  149     {
  150         free(hsession->host);
  151         hsession->host = NULL;
  152     }
  153     if (hsession->uri)
  154     {
  155         free(hsession->uri);
  156         hsession->uri = NULL;
  157     }
  158     if (hsession->content_type)
  159     {
  160         free(hsession->content_type);
  161         hsession->content_type = NULL;
  162     }
  163     if (hsession->location)
  164     {
  165         free(hsession->location);
  166         hsession->location = NULL;
  167     }
  168     if (hsession->body)
  169     {
  170         free(hsession->body);
  171         hsession->body = NULL;
  172     }
  173     if (hsession->req_body)
  174     {
  175         free(hsession->req_body);
  176         hsession->req_body = NULL;
  177     }
  178     if (hsession->server)
  179     {
  180         free(hsession->server);
  181         hsession->server = NULL;
  182     }
  183     if (hsession->x_working_with)
  184     {
  185         free(hsession->x_working_with);
  186         hsession->x_working_with = NULL;
  187     }
  188     if (hsession->xffAddr)
  189     {
  190         sfaddr_free(hsession->xffAddr);
  191         hsession->xffAddr = NULL;
  192     }
  193     if (hsession->xffPrecedence)
  194     {
  195         int i;
  196 
  197         for (i = 0; i < hsession->numXffFields; i++)
  198             free(hsession->xffPrecedence[i]);
  199         free(hsession->xffPrecedence);
  200         hsession->xffPrecedence = NULL;
  201     }
  202 }
  203 
  204 static inline void appHttpSessionDataFree (httpSession *hsession)
  205 {
  206     int i;
  207 
  208     if (hsession == NULL) return;
  209 
  210     appHttpFieldClear(hsession);
  211 
  212     if (hsession->new_field_contents)
  213     {
  214         for (i = 0; i < NUMBER_OF_PTYPES; i++)
  215         {
  216             if (NULL != hsession->new_field[i])
  217             {
  218                 free(hsession->new_field[i]);
  219                 hsession->new_field[i] = NULL;
  220             }
  221         }
  222     }
  223     if (hsession->fflow)
  224     {
  225         free(hsession->fflow);
  226         hsession->fflow = NULL;
  227     }
  228     if (hsession->via)
  229     {
  230         free(hsession->via);
  231         hsession->via = NULL;
  232     }
  233     if (hsession->content_type)
  234     {
  235         free(hsession->content_type);
  236         hsession->content_type = NULL;
  237     }
  238     if (hsession->response_code)
  239     {
  240         free(hsession->response_code);
  241         hsession->response_code = NULL;
  242     }
  243     if (hsession->tunDest)
  244     {
  245         free(hsession->tunDest);
  246         hsession->tunDest = NULL;
  247     }
  248 
  249     free(hsession);
  250 }
  251 
  252 static inline void appDNSSessionDataFree(dnsSession *dsession)
  253 {
  254     if (dsession == NULL) return;
  255     if (dsession->host)
  256     {
  257         free(dsession->host);
  258         dsession->host = NULL;
  259     }
  260     free(dsession);
  261 }
  262 
  263 static inline void appTlsSessionDataFree (tlsSession *tsession)
  264 {
  265     if (tsession == NULL) return;
  266 
  267     if (tsession->tls_host)
  268         free(tsession->tls_host);
  269     if (tsession->tls_cname)
  270         free(tsession->tls_cname);
  271     if (tsession->tls_orgUnit)
  272         free(tsession->tls_orgUnit);
  273     free(tsession);
  274 }
  275 
  276 #ifdef REG_TEST
  277 void appIdRegTestDumpEndOfSession(tAppIdData *appid_session)
  278 {
  279     if (appid_session == NULL)
  280         return;
  281 
  282     _dpd.logMsg("AppID End of Session...\n");
  283 
  284     _dpd.logMsg("    pickServiceAppId(appid_session) = %d\n", pickServiceAppId(appid_session));
  285     _dpd.logMsg("    pickPayloadId(appid_session) = %d\n", pickPayloadId(appid_session));
  286     _dpd.logMsg("    pickClientAppId(appid_session) = %d\n", pickClientAppId(appid_session));
  287     _dpd.logMsg("    pickMiscAppId(appid_session) = %d\n", pickMiscAppId(appid_session));
  288 
  289     if (appid_session->dsession != NULL)
  290     {
  291         _dpd.logMsg("    appid_session->dsession->host = %s\n", appid_session->dsession->host ?: "NULL");
  292         _dpd.logMsg("    appid_session->dsession->options_offset = %u\n", appid_session->dsession->options_offset);
  293     }
  294 
  295     if (appid_session->tsession != NULL)
  296     {
  297         _dpd.logMsg("    appid_session->tsession->tls_host = %s\n", appid_session->tsession->tls_host ?: "NULL");
  298     }
  299 
  300     _dpd.logMsg("    Flow is %s, ignore flag is %s\n",
  301         getAppIdFlag(appid_session, APPID_SESSION_OOO)? "out-of-order":"in-order",
  302         getAppIdFlag(appid_session, APPID_SESSION_IGNORE_FLOW)? "true":"false");
  303 }
  304 #endif
  305 
  306 void appSharedDataDelete(tAppIdData * sharedData)
  307 {
  308     RNAServiceSubtype *subtype;
  309 
  310     if (sharedData)
  311     {
  312 #ifdef DEBUG_FW_APPID
  313 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
  314         if (sharedData->service_port == DEBUG_FW_APPID_PORT)
  315 #endif
  316             fprintf(SF_DEBUG_FILE, "Deleting session %p\n", sharedData);
  317 #endif
  318         app_id_ongoing_session--;
  319 #ifdef REG_TEST
  320         if (appidStaticConfig->appid_reg_test_mode)
  321             appIdRegTestDumpEndOfSession(sharedData);
  322 #endif
  323         /*check daq flag */
  324         appIdStatsUpdate(sharedData);
  325 
  326         if (sharedData->ssn)
  327             FailInProcessService(sharedData, pAppidActiveConfig);
  328         AppIdFlowdataFree(sharedData);
  329 
  330         if (thirdparty_appid_module)
  331         {
  332             thirdparty_appid_module->session_delete(sharedData->tpsession, 0);    // we're completely done with it
  333             sharedData->tpsession = NULL;
  334         }
  335         free(sharedData->clientVersion);
  336         free(sharedData->serviceVendor);
  337         free(sharedData->serviceVersion);
  338         free(sharedData->netbios_name);
  339         while ((subtype = sharedData->subtype))
  340         {
  341             sharedData->subtype = subtype->next;
  342             free(*(void **)&subtype->service);
  343             free(*(void **)&subtype->vendor);
  344             free(*(void **)&subtype->version);
  345             free(subtype);
  346         }
  347         if (sharedData->candidate_service_list != NULL)
  348         {
  349             sflist_free(sharedData->candidate_service_list);
  350             sharedData->candidate_service_list = NULL;
  351         }
  352         if (sharedData->candidate_client_list != NULL)
  353         {
  354             sflist_free(sharedData->candidate_client_list);
  355             sharedData->candidate_client_list = NULL;
  356         }
  357         free(sharedData->username);
  358         free(sharedData->netbiosDomain);
  359         free(sharedData->payloadVersion);
  360         appHttpSessionDataFree(sharedData->hsession);
  361         appTlsSessionDataFree(sharedData->tsession);
  362         appDNSSessionDataFree(sharedData->dsession);
  363         sharedData->tsession = NULL;
  364         if (sharedData->multiPayloadList)
  365             sfghash_delete(sharedData->multiPayloadList);
  366         free(sharedData->firewallEarlyData);
  367         sharedData->firewallEarlyData = NULL;
  368 
  369         appSharedDataFree(sharedData);
  370     }
  371 }
  372 /* The snortId_for_unsynchronized value is to cheaply insure we get
  373    a unique value from snort's list that guarantees no other preprocessor has it in use. */
  374 
  375 static int16_t snortId_for_unsynchronized;
  376 static int16_t snortId_for_ftp_data;
  377 static int16_t snortId_for_http2;
  378 
  379 tAppIdData* appSharedDataAlloc(uint8_t proto,  const struct in6_addr *ip, uint16_t port)
  380 {
  381     static uint32_t gFlowId;
  382     tAppIdData *data;
  383 
  384     app_id_ongoing_session++;
  385     if (app_id_free_list)
  386     {
  387         data = app_id_free_list;
  388         app_id_free_list = data->next;
  389         memset(data, 0, sizeof(*data));
  390     }
  391     else if (!(data = calloc(1, sizeof(*data))))
  392         DynamicPreprocessorFatalMessage("Could not allocate tAppIdData data");
  393 
  394     app_id_total_alloc++;
  395 
  396     if (thirdparty_appid_module)
  397         if (!(data->tpsession = thirdparty_appid_module->session_create()))
  398             DynamicPreprocessorFatalMessage("Could not allocate tAppIdData->tpsession data");
  399 
  400     data->flowId = ++gFlowId;
  401     data->common.fsf_type.flow_type = APPID_SESSION_TYPE_NORMAL;
  402     data->proto = proto;
  403     data->common.initiator_ip = *ip;
  404     data->common.initiator_port = port;
  405     data->snortId = snortId_for_unsynchronized;
  406     data->search_support_type = SEARCH_SUPPORT_TYPE_UNKNOWN;
  407     return data;
  408 }
  409 
  410 static inline tAppIdData* appSharedCreateData(const SFSnortPacket *p, uint8_t proto, APPID_SESSION_DIRECTION direction)
  411 {
  412 #ifdef DEBUG_FW_APPID
  413     static unsigned long packet_count;
  414 #endif
  415     tAppIdData *data;
  416     sfaddr_t *ip;
  417 
  418     ip = (direction == APP_ID_FROM_INITIATOR) ? GET_SRC_IP(p) : GET_DST_IP(p);
  419     data = appSharedDataAlloc(proto, (struct in6_addr*)sfaddr_get_ip6_ptr(ip) ,  0 );
  420 
  421     if ((proto == IPPROTO_TCP || proto == IPPROTO_UDP) && p->src_port != p->dst_port)
  422         data->common.initiator_port = (direction == APP_ID_FROM_INITIATOR) ? p->src_port : p->dst_port;
  423     data->ssn = p->stream_session;
  424 #ifdef DEBUG_FW_APPID
  425 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
  426         if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
  427 #endif
  428             fprintf(SF_DEBUG_FILE, "pkt %lu : tAppIdData: Allocated %p\n", ++packet_count, data);
  429 #endif
  430     data->stats.firstPktsecond = p->pkt_header->ts.tv_sec;
  431 
  432     _dpd.sessionAPI->set_application_data(p->stream_session, PP_APP_ID, data,
  433             (void (*)(void *))appSharedDataDelete);
  434     return data;
  435 }
  436 
  437 static inline void appSharedReInitData(tAppIdData* session)
  438 {
  439     session->miscAppId = APP_ID_NONE;
  440 
  441     //payload
  442     if (isSslServiceAppId(session->tpAppId))
  443     {
  444         session->payloadAppId = session->referredPayloadAppId = session->tpPayloadAppId =  APP_ID_NONE;
  445         clearAppIdFlag(session, APPID_SESSION_CONTINUE);
  446         if (session->payloadVersion)
  447         {
  448             free(session->payloadVersion);
  449             session->payloadVersion = NULL;
  450         }
  451         if (session->hsession && session->hsession->url)
  452         {
  453             free(session->hsession->url);
  454             session->hsession->url = NULL;
  455         }
  456     }
  457 
  458     //service
  459     if (!getAppIdFlag(session, APPID_SESSION_STICKY_SERVICE))
  460     {
  461 
  462         session->tpAppId = session->serviceAppId = session->portServiceAppId = APP_ID_NONE;
  463         if (session->serviceVendor)
  464         {
  465             free(session->serviceVendor);
  466             session->serviceVendor = NULL;
  467         }
  468         if (session->serviceVersion)
  469         {
  470             free(session->serviceVersion);
  471             session->serviceVersion = NULL;
  472         }
  473 
  474         IP_CLEAR(session->service_ip);
  475         session->service_port = 0;
  476         session->rnaServiceState = RNA_STATE_NONE;
  477         session->serviceData = NULL;
  478         AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
  479 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  480         session->serviceAsId = 0xFF;
  481 #endif
  482 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
  483         session->carrierId = 0;
  484 #endif
  485     }
  486 
  487     //client
  488     session->clientAppId = session->clientServiceAppId = APP_ID_NONE;
  489     if (session->clientVersion)
  490     {
  491         free(session->clientVersion);
  492         session->clientVersion = NULL;
  493     }
  494     session->rnaClientState = RNA_STATE_NONE;
  495     session->clientData = NULL;
  496     if (session->candidate_client_list)
  497     {
  498         sflist_free(session->candidate_client_list);
  499         session->candidate_client_list = NULL;
  500     }
  501     session->num_candidate_clients_tried = 0;
  502 
  503     AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
  504 
  505     //3rd party cleaning
  506     if (thirdparty_appid_module)
  507         thirdparty_appid_module->session_delete(session->tpsession, 1);
  508     session->init_tpPackets = 0;
  509     session->resp_tpPackets = 0;
  510 
  511     session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
  512     clearAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED|APPID_SESSION_CLIENT_DETECTED|APPID_SESSION_SSL_SESSION|APPID_SESSION_HTTP_SESSION|APPID_SESSION_APP_REINSPECT);
  513 }
  514 void fwAppIdFini(tAppIdConfig *pConfig)
  515 {
  516 #ifdef APPID_FULL_CLEANUP
  517     tAppIdData *app_id;
  518     tTmpAppIdData *tmp_app_id;
  519 
  520     while ((app_id = app_id_free_list))
  521     {
  522         app_id_free_list = app_id->next;
  523         free(app_id);
  524     }
  525 
  526     while ((tmp_app_id = tmp_app_id_free_list))
  527     {
  528         tmp_app_id_free_list = tmp_app_id->next;
  529         free(tmp_app_id);
  530     }
  531     AppIdFlowdataFini();
  532 #endif
  533 
  534     appInfoTableFini(pConfig);
  535 }
  536 
  537 static inline int PENetworkMatch(const sfaddr_t *pktAddr, const PortExclusion *pe)
  538 {
  539     const uint32_t* pkt = sfaddr_get_ip6_ptr(pktAddr);
  540     const uint32_t* nm = pe->netmask.s6_addr32;
  541     const uint32_t* peIP = pe->ip.s6_addr32;
  542     return (((pkt[0] & nm[0]) == peIP[0])
  543             && ((pkt[1] & nm[1]) == peIP[1])
  544             && ((pkt[2] & nm[2]) == peIP[2])
  545             && ((pkt[3] & nm[3]) == peIP[3]));
  546 }
  547 
  548 static inline int checkPortExclusion(const SFSnortPacket *pkt, int reversed)
  549 {
  550     SF_LIST * *src_port_exclusions;
  551     SF_LIST * *dst_port_exclusions;
  552     SF_LIST *pe_list;
  553     PortExclusion *pe;
  554     sfaddr_t *s_ip;
  555     uint16_t port;
  556     tAppIdConfig *pConfig = appIdActiveConfigGet();
  557 
  558     if (IsTCP(pkt))
  559     {
  560         src_port_exclusions = pConfig->tcp_port_exclusions_src;
  561         dst_port_exclusions = pConfig->tcp_port_exclusions_dst;
  562     }
  563     else if (IsUDP(pkt))
  564     {
  565         src_port_exclusions = pConfig->udp_port_exclusions_src;
  566         dst_port_exclusions = pConfig->udp_port_exclusions_dst;
  567     }
  568     else
  569         return 0;
  570 
  571     /* check the source port */
  572     port = reversed ? pkt->dst_port : pkt->src_port;
  573     if( port && (pe_list=src_port_exclusions[port]) != NULL )
  574     {
  575         s_ip = reversed ? GET_DST_IP(pkt) : GET_SRC_IP(pkt);
  576 
  577         /* walk through the list of port exclusions for this port */
  578         for (pe=(PortExclusion *)sflist_first(pe_list);
  579                 pe;
  580                 pe=(PortExclusion *)sflist_next(pe_list))
  581         {
  582             if( PENetworkMatch(s_ip, pe))
  583             {
  584 #ifdef RNA_DEBUG_PE
  585                 char inetBuffer[INET6_ADDRSTRLEN];
  586                 inetBuffer[0] = 0;
  587                 inet_ntop(sfaddr_family(s_ip), (void *)sfaddr_get_ptr(s_ip), inetBuffer, sizeof(inetBuffer));
  588 
  589                 SFDEBUG(MODULE_NAME, "excluding src port: %d",port);
  590                 SFDEBUG(MODULE_NAME, "for addresses src: %s", inetBuffer);
  591 #endif
  592                 return 1;
  593             }
  594         }
  595     }
  596 
  597     /* check the dest port */
  598     port = reversed ? pkt->src_port : pkt->dst_port;
  599     if( port && (pe_list=dst_port_exclusions[port]) != NULL )
  600     {
  601         s_ip = reversed ? GET_SRC_IP(pkt) : GET_DST_IP(pkt);
  602 
  603         /* walk through the list of port exclusions for this port */
  604         for (pe=(PortExclusion *)sflist_first(pe_list);
  605                 pe;
  606                 pe=(PortExclusion *)sflist_next(pe_list))
  607         {
  608             if( PENetworkMatch(s_ip, pe))
  609             {
  610 #ifdef RNA_DEBUG_PE
  611                 char inetBuffer[INET6_ADDRSTRLEN];
  612                 inetBuffer[0] = 0;
  613                 inet_ntop(sfaddr_family(s_ip), (void *)sfaddr_get_ptr(s_ip), inetBuffer, sizeof(inetBuffer));
  614                 SFDEBUG(MODULE_NAME, "excluding dst port: %d",port);
  615                 SFDEBUG(MODULE_NAME, "for addresses dst: %s", inetBuffer);
  616 #endif
  617                 return 1;
  618             }
  619         }
  620     }
  621 
  622     return 0;
  623 }
  624 
  625 static inline bool fwAppIdDebugCheck(void *lwssn, tAppIdData *session, volatile int debug_flag,
  626         FWDebugSessionConstraints *info, char *debug_session, APPID_SESSION_DIRECTION direction)
  627 {
  628     if (debug_flag)
  629     {
  630         const StreamSessionKey *key;
  631 
  632         key = _dpd.sessionAPI->get_key_from_session_ptr(lwssn);
  633         if ((!info->protocol || info->protocol == key->protocol) &&
  634             (((!info->sport || info->sport == key->port_l) &&
  635               (!info->sip_flag || memcmp(&info->sip, key->ip_l, sizeof(info->sip)) == 0) &&
  636               (!info->dport || info->dport == key->port_h) &&
  637               (!info->dip_flag || memcmp(&info->dip, key->ip_h, sizeof(info->dip)) == 0)) ||
  638              ((!info->sport || info->sport == key->port_h) &&
  639                (!info->sip_flag || memcmp(&info->sip, key->ip_h, sizeof(info->sip)) == 0) &&
  640                (!info->dport || info->dport == key->port_l) &&
  641                (!info->dip_flag || memcmp(&info->dip, key->ip_l, sizeof(info->dip)) == 0))))
  642         {
  643             int af;
  644             const struct in6_addr* sip;
  645             const struct in6_addr* dip;
  646             unsigned offset;
  647             uint16_t sport;
  648             uint16_t dport;
  649             char sipstr[INET6_ADDRSTRLEN];
  650             char dipstr[INET6_ADDRSTRLEN];
  651 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  652             uint16_t sAsId; 
  653             uint16_t dAsId;
  654 #endif
  655             if (session && session->common.fsf_type.flow_type != APPID_SESSION_TYPE_IGNORE)
  656             {
  657                 if (session->common.initiator_port)
  658                 {
  659                     if (session->common.initiator_port == key->port_l)
  660                     {
  661                         sip = (const struct in6_addr*)key->ip_l;
  662                         dip = (const struct in6_addr*)key->ip_h;
  663                         sport = key->port_l;
  664                         dport = key->port_h;
  665 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  666                         sAsId = key->addressSpaceId_l;
  667                         dAsId = key->addressSpaceId_h;
  668 #endif
  669                     }
  670                     else
  671                     {
  672                         sip = (const struct in6_addr*)key->ip_h;
  673                         dip = (const struct in6_addr*)key->ip_l;
  674                         sport = key->port_h;
  675                         dport = key->port_l;
  676 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  677                         sAsId = key->addressSpaceId_h;
  678                         dAsId = key->addressSpaceId_l;
  679 #endif
  680                     }
  681                 }
  682                 else if (memcmp(&session->common.initiator_ip, key->ip_l, sizeof(session->common.initiator_ip))==0)
  683                 {
  684                     sip = (const struct in6_addr*)key->ip_l;
  685                     dip = (const struct in6_addr*)key->ip_h;
  686                     sport = key->port_l;
  687                     dport = key->port_h;
  688 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  689                     sAsId = key->addressSpaceId_l;
  690                     dAsId = key->addressSpaceId_h;
  691 #endif
  692                 }
  693                 else
  694                 {
  695                     sip = (const struct in6_addr*)key->ip_h;
  696                     dip = (const struct in6_addr*)key->ip_l;
  697                     sport = key->port_h;
  698                     dport = key->port_l;
  699 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  700                     sAsId = key->addressSpaceId_h;
  701                     dAsId = key->addressSpaceId_l;
  702 #endif
  703                 }
  704             }
  705             else
  706             {
  707                 sip = (const struct in6_addr*)key->ip_l;
  708                 dip = (const struct in6_addr*)key->ip_h;
  709                 sport = key->port_l;
  710                 dport = key->port_h;
  711 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  712                 sAsId = key->addressSpaceId_l;
  713                 dAsId = key->addressSpaceId_h;
  714 #endif
  715             }
  716             sipstr[0] = 0;
  717             if (sip->s6_addr32[0] || sip->s6_addr32[1] || sip->s6_addr16[4] || (sip->s6_addr16[5] && sip->s6_addr16[5] != 0xFFFF))
  718             {
  719                 af = AF_INET6;
  720                 offset = 0;
  721             }
  722             else
  723             {
  724                 af = AF_INET;
  725                 offset = 12;
  726             }
  727             inet_ntop(af, &sip->s6_addr[offset], sipstr, sizeof(sipstr));
  728             dipstr[0] = 0;
  729             if (dip->s6_addr32[0] || dip->s6_addr32[1] || dip->s6_addr16[4] || (dip->s6_addr16[5] && dip->s6_addr16[5] != 0xFFFF))
  730             {
  731                 af = AF_INET6;
  732                 offset = 0;
  733             }
  734             else
  735             {
  736                 af = AF_INET;
  737                 offset = 12;
  738             }
  739             inet_ntop(af, &dip->s6_addr[offset], dipstr, sizeof(dipstr));
  740 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
  741             uint32_t cid = key->carrierId;
  742 #ifdef HAVE_DAQ_ADDRESS_SPACE_ID
  743 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  744             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u-%u I %u CID %u",
  745                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  746                      (direction == APP_ID_FROM_INITIATOR) ? "":" R",
  747                      sAsId, dAsId, (unsigned)snortInstance, (unsigned)cid);
  748 #else
  749             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u I %u CID %u",
  750                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  751                      (direction == APP_ID_FROM_INITIATOR) ? "":" R",
  752                      (unsigned)key->addressSpaceId, (unsigned)snortInstance, (unsigned)cid);
  753 #endif
  754 #else
  755             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s I %u CID %u",
  756                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  757                      (direction == APP_ID_FROM_INITIATOR) ? "":" R", (unsigned)snortInstance,
  758                      (unsigned)cid );
  759 #endif
  760 #else /* No carrierid support */
  761 #ifdef HAVE_DAQ_ADDRESS_SPACE_ID
  762 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
  763             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u-%u I %u",
  764                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  765                      (direction == APP_ID_FROM_INITIATOR) ? "":" R",
  766                      sAsId, dAsId, (unsigned)snortInstance);
  767 #else
  768             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u I %u",
  769                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  770                      (direction == APP_ID_FROM_INITIATOR) ? "":" R",
  771                      (unsigned)key->addressSpaceId, (unsigned)snortInstance);
  772 #endif
  773 #else
  774             snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s I %u",
  775                      sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->protocol,
  776                      (direction == APP_ID_FROM_INITIATOR) ? "":" R", (unsigned)snortInstance);
  777 #endif
  778 #endif
  779             return true;
  780         }
  781     }
  782     return false;
  783 }
  784 
  785 static inline void appIdDebugParse(const char *desc, const uint8_t *data, uint32_t length,
  786                           volatile int *debug_flag, FWDebugSessionConstraints *info)
  787 {
  788     *debug_flag = 0;
  789     memset(info, 0, sizeof(*info));
  790     do
  791     {
  792         if (length >= sizeof(info->protocol))
  793         {
  794             info->protocol = *data;
  795             length -= sizeof(info->protocol);
  796             data += sizeof(info->protocol);
  797         }
  798         else
  799             break;
  800 
  801         if (length >= sizeof(info->sip))
  802         {
  803 
  804             memcpy(&info->sip, data, sizeof(info->sip));
  805             if (info->sip.s6_addr32[1] || info->sip.s6_addr32[2] || info->sip.s6_addr32[3])
  806                 info->sip_flag = 1;
  807             else if (info->sip.s6_addr32[0])
  808             {
  809                 info->sip.s6_addr32[3] = info->sip.s6_addr32[0];
  810                 info->sip.s6_addr32[0] = 0;
  811                 info->sip.s6_addr16[5] = 0xFFFF;
  812                 info->sip_flag = 1;
  813             }
  814             length -= sizeof(info->sip);
  815             data += sizeof(info->sip);
  816         }
  817         else
  818             break;
  819 
  820         if (length >= sizeof(info->sport))
  821         {
  822             memcpy(&info->sport, data, sizeof(info->sport));
  823             length -= sizeof(info->sport);
  824             data += sizeof(info->sport);
  825         }
  826         else
  827             break;
  828 
  829         if (length >= sizeof(info->dip))
  830         {
  831             memcpy(&info->dip, data, sizeof(info->dip));
  832             if (info->dip.s6_addr32[1] || info->dip.s6_addr32[2] || info->dip.s6_addr32[3])
  833                 info->dip_flag = 1;
  834             else if (info->dip.s6_addr32[0])
  835             {
  836                 info->dip.s6_addr32[3] = info->dip.s6_addr32[0];
  837                 info->dip.s6_addr32[0] = 0;
  838                 info->dip.s6_addr16[5] = 0xFFFF;
  839                 info->dip_flag = 1;
  840             }
  841             length -= sizeof(info->dip);
  842             data += sizeof(info->dip);
  843         }
  844         else
  845             break;
  846 
  847         if (length >= sizeof(info->dport))
  848         {
  849             memcpy(&info->dport, data, sizeof(info->dport));
  850             length -= sizeof(info->dport);
  851             data += sizeof(info->dport);
  852         }
  853         else
  854             break;
  855     } while (0);
  856 
  857     if (info->protocol || info->sip_flag || info->sport || info->dip_flag || info->dport)
  858     {
  859         int saf;
  860         int daf;
  861         char sipstr[INET6_ADDRSTRLEN];
  862         char dipstr[INET6_ADDRSTRLEN];
  863 
  864         if (!info->sip.s6_addr32[0] && !info->sip.s6_addr32[0] && !info->sip.s6_addr16[4] &&
  865             info->sip.s6_addr16[5] == 0xFFFF)
  866         {
  867             saf = AF_INET;
  868         }
  869         else
  870             saf = AF_INET6;
  871         if (!info->dip.s6_addr32[0] && !info->dip.s6_addr32[0] && !info->dip.s6_addr16[4] &&
  872             info->dip.s6_addr16[5] == 0xFFFF)
  873         {
  874             daf = AF_INET;
  875         }
  876         else
  877             daf = AF_INET6;
  878         if (!info->sip_flag)
  879             saf = daf;
  880         if (!info->dip_flag)
  881             daf = saf;
  882         sipstr[0] = 0;
  883         inet_ntop(saf, saf == AF_INET ? &info->sip.s6_addr32[3] : info->sip.s6_addr32, sipstr, sizeof(sipstr));
  884         dipstr[0] = 0;
  885         inet_ntop(daf, daf == AF_INET ? &info->dip.s6_addr32[3] : info->dip.s6_addr32, dipstr, sizeof(dipstr));
  886         _dpd.logMsg("Debugging %s with %s-%u and %s-%u %u\n", desc,
  887                     sipstr, (unsigned)info->sport,
  888                     dipstr, (unsigned)info->dport,
  889                     (unsigned)info->protocol);
  890         *debug_flag = 1;
  891     }
  892     else
  893         _dpd.logMsg("Debugging %s disabled\n", desc);
  894 }
  895 int AppIdDebug(uint16_t type, const uint8_t *data, uint32_t length, void **new_context,
  896                char* statusBuf, int statusBuf_len)
  897 {
  898     appIdDebugParse("appId", data, length, &app_id_debug_flag, &app_id_debug_info);
  899     return 0;
  900 }
  901 
  902 unsigned isIPv4HostMonitored(uint32_t ip4, int32_t zone)
  903 {
  904     NetworkSet *net_list;
  905     unsigned flags;
  906     tAppIdConfig *pConfig = appIdActiveConfigGet();
  907 
  908     if (zone >= 0 && zone < MAX_ZONES && pConfig->net_list_by_zone[zone])
  909         net_list = pConfig->net_list_by_zone[zone];
  910     else
  911         net_list = pConfig->net_list;
  912 
  913     NetworkSet_ContainsEx(net_list, ip4, &flags);
  914     return flags;
  915 }
  916 
  917 static inline unsigned isIPMonitored(const SFSnortPacket *p, int dst)
  918 {
  919     uint32_t ipAddr;
  920     sfaddr_t *sf_ip;
  921     struct in_addr ip;
  922     NetworkSet *net_list;
  923     unsigned flags;
  924     int32_t zone;
  925     NSIPv6Addr ip6;
  926     tAppIdConfig *pConfig = appIdActiveConfigGet();
  927 
  928     if (!dst)
  929     {
  930         zone = p->pkt_header->ingress_group;
  931         sf_ip = GET_SRC_IP(p);
  932     }
  933     else
  934     {
  935         zone = (p->pkt_header->egress_index == DAQ_PKTHDR_UNKNOWN) ? p->pkt_header->ingress_group : p->pkt_header->egress_group;
  936         if (zone == DAQ_PKTHDR_FLOOD)
  937             return 0;
  938         sf_ip = GET_DST_IP(p);
  939     }
  940     if (zone >= 0 && zone < MAX_ZONES && pConfig->net_list_by_zone[zone])
  941         net_list = pConfig->net_list_by_zone[zone];
  942     else
  943         net_list = pConfig->net_list;
  944     if (sfaddr_family(sf_ip) == AF_INET)
  945     {
  946         ip.s_addr = sfaddr_get_ip4_value(sf_ip);
  947         if (ip.s_addr == 0xFFFFFFFF)
  948             return IPFUNCS_CHECKED;
  949         ipAddr = ntohl(ip.s_addr);
  950         NetworkSet_ContainsEx(net_list, ipAddr, &flags);
  951     }
  952     else
  953     {
  954         memcpy(&ip6, sfaddr_get_ptr(sf_ip), sizeof(ip6));
  955         NSIPv6AddrNtoH(&ip6);
  956         NetworkSet_Contains6Ex(net_list, &ip6, &flags);
  957     }
  958     return flags | IPFUNCS_CHECKED;
  959 }
  960 
  961 static inline int isSpecialSessionMonitored(const SFSnortPacket *p)
  962 {
  963     sfaddr_t *srcAddr;
  964 
  965     srcAddr = GET_SRC_IP(p);
  966     if (sfaddr_family(srcAddr) == AF_INET)
  967     {
  968         if (IsUDP(p) && ((p->src_port == 68 && p->dst_port == 67) || (p->src_port == 67 && p->dst_port == 68)))
  969         {
  970             return 1;
  971         }
  972     }
  973     return 0;
  974 }
  975 
  976 static inline uint64_t isSessionMonitored(const SFSnortPacket *p, APPID_SESSION_DIRECTION dir, tAppIdData *session)
  977 {
  978     uint64_t flags;
  979     uint64_t flow_flags = 0;
  980     tAppIdConfig *pConfig = appIdActiveConfigGet();
  981 
  982     if (pConfig == NULL)
  983         return flow_flags;
  984 
  985     if (pConfig->isAppIdAlwaysRequired == APPID_REQ_UNINITIALIZED)
  986         pConfig->isAppIdAlwaysRequired = _dpd.isAppIdRequired() ? APPID_REQ_YES : APPID_REQ_NO;
  987     if (pConfig->isAppIdAlwaysRequired == APPID_REQ_YES)
  988         flow_flags |= APPID_SESSION_DISCOVER_APP;
  989 
  990     flow_flags |= (dir == APP_ID_FROM_INITIATOR) ? APPID_SESSION_INITIATOR_SEEN : APPID_SESSION_RESPONDER_SEEN;
  991     if (session)
  992     {
  993         flow_flags |= session->common.flags;
  994         if (session->common.policyId != appIdPolicyId)
  995         {
  996             if (checkPortExclusion(p, dir == APP_ID_FROM_RESPONDER))
  997             {
  998                 flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN | APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
  999                 flow_flags &= ~(APPID_SESSION_INITIATOR_MONITORED | APPID_SESSION_RESPONDER_MONITORED);
 1000                 return flow_flags;
 1001             }
 1002             if (dir == APP_ID_FROM_INITIATOR)
 1003             {
 1004                 if (getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
 1005                 {
 1006                     flags = isIPMonitored(p, 0);
 1007                     if (flags & IPFUNCS_HOSTS_IP)
 1008                     {
 1009                         flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1010                         AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR0;
 1011                     }
 1012                     else
 1013                         flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
 1014                 }
 1015 
 1016                 if (getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
 1017                 {
 1018                     flags = isIPMonitored(p, 1);
 1019                     if (flags & IPFUNCS_HOSTS_IP)
 1020                         flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1021                     else
 1022                         flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
 1023                 }
 1024             }
 1025             else
 1026             {
 1027                 if (getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
 1028                 {
 1029                     flags = isIPMonitored(p, 0);
 1030                     if (flags & IPFUNCS_HOSTS_IP)
 1031                         flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1032                     else
 1033                         flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
 1034                 }
 1035 
 1036                 if (getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
 1037                 {
 1038                     flags = isIPMonitored(p, 1);
 1039                     if (flags & IPFUNCS_HOSTS_IP)
 1040                     {
 1041                         flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1042                         AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR1;
 1043                     }
 1044                     else
 1045                         flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
 1046                 }
 1047             }
 1048         }
 1049 
 1050         if (getAppIdFlag(session, APPID_SESSION_BIDIRECTIONAL_CHECKED) == APPID_SESSION_BIDIRECTIONAL_CHECKED)
 1051             return flow_flags;
 1052 
 1053         if (dir == APP_ID_FROM_INITIATOR)
 1054         {
 1055             if (!getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
 1056             {
 1057                 flags = isIPMonitored(p, 0);
 1058                 flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
 1059                 if (flags & IPFUNCS_HOSTS_IP)
 1060                 {
 1061                     flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1062                     AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR2;
 1063                 }
 1064                 if (flags & IPFUNCS_USER_IP)
 1065                     flow_flags |= APPID_SESSION_DISCOVER_USER;
 1066                 if (flags & IPFUNCS_APPLICATION)
 1067                     flow_flags |= APPID_SESSION_DISCOVER_APP;
 1068 
 1069                 if (isSpecialSessionMonitored(p))
 1070                 {
 1071                     flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1072                 }
 1073             }
 1074             if (!(flow_flags & APPID_SESSION_DISCOVER_APP) && !getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
 1075             {
 1076                 flags = isIPMonitored(p, 1);
 1077                 if (flags & IPFUNCS_CHECKED)
 1078                     flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
 1079                 if (flags & IPFUNCS_HOSTS_IP)
 1080                     flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1081                 if (flags & IPFUNCS_APPLICATION)
 1082                     flow_flags |= APPID_SESSION_DISCOVER_APP;
 1083                 if (isSpecialSessionMonitored(p))
 1084                 {
 1085                     flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1086                 }
 1087             }
 1088         }
 1089         else
 1090         {
 1091             if (!getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
 1092             {
 1093                 flags = isIPMonitored(p, 0);
 1094                 flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
 1095                 if (flags & IPFUNCS_HOSTS_IP)
 1096                     flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1097                 if (flags & IPFUNCS_APPLICATION)
 1098                     flow_flags |= APPID_SESSION_DISCOVER_APP;
 1099                 if (isSpecialSessionMonitored(p))
 1100                 {
 1101                     flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1102                 }
 1103             }
 1104             if (!(flow_flags & APPID_SESSION_DISCOVER_APP) && !getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
 1105             {
 1106                 flags = isIPMonitored(p, 1);
 1107                 if (flags & IPFUNCS_CHECKED)
 1108                     flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
 1109                 if (flags & IPFUNCS_HOSTS_IP)
 1110                 {
 1111                     flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1112                     AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR3;
 1113                 }
 1114                 if (flags & IPFUNCS_USER_IP)
 1115                     flow_flags |= APPID_SESSION_DISCOVER_USER;
 1116                 if (flags & IPFUNCS_APPLICATION)
 1117                     flow_flags |= APPID_SESSION_DISCOVER_APP;
 1118                 if (isSpecialSessionMonitored(p))
 1119                 {
 1120                     flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1121                 }
 1122             }
 1123         }
 1124     }
 1125     else if (checkPortExclusion(p, 0))
 1126     {
 1127         flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN | APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
 1128     }
 1129     else if (dir == APP_ID_FROM_INITIATOR)
 1130     {
 1131         flags = isIPMonitored(p, 0);
 1132         flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
 1133         if (flags & IPFUNCS_HOSTS_IP)
 1134         {
 1135             flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1136             AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR4;
 1137         }
 1138         if (flags & IPFUNCS_USER_IP)
 1139             flow_flags |= APPID_SESSION_DISCOVER_USER;
 1140         if (flags & IPFUNCS_APPLICATION)
 1141             flow_flags |= APPID_SESSION_DISCOVER_APP;
 1142         if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
 1143         {
 1144             flags = isIPMonitored(p, 1);
 1145             if (flags & IPFUNCS_CHECKED)
 1146                 flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
 1147             if (flags & IPFUNCS_HOSTS_IP)
 1148                 flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1149             if (flags & IPFUNCS_APPLICATION)
 1150                 flow_flags |= APPID_SESSION_DISCOVER_APP;
 1151         }
 1152         if (isSpecialSessionMonitored(p))
 1153         {
 1154             flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1155         }
 1156     }
 1157     else
 1158     {
 1159         flags = isIPMonitored(p, 0);
 1160         flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
 1161         if (flags & IPFUNCS_HOSTS_IP)
 1162             flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
 1163         if (flags & IPFUNCS_APPLICATION)
 1164             flow_flags |= APPID_SESSION_DISCOVER_APP;
 1165         if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
 1166         {
 1167             flags = isIPMonitored(p, 1);
 1168             if (flags & IPFUNCS_CHECKED)
 1169                 flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
 1170             if (flags & IPFUNCS_HOSTS_IP)
 1171             {
 1172                 flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
 1173                 AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_MONITOR5;
 1174             }
 1175             if (flags & IPFUNCS_USER_IP)
 1176                 flow_flags |= APPID_SESSION_DISCOVER_USER;
 1177             if (flags & IPFUNCS_APPLICATION)
 1178                 flow_flags |= APPID_SESSION_DISCOVER_APP;
 1179         }
 1180 
 1181         if (isSpecialSessionMonitored(p))
 1182         {
 1183             flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
 1184         }
 1185     }
 1186 
 1187     return flow_flags;
 1188 }
 1189 
 1190 void CheckDetectorCallback(const SFSnortPacket *p, tAppIdData *session, APPID_SESSION_DIRECTION direction, tAppId appId, const tAppIdConfig *pConfig)
 1191 {
 1192     AppInfoTableEntry *entry;
 1193     int ret;
 1194 
 1195     if(!p || !session)
 1196         return;
 1197 
 1198     if ((entry = appInfoEntryGet(appId, pConfig)))
 1199     {
 1200         if (entry->flags & APPINFO_FLAG_CLIENT_DETECTOR_CALLBACK)
 1201         {
 1202             if (entry->clntValidator)
 1203             {
 1204                 if (entry->clntValidator->detectorContext)
 1205                     return;
 1206 
 1207                 entry->clntValidator->detectorContext = true;
 1208                 ret = entry->clntValidator->detectorCallback(p->payload, p->payload_size, direction,
 1209                                                        session, p, entry->clntValidator->userData, pConfig);
 1210                 if (app_id_debug_session_flag)
 1211                     _dpd.logMsg("AppIdDbg %s %s client detector callback returned %d\n", app_id_debug_session,
 1212                                 entry->clntValidator->name ? entry->clntValidator->name : "UNKNOWN", ret);
 1213         entry->clntValidator->detectorContext = false;
 1214             }
 1215         }
 1216         if (entry->flags & APPINFO_FLAG_SERVICE_DETECTOR_CALLBACK)
 1217         {
 1218             if (entry->svrValidator)
 1219             {
 1220                 if (entry->svrValidator->detectorContext)
 1221             return;
 1222 
 1223         entry->svrValidator->detectorContext = true;
 1224                 ret = entry->svrValidator->detectorCallback(p->payload, p->payload_size, direction,
 1225                                                       session, p, entry->svrValidator->userdata, pConfig);
 1226                 if (app_id_debug_session_flag)
 1227                     _dpd.logMsg("AppIdDbg %s %s service detector callback returned %d\n", app_id_debug_session,
 1228                                 entry->svrValidator->name ? entry->svrValidator->name : "UNKNOWN", ret);
 1229         entry->svrValidator->detectorContext = false;
 1230             }
 1231         }
 1232     }
 1233 }
 1234 static inline bool svcTakingTooMuchTime(tAppIdData* session)
 1235 {
 1236     return ((session->initiatorPcketCountWithoutReply > appidStaticConfig-> max_packet_service_fail_ignore_bytes) ||
 1237             (session->initiatorPcketCountWithoutReply > appidStaticConfig->max_packet_before_service_fail &&
 1238              session->initiatorBytesWithoutServerReply > appidStaticConfig->max_bytes_before_service_fail));
 1239 }
 1240 
 1241 static inline void setServiceAppIdData(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppId serviceAppId, char *vendor, char **version)
 1242 {
 1243     if (serviceAppId <= APP_ID_NONE)
 1244         return;
 1245 
 1246     //in drambuie, 3rd party is in INIT state after processing first GET requuest.
 1247     if (serviceAppId == APP_ID_HTTP)
 1248     {
 1249         if (session->clientServiceAppId == APP_ID_NONE)
 1250         {
 1251             session->clientServiceAppId = serviceAppId;
 1252         }
 1253         return;
 1254     }
 1255 
 1256     if (session->serviceAppId != serviceAppId)
 1257     {
 1258         session->serviceAppId = serviceAppId;
 1259 
 1260         CheckDetectorCallback(p, session, direction, serviceAppId, appIdActiveConfigGet());
 1261 
 1262         if (appidStaticConfig->instance_id)
 1263             checkSandboxDetection(serviceAppId);
 1264 
 1265         /* Clear out previous values of vendor & version */
 1266         if (session->serviceVendor)
 1267         {
 1268             free(session->serviceVendor);
 1269             session->serviceVendor = NULL;
 1270         }
 1271         if (session->serviceVersion)
 1272         {
 1273             free(session->serviceVersion);
 1274             session->serviceVersion = NULL;
 1275         }
 1276 
 1277         if (vendor)
 1278             session->serviceVendor = vendor;
 1279 
 1280         if (version && *version)
 1281         {
 1282             session->serviceVersion = *version;
 1283             *version = NULL;
 1284         }
 1285     }
 1286     else
 1287     {
 1288         if (vendor || version)
 1289         {
 1290             /* Clear previous values */
 1291             if (session->serviceVendor)
 1292                 free(session->serviceVendor);
 1293             if (session->serviceVersion)
 1294                 free(session->serviceVersion);
 1295 
 1296             /* set vendor */
 1297             if (vendor)
 1298                 session->serviceVendor = vendor;
 1299             else
 1300                 session->serviceVendor = NULL;
 1301 
 1302             /* set version */
 1303             if (version && *version)
 1304             {
 1305                 session->serviceVersion = *version;
 1306                 *version = NULL;
 1307             }
 1308             else
 1309                 session->serviceVersion = NULL;
 1310         }
 1311     }
 1312 }
 1313 
 1314 static inline void setClientAppIdData(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppId clientAppId, char **version)
 1315 {
 1316     tAppIdConfig *pConfig = appIdActiveConfigGet();
 1317     if (clientAppId <= APP_ID_NONE || clientAppId == APP_ID_HTTP)
 1318     {
 1319         if (version && *version)
 1320         { 
 1321             free(*version);
 1322             *version = NULL;
 1323         }
 1324         return;
 1325     }
 1326 
 1327     if (session->clientAppId != clientAppId)
 1328     {
 1329         unsigned prev_priority = appInfoEntryPriorityGet(session->clientAppId, pConfig);
 1330         unsigned curr_priority = appInfoEntryPriorityGet(clientAppId, pConfig) ;
 1331 
 1332         if (appidStaticConfig->instance_id)
 1333             checkSandboxDetection(clientAppId);
 1334 
 1335         if ((session->clientAppId) && (prev_priority > curr_priority ))
 1336         {
 1337             if (version && *version)
 1338             {
 1339                 free(*version);
 1340                 *version = NULL;
 1341             }
 1342             return;
 1343         }
 1344         session->clientAppId = clientAppId;
 1345 
 1346     CheckDetectorCallback(p, session, direction, clientAppId, pConfig);
 1347 
 1348         if (session->clientVersion)
 1349             free(session->clientVersion);
 1350 
 1351         if (version && *version)
 1352         {
 1353             session->clientVersion = *version;
 1354             *version = NULL;
 1355         }
 1356         else
 1357             session->clientVersion = NULL;
 1358     }
 1359     else if (version && *version)
 1360     {
 1361         if (session->clientVersion)
 1362             free(session->clientVersion);
 1363         session->clientVersion = *version;
 1364         *version = NULL;
 1365     }
 1366 }
 1367 
 1368 static inline void setReferredPayloadAppIdData(tAppIdData *session, tAppId referredPayloadAppId)
 1369 {
 1370     if (referredPayloadAppId <= APP_ID_NONE)
 1371         return;
 1372 
 1373     if (session->referredPayloadAppId != referredPayloadAppId)
 1374     {
 1375         if (appidStaticConfig->instance_id)
 1376             checkSandboxDetection(referredPayloadAppId);
 1377 
 1378         session->referredPayloadAppId = referredPayloadAppId;
 1379     }
 1380 }
 1381 
 1382 static inline void setPayloadAppIdData(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppId payloadAppId, char **version)
 1383 {
 1384     tAppIdConfig *pConfig = appIdActiveConfigGet();
 1385 
 1386     if (payloadAppId <= APP_ID_NONE)
 1387         return;
 1388 
 1389     if (session->payloadAppId != payloadAppId)
 1390     {
 1391         unsigned prev_priority = appInfoEntryPriorityGet(session->payloadAppId, pConfig);
 1392         unsigned curr_priority = appInfoEntryPriorityGet(payloadAppId, pConfig);
 1393 
 1394         if (appidStaticConfig->instance_id)
 1395             checkSandboxDetection(payloadAppId);
 1396 
 1397         if ((session->payloadAppId ) && (prev_priority > curr_priority ))
 1398             return;
 1399 
 1400         session->payloadAppId = payloadAppId;
 1401 
 1402         CheckDetectorCallback(p, session, direction, payloadAppId, pConfig);
 1403 
 1404         if (session->payloadVersion)
 1405             free(session->payloadVersion);
 1406 
 1407         if (version && *version)
 1408         {
 1409             session->payloadVersion = *version;
 1410             *version = NULL;
 1411         }
 1412         else
 1413             session->payloadVersion = NULL;
 1414     }
 1415     else if (version && *version)
 1416     {
 1417         if (session->payloadVersion)
 1418             free(session->payloadVersion);
 1419         session->payloadVersion = *version;
 1420         *version = NULL;
 1421     }
 1422 }
 1423 
 1424 static inline void setTPAppIdData(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppId tpAppId)
 1425 {
 1426     tAppIdConfig *pConfig = appIdActiveConfigGet();
 1427 
 1428     if (tpAppId <= APP_ID_NONE || !session)
 1429         return;
 1430 
 1431     if (session->tpAppId != tpAppId)
 1432     {
 1433         session->tpAppId = tpAppId;
 1434         CheckDetectorCallback(p, session, direction, tpAppId, pConfig);
 1435     }
 1436 }
 1437 
 1438 static inline void setTPPayloadAppIdData(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppId tpPayloadAppId)
 1439 {
 1440     tAppIdConfig *pConfig = appIdActiveConfigGet();
 1441 
 1442     if (tpPayloadAppId <= APP_ID_NONE || !session)
 1443         return;
 1444 
 1445     if (session->tpPayloadAppId != tpPayloadAppId)
 1446     {
 1447         session->tpPayloadAppId = tpPayloadAppId;
 1448         CheckDetectorCallback(p, session, direction, tpPayloadAppId, pConfig);
 1449     }
 1450 }
 1451 
 1452 static inline void clearSessionAppIdData(tAppIdData *session)
 1453 {
 1454     session->payloadAppId = APP_ID_UNKNOWN;
 1455     session->serviceAppId = APP_ID_UNKNOWN;
 1456     session->tpPayloadAppId = APP_ID_UNKNOWN;
 1457     session->tpAppId = APP_ID_UNKNOWN;
 1458     if (session->payloadVersion)
 1459     {
 1460         free(session->payloadVersion);
 1461         session->payloadVersion = NULL;
 1462     }
 1463     if (session->serviceVendor)
 1464     {
 1465         free(session->serviceVendor);
 1466         session->serviceVendor = NULL;
 1467     }
 1468     if (session->serviceVersion)
 1469     {
 1470         free(session->serviceVersion);
 1471         session->serviceVersion = NULL;
 1472     }
 1473     if (session->clientVersion)
 1474     {
 1475         free(session->clientVersion);
 1476         session->clientVersion = NULL;
 1477     }
 1478     if (session->tsession)
 1479     {
 1480         appTlsSessionDataFree(session->tsession);
 1481         session->tsession = NULL;
 1482     }
 1483     if (session->hsession)
 1484     {
 1485         appHttpSessionDataFree(session->hsession);
 1486         session->hsession = NULL;
 1487     }
 1488     if (session->dsession)
 1489     {
 1490         appDNSSessionDataFree(session->dsession);
 1491         session->dsession = NULL;
 1492     }
 1493     if (thirdparty_appid_module)
 1494         thirdparty_appid_module->session_delete(session->tpsession, 1);
 1495 }
 1496 
 1497 static inline int initial_CHP_sweep (char ** chp_buffers, uint16_t * chp_buffer_lengths, MatchedCHPAction **ppmatches, tAppIdData *session, const tDetectorHttpConfig *pHttpConfig)
 1498 {
 1499     CHPApp* cah = NULL;
 1500     int longest = 0;
 1501     int i;
 1502     httpSession *hsession;
 1503     int scanKeyFoundSomething=0;
 1504     CHPMatchTally *pTally = NULL; // scanKeyCHP allocates a pointer, but we free it when ready
 1505 
 1506     hsession = session->hsession;
 1507 
 1508     for (i = 0; i <= MAX_KEY_PATTERN; i++)
 1509     {
 1510         ppmatches[i] = NULL;
 1511         if (chp_buffers[i] && chp_buffer_lengths[i] &&
 1512             scanKeyCHP((PatternType)i, chp_buffers[i], chp_buffer_lengths[i], &pTally, &ppmatches[i], pHttpConfig))
 1513            scanKeyFoundSomething=1;
 1514     }
 1515     if (!scanKeyFoundSomething)
 1516     {
 1517         if (pTally) free(pTally);
 1518         for (i = 0; i <= MAX_KEY_PATTERN; i++)
 1519         {
 1520             if (ppmatches[i])
 1521             {
 1522                 FreeMatchedCHPActions(ppmatches[i]);
 1523                 ppmatches[i] = NULL;
 1524             }
 1525         }
 1526         return 0;
 1527     }
 1528 
 1529     for (i = 0; i < pTally->in_use_elements; i++)
 1530     {
 1531         // Only those items which have had their key_pattern_countdown field reduced to zero are a full match
 1532         if (pTally->item[i].key_pattern_countdown)
 1533             continue;
 1534         if (longest < pTally->item[i].key_pattern_length_sum)
 1535         {
 1536             // We've found a new longest pattern set
 1537             longest = pTally->item[i].key_pattern_length_sum;
 1538             cah = pTally->item[i].chpapp;
 1539         }
 1540     }
 1541     // either we have a candidate or we don't so we can free the tally structure either way.
 1542     free(pTally);
 1543 
 1544     if (cah == NULL)
 1545     {
 1546         // We were planning to pass along the content of ppmatches to the second phase and let
 1547         // them be freed inside scanCHP, but we have no candidate so we free here
 1548         for (i = 0; i <= MAX_KEY_PATTERN; i++)
 1549         {
 1550             if (ppmatches[i])
 1551             {
 1552                 FreeMatchedCHPActions(ppmatches[i]);
 1553                 ppmatches[i] = NULL;
 1554             }
 1555         }
 1556 
 1557         return 0;
 1558     }
 1559 
 1560     /****************************************************************/
 1561     /* candidate has been chosen and it is pointed to by cah        */
 1562     /* we will preserve any match sets until the calls to scanCHP() */
 1563     /****************************************************************/
 1564     for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1565     {
 1566         ptype_scan_counts[i] = cah->ptype_scan_counts[i];
 1567         hsession->ptype_req_counts[i] = cah->ptype_req_counts[i];
 1568         if (i > 3 && !cah->ptype_scan_counts[i] && !getAppIdFlag(session, APPID_SESSION_SPDY_SESSION))
 1569         {
 1570             clearAppIdFlag(session, APPID_SESSION_CHP_INSPECTING);
 1571             if (thirdparty_appid_module)
 1572                 thirdparty_appid_module->session_attr_clear(session->tpsession, TP_ATTR_CONTINUE_MONITORING);
 1573         }
 1574     }
 1575     hsession->chp_candidate = cah->appIdInstance;
 1576     hsession->app_type_flags = cah->app_type_flags;
 1577     hsession->num_matches = cah->num_matches;
 1578     hsession->num_scans = cah->num_scans;
 1579 
 1580     if (thirdparty_appid_module)
 1581     {
 1582         if ((ptype_scan_counts[CONTENT_TYPE_PT]))
 1583             thirdparty_appid_module->session_attr_set(session->tpsession, TP_ATTR_COPY_RESPONSE_CONTENT);
 1584         else
 1585             thirdparty_appid_module->session_attr_clear(session->tpsession, TP_ATTR_COPY_RESPONSE_CONTENT);
 1586 
 1587         if ((ptype_scan_counts[LOCATION_PT]))
 1588             thirdparty_appid_module->session_attr_set(session->tpsession, TP_ATTR_COPY_RESPONSE_LOCATION);
 1589         else
 1590             thirdparty_appid_module->session_attr_clear(session->tpsession, TP_ATTR_COPY_RESPONSE_LOCATION);
 1591 
 1592         if ((ptype_scan_counts[BODY_PT]))
 1593             thirdparty_appid_module->session_attr_set(session->tpsession, TP_ATTR_COPY_RESPONSE_BODY);
 1594         else
 1595             thirdparty_appid_module->session_attr_clear(session->tpsession, TP_ATTR_COPY_RESPONSE_BODY);
 1596     }
 1597 
 1598     return 1;
 1599 }
 1600 
 1601 static char *httpFieldName[ NUMBER_OF_PTYPES ] = // for use in debug messages
 1602 {
 1603     "useragent",
 1604     "host",
 1605     "referer",
 1606     "uri",
 1607     "cookie",
 1608     "req_body",
 1609     "content_type",
 1610     "location",
 1611     "body",
 1612 };
 1613 
 1614 static inline void processCHP(tAppIdData *session, char **version, SFSnortPacket *p, APPID_SESSION_DIRECTION direction, const tAppIdConfig *pConfig)
 1615 {
 1616     int i;
 1617     int found_in_buffer = 0;
 1618     char *user = NULL;
 1619     tAppId chp_final;
 1620     tAppId ret = 0;
 1621     httpSession *http_session = session->hsession;
 1622 
 1623     char *chp_buffers[NUMBER_OF_PTYPES] = {
 1624         http_session->useragent,
 1625         http_session->host,
 1626         http_session->referer,
 1627         http_session->uri,
 1628         http_session->cookie,
 1629         http_session->req_body,
 1630         http_session->content_type,
 1631         http_session->location,
 1632         http_session->body,
 1633     };
 1634 
 1635     uint16_t chp_buffer_lengths[NUMBER_OF_PTYPES] = {
 1636         http_session->useragent_buflen,
 1637         http_session->host_buflen,
 1638         http_session->referer_buflen,
 1639         http_session->uri_buflen,
 1640         http_session->cookie_buflen,
 1641         http_session->req_body_buflen,
 1642         http_session->content_type_buflen,
 1643         http_session->location_buflen,
 1644         http_session->body_buflen,
 1645     };
 1646 
 1647     char *chp_rewritten[NUMBER_OF_PTYPES] = {
 1648         NULL,NULL,NULL,
 1649         NULL,NULL,NULL,
 1650         NULL,NULL,NULL
 1651     };
 1652 
 1653     MatchedCHPAction *chp_matches[NUMBER_OF_PTYPES] = {
 1654         NULL,NULL,NULL,
 1655         NULL,NULL,NULL,
 1656         NULL,NULL,NULL
 1657     };
 1658 
 1659     if (http_session->chp_hold_flow)
 1660         http_session->chp_finished = 0;
 1661 
 1662     if (!http_session->chp_candidate)
 1663     {
 1664         // remove artifacts from previous matches before we start again.
 1665         if (http_session->new_field_contents)
 1666         {
 1667             for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1668             {
 1669                 if (http_session->new_field[i])
 1670                 {
 1671                     free(http_session->new_field[i]);
 1672                     http_session->new_field[i] = NULL;
 1673                 }
 1674             }
 1675         }
 1676 
 1677         if (!initial_CHP_sweep(chp_buffers, chp_buffer_lengths, chp_matches, session, &pConfig->detectorHttpConfig))
 1678             http_session->chp_finished = 1; // this is a failure case.
 1679     }
 1680     if (!http_session->chp_finished && http_session->chp_candidate)
 1681     {
 1682         for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1683         {
 1684             if (!ptype_scan_counts[i])
 1685                 continue;
 1686 
 1687             // Do scans and check results
 1688             if (chp_buffers[i] && chp_buffer_lengths[i])
 1689             {
 1690                 found_in_buffer = 0;
 1691                 ret = scanCHP((PatternType)i, chp_buffers[i], chp_buffer_lengths[i], chp_matches[i], version,
 1692                         &user, &chp_rewritten[i], &found_in_buffer,
 1693                         http_session, p, &pConfig->detectorHttpConfig);
 1694                 chp_matches[i] = NULL; // freed by scanCHP()
 1695                 http_session->total_found += found_in_buffer;
 1696                 if (!ret || found_in_buffer < http_session->ptype_req_counts[i])
 1697                 {
 1698                     // No match at all or the required matches for the field was NOT made
 1699                     if (!http_session->num_matches)
 1700                     {
 1701                         // num_matches == 0 means: all must succeed
 1702                         // give up early
 1703                         http_session->chp_candidate = 0;
 1704                         break;
 1705                     }
 1706                 }
 1707             }
 1708             else
 1709             {
 1710                 // No buffer or empty
 1711                 if (!http_session->num_matches)
 1712                 {
 1713                     // We had a pattern(s) and no buffer to look in.
 1714                     // num_matches == 0 means: all must succeed
 1715                     // give up early
 1716                     http_session->chp_candidate = 0;
 1717                     break;
 1718                 }
 1719             }
 1720 
 1721             // Decrement the expected scan count toward 0.
 1722             ptype_scan_counts[i] = 0;
 1723             http_session->num_scans--;
 1724             // if we have reached the end of the list of scans (which have something to do), then num_scans == 0
 1725             if (http_session->num_scans == 0)
 1726             {
 1727                 // we finished the last scan
 1728                 // either the num_matches value was zero and we failed early-on or we need to check for the min.
 1729                 if (http_session->num_matches &&
 1730                     http_session->total_found < http_session->num_matches)
 1731                 {
 1732                     // There was a minimum scans match count (num_matches != 0)
 1733                     // And we did not reach that minimum
 1734                     http_session->chp_candidate = 0;
 1735                     break;
 1736                 }
 1737                 // All required matches were met.
 1738                 http_session->chp_finished = 1;
 1739                 break;
 1740             }
 1741         }
 1742         for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1743         {
 1744             if (chp_matches[i]) // free leftover matches
 1745             {
 1746                 FreeMatchedCHPActions(chp_matches[i]);
 1747                 chp_matches[i] = NULL;
 1748             }
 1749         }
 1750         if (!http_session->chp_candidate)
 1751         {
 1752             http_session->chp_finished = 1;
 1753             if (*version)
 1754             {
 1755                 free(*version);
 1756                 *version = NULL;
 1757             }
 1758             if (user)
 1759             {
 1760                 free(user);
 1761                 user = NULL;
 1762             }
 1763             for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1764             {
 1765                 if (NULL != chp_rewritten[i])
 1766                 {
 1767                     free(chp_rewritten[i]);
 1768                     chp_rewritten[i] = NULL;
 1769                 }
 1770             }
 1771             memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
 1772 
 1773             // Make it possible for other detectors to run.
 1774             http_session->skip_simple_detect = false;
 1775             return;
 1776         }
 1777         if (http_session->chp_candidate && http_session->chp_finished)
 1778         {
 1779             chp_final = http_session->chp_alt_candidate ?
 1780                 http_session->chp_alt_candidate :
 1781                 CHP_APPIDINSTANCE_TO_ID(http_session->chp_candidate);
 1782             if (http_session->app_type_flags & APP_TYPE_SERVICE)
 1783             {
 1784                 setServiceAppIdData(p, direction, session, chp_final, NULL, version);
 1785             }
 1786             if (http_session->app_type_flags & APP_TYPE_CLIENT)
 1787             {
 1788                 setClientAppIdData(p, direction, session, chp_final, version);
 1789             }
 1790             if (http_session->app_type_flags & APP_TYPE_PAYLOAD)
 1791             {
 1792                 setPayloadAppIdData(p, direction, session, chp_final, version);
 1793             }
 1794             if (http_session->fflow && http_session->fflow->flow_prepared)
 1795             {
 1796                 finalizeFflow(http_session->fflow, http_session->app_type_flags,
 1797                               (http_session->fflow->appId ? http_session->fflow->appId : chp_final), p);
 1798                 free(http_session->fflow);
 1799                 http_session->fflow = NULL;
 1800             }
 1801             if (*version)
 1802                 *version = NULL;
 1803             if (user)
 1804             {
 1805                 session->username = user;
 1806                 user = NULL;
 1807                 if (http_session->app_type_flags & APP_TYPE_SERVICE)
 1808                     session->usernameService = chp_final;
 1809                 else
 1810                     session->usernameService = session->serviceAppId;
 1811                 setAppIdFlag(session, APPID_SESSION_LOGIN_SUCCEEDED);
 1812             }
 1813             for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1814             {
 1815                 if (NULL != chp_rewritten[i])
 1816                 {
 1817                     if (app_id_debug_session_flag)
 1818                         _dpd.logMsg("AppIdDbg %s rewritten %s: %s\n", app_id_debug_session, httpFieldName[i], chp_rewritten[i]);
 1819                     if (http_session->new_field[i])
 1820                         free(http_session->new_field[i]);
 1821                     http_session->new_field[i] = chp_rewritten[i];
 1822                     http_session->new_field_contents = true;
 1823                     chp_rewritten[i] = NULL;
 1824                 }
 1825             }
 1826             http_session->chp_candidate = 0;
 1827             //if we're doing safesearch rewrites, we want to continue to hold the flow
 1828             if (!http_session->get_offsets_from_rebuilt)
 1829                 http_session->chp_hold_flow = 0;
 1830             session->scan_flags &= ~SCAN_HTTP_VIA_FLAG;
 1831             session->scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
 1832             session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
 1833             memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
 1834         }
 1835         else /* if we have a candidate, but we're not finished */
 1836         {
 1837             if (user)
 1838             {
 1839                 free(user);
 1840                 user = NULL;
 1841             }
 1842             for (i = 0; i < NUMBER_OF_PTYPES; i++)
 1843             {
 1844                 if (NULL != chp_rewritten[i])
 1845                 {
 1846                     free(chp_rewritten[i]);
 1847                     chp_rewritten[i] = NULL;
 1848                 }
 1849             }
 1850         }
 1851     }
 1852 }
 1853 
 1854 static inline bool payloadAppIdIsSet(tAppIdData *session)
 1855 {
 1856     return ( session->payloadAppId || session->tpPayloadAppId );
 1857 }
 1858 
 1859 static inline void clearMiscHttpFlags(tAppIdData *session)
 1860 {
 1861     if (!getAppIdFlag(session, APPID_SESSION_SPDY_SESSION))
 1862     {
 1863         clearAppIdFlag(session, APPID_SESSION_CHP_INSPECTING);
 1864         if (thirdparty_appid_module)
 1865             thirdparty_appid_module->session_attr_clear(session->tpsession, TP_ATTR_CONTINUE_MONITORING);
 1866     }
 1867 }
 1868 
 1869 STATIC INLINE int processHTTPPacket(SFSnortPacket *p, tAppIdData *session, APPID_SESSION_DIRECTION direction, HttpParsedHeaders *const headers, const tAppIdConfig *pConfig)
 1870 {
 1871 #define RESPONSE_CODE_LENGTH 3
 1872     HeaderMatchedPatterns hmp;
 1873     httpSession *http_session;
 1874     int start, end, size;
 1875     char *version = NULL;
 1876     char *vendorVersion = NULL;
 1877     char *vendor = NULL;
 1878     tAppId serviceAppId = 0;
 1879     tAppId clientAppId = 0;
 1880     tAppId payloadAppId = 0;
 1881     tAppId referredPayloadAppId = 0;
 1882     char *host;
 1883     char *url;
 1884     char *useragent;
 1885     char *referer;
 1886     char *via;
 1887     AppInfoTableEntry *entry;
 1888     PROFILE_VARS;
 1889     PREPROC_PROFILE_START(httpPerfStats);
 1890 
 1891     http_session = session->hsession;
 1892     if (!http_session)
 1893     {
 1894         clearSessionAppIdData(session);
 1895         if (app_id_debug_session_flag)
 1896             _dpd.logMsg("AppIdDbg %s attempt to process HTTP packet with no HTTP data\n", app_id_debug_session);
 1897         PREPROC_PROFILE_END(httpPerfStats);
 1898         return 0;
 1899     }
 1900 
 1901     // For fragmented HTTP headers, do not process if none of the fields are set.
 1902     // These fields will get set when the HTTP header is reassembled.
 1903     if ((!http_session->useragent) && (!http_session->host) && (!http_session->referer) && (!http_session->uri))
 1904     {
 1905         if (!http_session->skip_simple_detect)
 1906             clearMiscHttpFlags(session);
 1907         PREPROC_PROFILE_END(httpPerfStats);
 1908         return 0;
 1909     }
 1910 
 1911     if (direction == APP_ID_FROM_RESPONDER && !getAppIdFlag(session, APPID_SESSION_RESPONSE_CODE_CHECKED))
 1912     {
 1913         if (http_session->response_code)
 1914         {
 1915             setAppIdFlag(session, APPID_SESSION_RESPONSE_CODE_CHECKED);
 1916             if (http_session->response_code_buflen != RESPONSE_CODE_LENGTH)
 1917             {
 1918                 /* received bad response code. Stop processing this session */
 1919                 clearSessionAppIdData(session);
 1920                 if (app_id_debug_session_flag)
 1921                     _dpd.logMsg("AppIdDbg %s bad http response code\n", app_id_debug_session);
 1922                 PREPROC_PROFILE_END(httpPerfStats);
 1923                 return 0;
 1924             }
 1925         }
 1926 #if RESPONSE_CODE_PACKET_THRESHHOLD
 1927         else if (++(http_session->response_code_packets) == RESPONSE_CODE_PACKET_THRESHHOLD)
 1928         {
 1929             setAppIdFlag(session, APPID_SESSION_RESPONSE_CODE_CHECKED);
 1930             /* didn't receive response code in first X packets. Stop processing this session */
 1931             clearSessionAppIdData(session);
 1932             if (app_id_debug_session_flag)
 1933                 _dpd.logMsg("AppIdDbg %s no response code received\n", app_id_debug_session);
 1934             PREPROC_PROFILE_END(httpPerfStats);
 1935             return 0;
 1936         }
 1937 #endif
 1938     }
 1939     host = http_session->host;
 1940     url = http_session->url;
 1941     via = http_session->via;
 1942     useragent = http_session->useragent;
 1943     referer = http_session->referer;
 1944     memset(&hmp, 0, sizeof(hmp));
 1945 
 1946     if (session->serviceAppId == APP_ID_NONE)
 1947     {
 1948         session->serviceAppId = APP_ID_HTTP;
 1949         if (appidStaticConfig->instance_id)
 1950             checkSandboxDetection(APP_ID_HTTP);
 1951     }
 1952 
 1953     if (app_id_debug_session_flag)
 1954         _dpd.logMsg("AppIdDbg %s chp_finished %d chp_hold_flow %d\n", app_id_debug_session, http_session->chp_finished, http_session->chp_hold_flow);
 1955 
 1956     if (!http_session->chp_finished || http_session->chp_hold_flow)
 1957         processCHP(session, &version, p, direction, pConfig);
 1958 
 1959     if (!http_session->skip_simple_detect)  // false unless a match happened with a call to processCHP().
 1960     {
 1961         if (!getAppIdFlag(session, APPID_SESSION_APP_REINSPECT))
 1962         {
 1963             // Scan Server Header for Vendor & Version
 1964             if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_VENDOR_FLAG) && session->hsession->server) ||
 1965                 (!thirdparty_appid_module && getHTTPHeaderLocation(p->payload, p->payload_size, HTTP_ID_SERVER, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
 1966             {
 1967                 if (session->serviceAppId == APP_ID_NONE || session->serviceAppId == APP_ID_HTTP)
 1968                 {
 1969                     RNAServiceSubtype *subtype = NULL;
 1970                     RNAServiceSubtype **tmpSubtype;
 1971 
 1972                     if (thirdparty_appid_module)
 1973                         getServerVendorVersion((uint8_t*)session->hsession->server, strlen(session->hsession->server), &vendorVersion, &vendor, &subtype);
 1974                     else getServerVendorVersion(p->payload + start, end - start, &vendorVersion, &vendor, &subtype);
 1975                     if (vendor || vendorVersion)
 1976                     {
 1977                         if (session->serviceVendor)
 1978                         {
 1979                             free(session->serviceVendor);
 1980                             session->serviceVendor = NULL;
 1981                         }
 1982                         if (session->serviceVersion)
 1983                         {
 1984                             free(session->serviceVersion);
 1985                             session->serviceVersion = NULL;
 1986                         }
 1987                         if (vendor)
 1988                             session->serviceVendor = vendor;
 1989                         if (vendorVersion)
 1990                             session->serviceVersion = vendorVersion;
 1991                         session->scan_flags &= ~SCAN_HTTP_VENDOR_FLAG;
 1992                     }
 1993                     if (subtype)
 1994                     {
 1995                         for (tmpSubtype = &session->subtype; *tmpSubtype; tmpSubtype = &(*tmpSubtype)->next);
 1996 
 1997                         *tmpSubtype = subtype;
 1998                     }
 1999                 }
 2000             }
 2001 
 2002             if (webdav_found(&hmp))
 2003             {
 2004                 if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE && session->payloadAppId != payloadAppId)
 2005                     _dpd.logMsg("AppIdDbg %s payload is webdav\n", app_id_debug_session);
 2006                 setPayloadAppIdData(p, direction, session, APP_ID_WEBDAV, NULL);
 2007             }
 2008 
 2009             // Scan User-Agent for Browser types or Skype
 2010             if ((session->scan_flags & SCAN_HTTP_USER_AGENT_FLAG) && session->clientAppId <= APP_ID_NONE && useragent && http_session->useragent_buflen)
 2011             {
 2012                 if (version)
 2013                 {
 2014                     free(version);
 2015                     version = NULL;
 2016                 }
 2017                 identifyUserAgent((uint8_t *)useragent, http_session->useragent_buflen, &serviceAppId, &clientAppId, &version, &pConfig->detectorHttpConfig);
 2018                 if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId != APP_ID_HTTP && session->serviceAppId != serviceAppId)
 2019                     _dpd.logMsg("AppIdDbg %s User Agent is service %d\n", app_id_debug_session, serviceAppId);
 2020                 setServiceAppIdData(p, direction, session, serviceAppId, NULL, NULL);
 2021                 if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId != APP_ID_HTTP && session->clientAppId != clientAppId)
 2022                     _dpd.logMsg("AppIdDbg %s User Agent is client %d\n", app_id_debug_session, clientAppId);
 2023                 setClientAppIdData(p, direction, session, clientAppId, &version);
 2024                 session->scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
 2025             }
 2026 
 2027             /* Scan Via Header for squid */
 2028             if (!payloadAppIdIsSet(session) && (session->scan_flags & SCAN_HTTP_VIA_FLAG) && via && (size = strlen(via)) > 0)
 2029             {
 2030                 if (version)
 2031                 {
 2032                     free(version);
 2033                     version = NULL;
 2034                 }
 2035                 payloadAppId = getAppidByViaPattern((uint8_t *)via, size, &version, &pConfig->detectorHttpConfig);
 2036                 if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE && session->payloadAppId != payloadAppId)
 2037                     _dpd.logMsg("AppIdDbg %s VIA is payload %d\n", app_id_debug_session, payloadAppId);
 2038                 setPayloadAppIdData(p, direction, session, payloadAppId, NULL);
 2039                 session->scan_flags &= ~SCAN_HTTP_VIA_FLAG;
 2040             }
 2041         }
 2042 
 2043         /* Scan X-Working-With HTTP header */
 2044         if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) && session->hsession->x_working_with) ||
 2045             (!thirdparty_appid_module && getHTTPHeaderLocation(p->payload, p->payload_size, HTTP_ID_X_WORKING_WITH, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
 2046         {
 2047             tAppId appId;
 2048 
 2049             if (thirdparty_appid_module)
 2050                 appId = scan_header_x_working_with((uint8_t*)session->hsession->x_working_with, strlen(session->hsession->x_working_with), &version);
 2051             else appId = scan_header_x_working_with(p->payload + start, end - start, &version);
 2052 
 2053             if (appId)
 2054             {
 2055                 if (direction == APP_ID_FROM_INITIATOR)
 2056                 {
 2057                     if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId != APP_ID_HTTP && session->clientAppId != clientAppId)
 2058                         _dpd.logMsg("AppIdDbg %s X is client %d\n", app_id_debug_session, appId);
 2059                     setClientAppIdData(p, direction, session, appId, &version);
 2060                 }
 2061                 else
 2062                 {
 2063                     if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId != APP_ID_HTTP && session->serviceAppId != serviceAppId)
 2064                         _dpd.logMsg("AppIdDbg %s X is service %d\n", app_id_debug_session, appId);
 2065                     setServiceAppIdData(p, direction, session, appId, NULL, &version);
 2066                 }
 2067                 session->scan_flags &= ~SCAN_HTTP_XWORKINGWITH_FLAG;
 2068             }
 2069         }
 2070 
 2071         // Scan Content-Type Header for multimedia types and scan contents
 2072         if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
 2073              && session->hsession->content_type  && !payloadAppIdIsSet(session)) ||
 2074             (!thirdparty_appid_module && !payloadAppIdIsSet(session) &&
 2075              getHTTPHeaderLocation(p->payload, p->payload_size, HTTP_ID_CONTENT_TYPE, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
 2076         {
 2077             if (thirdparty_appid_module)
 2078                 payloadAppId = getAppidByContentType((uint8_t*)session->hsession->content_type, strlen(session->hsession->content_type), &pConfig->detectorHttpConfig);
 2079             else payloadAppId = getAppidByContentType(p->payload + start, end - start, &pConfig->detectorHttpConfig);
 2080             if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE && session->payloadAppId != payloadAppId)
 2081                 _dpd.logMsg("AppIdDbg %s Content-Type is payload %d\n", app_id_debug_session, payloadAppId);
 2082             setPayloadAppIdData(p, direction, session, payloadAppId, NULL);
 2083             session->scan_flags &= ~SCAN_HTTP_CONTENT_TYPE_FLAG;
 2084         }
 2085 
 2086         if (session->scan_flags & SCAN_HTTP_HOST_URL_FLAG)
 2087         {
 2088             if (version)
 2089             {
 2090                 free(version);
 2091                 version = NULL;
 2092             }
 2093             if (getAppIdFromUrl(host, url, &version, referer, &clientAppId, &serviceAppId, &payloadAppId, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig) == 1)
 2094             {
 2095                 // do not overwrite a previously-set client or service
 2096                 if (session->clientAppId <= APP_ID_NONE)
 2097                 {
 2098                     if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId != APP_ID_HTTP && session->clientAppId != clientAppId)
 2099                         _dpd.logMsg("AppIdDbg %s URL is client %d\n", app_id_debug_session, clientAppId);
 2100                     setClientAppIdData(p, direction, session, clientAppId, NULL);
 2101                 }
 2102                 if (session->serviceAppId <= APP_ID_NONE)
 2103                 {
 2104                     if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId != APP_ID_HTTP && session->serviceAppId != serviceAppId)
 2105                         _dpd.logMsg("AppIdDbg %s URL is service %d\n", app_id_debug_session, serviceAppId);
 2106                     setServiceAppIdData(p, direction, session, serviceAppId, NULL, NULL);
 2107                 }
 2108                 // DO overwrite a previously-set payload
 2109                 if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE && session->payloadAppId != payloadAppId)
 2110                     _dpd.logMsg("AppIdDbg %s URL is payload %d\n", app_id_debug_session, payloadAppId);
 2111                 setPayloadAppIdData(p, direction, session, payloadAppId, &version);
 2112                 setReferredPayloadAppIdData(session, referredPayloadAppId);
 2113             }
 2114             session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
 2115         }
 2116 
 2117         if (session->clientAppId == APP_ID_APPLE_CORE_MEDIA)
 2118         {
 2119             if (session->tpPayloadAppId > APP_ID_NONE)
 2120             {
 2121                 entry = appInfoEntryGet(session->tpPayloadAppId, pConfig);
 2122                 // only move tpPayloadAppId to client if its got a clientAppId
 2123                 if (entry && (entry->clientId > APP_ID_NONE))
 2124                 {
 2125                     session->miscAppId = session->clientAppId;
 2126                     session->clientAppId = session->tpPayloadAppId;
 2127                 }
 2128             }
 2129             else if (session->payloadAppId > APP_ID_NONE)
 2130             {
 2131                 entry =  appInfoEntryGet(session->payloadAppId, pConfig);
 2132                 // only move payloadAppId to client if it has a clientAppid
 2133                 if (entry && (entry->clientId > APP_ID_NONE))
 2134                 {
 2135                     session->miscAppId = session->clientAppId;
 2136                     session->clientAppId = session->payloadAppId;
 2137                 }
 2138             }
 2139         }
 2140 
 2141         clearMiscHttpFlags(session);
 2142     }  // end DON'T skip_simple_detect
 2143 
 2144     if (version) // We allocated this, but nobody used!
 2145     {
 2146         free(version);
 2147         version = NULL;
 2148     }
 2149     PREPROC_PROFILE_END(httpPerfStats);
 2150     return 0;
 2151 }
 2152 
 2153 static inline void stopRnaServiceInspection(SFSnortPacket *p, tAppIdData* session, APPID_SESSION_DIRECTION direction)
 2154 {
 2155     sfaddr_t *ip;
 2156     if (direction == APP_ID_FROM_INITIATOR)
 2157     {
 2158         ip = GET_DST_IP(p);
 2159         session->service_ip = *ip;
 2160         session->service_port = p->dst_port;
 2161 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2162         session->serviceAsId = p->pkt_header->address_space_id_dst;
 2163 #endif
 2164     }
 2165     else
 2166     {
 2167         ip = GET_SRC_IP(p);
 2168         session->service_ip = *ip;
 2169         session->service_port = p->src_port;
 2170 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2171         session->serviceAsId = p->pkt_header->address_space_id_src;
 2172 #endif
 2173     }
 2174     session->rnaServiceState = RNA_STATE_FINISHED;
 2175 
 2176 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2177     session->carrierId = p->pkt_header->carrier_id;
 2178 #endif
 2179 
 2180     if ((TPIsAppIdAvailable(session->tpsession) || getAppIdFlag(session, APPID_SESSION_NO_TPI)) &&
 2181         session->payloadAppId == APP_ID_NONE)
 2182         session->payloadAppId = APP_ID_UNKNOWN;
 2183     setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED);
 2184     clearAppIdFlag(session, APPID_SESSION_CONTINUE);
 2185 #ifdef DEBUG_FW_APPID
 2186 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 2187     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 2188 #endif
 2189         fprintf(SF_DEBUG_FILE, "%u -> %u %d stopping RNA service inspection\n",
 2190             (unsigned)p->src_port, (unsigned)p->dst_port, IsTCP(p)? IPPROTO_TCP:IPPROTO_UDP);
 2191 #endif
 2192 }
 2193 
 2194 // Mock (derived?) function for _dpd.streamAPI->is_session_decrytped().
 2195 // It gets set at the beginning of fwAppIdSearch() in this file.
 2196 // Note that _dpd.streamAPI->is_session_decrypted() gets called multiple times
 2197 // in sfrna/firewall/src/spp_fw_engine.c.
 2198 // change UNIT_TESTING and UNIT_TEST_FIRST_DECRYPTED_PACKET in appIdApi.h
 2199 #ifdef UNIT_TEST_FIRST_DECRYPTED_PACKET
 2200 bool is_session_decrypted_unit_test(void * ssn)
 2201 {
 2202     tAppIdData * session=getAppIdData(ssn);
 2203     if (session && (session->session_packet_count >= UNIT_TEST_FIRST_DECRYPTED_PACKET))
 2204         return 1;
 2205     return 0;
 2206 }
 2207 #endif
 2208 
 2209 static inline bool isSslDecryptionEnabled(tAppIdData *session)
 2210 {
 2211     if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
 2212         return 1;
 2213     return _dpd.streamAPI->is_session_decrypted(session->ssn);
 2214 }
 2215 
 2216 static inline void checkRestartSSLDetection(tAppIdData *session)
 2217 {
 2218     if (getAppIdFlag(session, APPID_SESSION_DECRYPTED)) return;
 2219     if (!isSslDecryptionEnabled(session)) return;
 2220 
 2221     tAppId serviceAppId = pickServiceAppId(session);
 2222     bool isSsl = isSslServiceAppId(serviceAppId);
 2223 
 2224     // A session could either:
 2225     // 1. Start of as SSL - captured with isSsl flag, OR
 2226     // 2. It could start of as a non-SSL session and later change to SSL. For example, FTP->FTPS.
 2227     //    In this case APPID_SESSION_ENCRYPTED flag is set by the protocol state machine.
 2228     if (getAppIdFlag(session, APPID_SESSION_ENCRYPTED) || isSsl)
 2229     {
 2230 #ifdef DEBUG_FW_APPID
 2231         fprintf(SF_DEBUG_FILE, "SSL decryption is available, restarting app Detection\n");
 2232 #endif
 2233         setAppIdFlag(session, APPID_SESSION_DECRYPTED);
 2234         session->encrypted.serviceAppId = serviceAppId;
 2235         session->encrypted.payloadAppId = pickPayloadId(session);
 2236         session->encrypted.clientAppId = pickClientAppId(session);
 2237         session->encrypted.miscAppId = pickMiscAppId(session);
 2238         session->encrypted.referredAppId = pickReferredPayloadId(session);
 2239         appSharedReInitData(session);
 2240         if (app_id_debug_session_flag)
 2241             _dpd.logMsg("AppIdDbg %s SSL decryption is available, restarting app Detection\n", app_id_debug_session);
 2242 
 2243         // APPID_SESSION_ENCRYPTED is set upon receiving a command which upgrades the session to SSL.
 2244         // Next packet after the command will have encrypted traffic.
 2245         // In the case of a session which starts as SSL, current packet itself is encrypted. Set the special flag
 2246         // APPID_SESSION_APP_REINSPECT_SSL which allows reinspection of this packet.
 2247         if (isSsl)
 2248             setAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL);
 2249     }
 2250 }
 2251 
 2252 static inline void checkRestartTunnelDetection(tAppIdData *session)
 2253 {
 2254     if ((session->hsession && session->hsession->is_tunnel) ||
 2255         (session->tpPayloadAppId == APP_ID_HTTP_TUNNEL && !getAppIdFlag(session, APPID_SESSION_HTTP_TUNNEL)))
 2256     {
 2257         if (app_id_debug_session_flag)
 2258             _dpd.logMsg("AppIdDbg %s Found HTTP Tunnel, restarting app Detection\n", app_id_debug_session);
 2259 
 2260         // Service
 2261         if (session->serviceAppId == session->portServiceAppId)
 2262             session->serviceAppId = APP_ID_NONE;
 2263         session->portServiceAppId = APP_ID_NONE;
 2264         if (session->serviceVendor)
 2265         {
 2266             free(session->serviceVendor);
 2267             session->serviceVendor = NULL;
 2268         }
 2269         if (session->serviceVersion)
 2270         {
 2271             free(session->serviceVersion);
 2272             session->serviceVersion = NULL;
 2273         }
 2274         IP_CLEAR(session->service_ip);
 2275         session->service_port = 0; 
 2276         session->rnaServiceState = RNA_STATE_NONE;
 2277         session->serviceData = NULL;
 2278 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2279         session->serviceAsId = 0xFF;
 2280 #endif
 2281 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2282         session->carrierId = 0;
 2283 #endif
 2284 
 2285         AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
 2286 
 2287         // Client
 2288         session->rnaClientState = RNA_STATE_NONE;
 2289         session->clientData = NULL;
 2290         if (session->candidate_client_list)
 2291         {
 2292             sflist_free(session->candidate_client_list);
 2293             session->candidate_client_list = NULL;
 2294         }
 2295         session->num_candidate_clients_tried = 0;
 2296         AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
 2297 
 2298         session->init_tpPackets = 0;
 2299         session->resp_tpPackets = 0;
 2300 
 2301         session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
 2302         clearAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CLIENT_DETECTED
 2303                                 | APPID_SESSION_HTTP_SESSION | APPID_SESSION_HTTP_CONNECT);
 2304         if (session->hsession && session->hsession->is_tunnel)
 2305         {
 2306             session->hsession->is_tunnel = false;
 2307             if (appidStaticConfig->http_tunnel_detect == HTTP_TUNNEL_DETECT_RESTART_AND_RESET && thirdparty_appid_module)
 2308             {
 2309                 thirdparty_appid_module->session_delete(session->tpsession, 0);
 2310                 session->tpsession = NULL;
 2311             }
 2312         }
 2313 
 2314         setAppIdFlag(session, APPID_SESSION_HTTP_TUNNEL);
 2315     }
 2316     return;
 2317 }
 2318 
 2319 static inline void checkRestartAppDetection(tAppIdData *session)
 2320 {
 2321     checkRestartSSLDetection(session);
 2322     checkRestartTunnelDetection(session);
 2323 }
 2324 
 2325 static inline void updateEncryptedAppId( tAppIdData *session, tAppId serviceAppId)
 2326 {
 2327     switch (serviceAppId)
 2328     {
 2329         case APP_ID_HTTP:
 2330             if (session->miscAppId == APP_ID_NSIIOPS || session->miscAppId == APP_ID_DDM_SSL
 2331                     || session->miscAppId == APP_ID_MSFT_GC_SSL || session->miscAppId == APP_ID_SF_APPLIANCE_MGMT)
 2332             {
 2333                 break;
 2334             }
 2335             session->miscAppId = APP_ID_HTTPS;
 2336             break;
 2337         case APP_ID_SMTP:
 2338             session->miscAppId = APP_ID_SMTPS;
 2339             break;
 2340         case APP_ID_NNTP:
 2341             session->miscAppId = APP_ID_NNTPS;
 2342             break;
 2343         case APP_ID_IMAP:
 2344             session->miscAppId = APP_ID_IMAPS;
 2345             break;
 2346         case APP_ID_SHELL:
 2347             session->miscAppId = APP_ID_SSHELL;
 2348             break;
 2349         case APP_ID_LDAP:
 2350             session->miscAppId = APP_ID_LDAPS;
 2351             break;
 2352         case APP_ID_FTP_DATA:
 2353             session->miscAppId = APP_ID_FTPSDATA;
 2354             break;
 2355         case APP_ID_FTP:
 2356     case APP_ID_FTP_CONTROL:
 2357             session->miscAppId = APP_ID_FTPS;
 2358             break;
 2359         case APP_ID_TELNET:
 2360             session->miscAppId = APP_ID_TELNET;
 2361             break;
 2362         case APP_ID_IRC:
 2363             session->miscAppId = APP_ID_IRCS;
 2364             break;
 2365         case APP_ID_POP3:
 2366             session->miscAppId = APP_ID_POP3S;
 2367             break;
 2368         default:
 2369             break;
 2370     }
 2371 }
 2372 
 2373 /*
 2374  * Desc: This function does AppId detection corresponding to the SSL params
 2375  * The order of processing is:
 2376  * Valid SNI:              SNI->first_SAN->CN->OU
 2377  * No SNI/Mismatched SNI:  first_SAN->CN->OU
 2378  */
 2379 static int scanSslParamsLookupAppId(tAppIdData *session, const char *serverName,
 2380             bool isSniMismatch, const char *subjectAltName, const char *commonName,
 2381             const char *orgName, tAppId *clientAppId, tAppId *payloadAppId)
 2382 {
 2383     int ret = 0;
 2384 
 2385     if ((session->scan_flags & SCAN_SSL_HOST_FLAG) && serverName && !isSniMismatch)
 2386     {
 2387         ret = ssl_scan_hostname((const uint8_t *)serverName, strlen(serverName),
 2388                 clientAppId, payloadAppId, &pAppidActiveConfig->serviceSslConfig);
 2389         session->tsession->matched_tls_type = MATCHED_TLS_HOST; 
 2390         session->scan_flags &= ~SCAN_SSL_HOST_FLAG;
 2391     }
 2392 
 2393     if (subjectAltName && (APP_ID_NONE == *clientAppId) && (APP_ID_NONE == *payloadAppId))
 2394     {
 2395         ret = ssl_scan_hostname((const uint8_t *)subjectAltName, strlen(subjectAltName),
 2396                 clientAppId, payloadAppId, &pAppidActiveConfig->serviceSslConfig);
 2397         session->tsession->matched_tls_type = MATCHED_TLS_FIRST_SAN; 
 2398     }
 2399 
 2400     if ((session->scan_flags & SCAN_SSL_CERTIFICATE_FLAG) && commonName &&
 2401             (APP_ID_NONE == *clientAppId) && (APP_ID_NONE == *payloadAppId))
 2402     {
 2403         ret = ssl_scan_cname((const uint8_t *)commonName, strlen(commonName),
 2404                 clientAppId, payloadAppId, &pAppidActiveConfig->serviceSslConfig);
 2405         session->tsession->matched_tls_type = MATCHED_TLS_CNAME; 
 2406         session->scan_flags &= ~SCAN_SSL_CERTIFICATE_FLAG;
 2407     }
 2408 
 2409     if (orgName && (APP_ID_NONE == *clientAppId) && (APP_ID_NONE == *payloadAppId))
 2410     {
 2411         ret = ssl_scan_cname((const uint8_t *)orgName, strlen(orgName),
 2412                 clientAppId, payloadAppId, &pAppidActiveConfig->serviceSslConfig);
 2413         session->tsession->matched_tls_type = MATCHED_TLS_ORG_UNIT; 
 2414     }
 2415 
 2416     if ((APP_ID_NONE == *clientAppId) && (APP_ID_NONE == *payloadAppId))
 2417         session->tsession->matched_tls_type = MATCHED_TLS_NONE; 
 2418 
 2419     return ret;
 2420 }
 2421 
 2422 static inline void ExamineSslMetadata(SFSnortPacket *p, APPID_SESSION_DIRECTION direction, tAppIdData *session, tAppIdConfig *pConfig)
 2423 {
 2424     int ret = 0;
 2425     tAppId clientAppId = 0;
 2426     tAppId payloadAppId = 0;
 2427 
 2428     /* TLS params already scanned, skip scanning again */
 2429     if ((session->scan_flags & SCAN_CERTVIZ_ENABLED_FLAG))
 2430         return;
 2431 
 2432     ret = scanSslParamsLookupAppId(session, (const char*)session->tsession->tls_host,
 2433             false, NULL, (const char*)session->tsession->tls_cname,
 2434             (const char*)session->tsession->tls_orgUnit, &clientAppId, &payloadAppId);
 2435 
 2436     if (session->clientAppId == APP_ID_NONE ||
 2437             session->clientAppId == APP_ID_SSL_CLIENT)
 2438         setClientAppIdData(p, direction, session, clientAppId, NULL);
 2439     setPayloadAppIdData(p, direction, session, payloadAppId, NULL);
 2440     setSSLSquelch(p, ret, (ret == 1 ? payloadAppId : clientAppId));
 2441 
 2442     if (session->tsession->tls_orgUnit)
 2443     {
 2444         free(session->tsession->tls_orgUnit);
 2445         session->tsession->tls_orgUnit = NULL;
 2446     }
 2447 
 2448     if (session->tsession->tls_handshake_done &&
 2449             session->payloadAppId == APP_ID_NONE)
 2450     {
 2451         if (app_id_debug_session_flag)
 2452             _dpd.logMsg("AppIdDbg %s End of SSL/TLS handshake detected with no payloadAppId, so setting to unknown\n", app_id_debug_session);
 2453         session->payloadAppId = APP_ID_UNKNOWN;
 2454     }
 2455 
 2456 }
 2457 
 2458 static inline int RunClientDetectors(tAppIdData *session,
 2459                               SFSnortPacket *p,
 2460                               int direction,
 2461                               tAppIdConfig *pConfig)
 2462 {
 2463     int ret = CLIENT_APP_INPROCESS;
 2464     const struct RNAClientAppModule *tmpClientData = session->clientData;
 2465 
 2466     if (tmpClientData != NULL)
 2467     {
 2468         ret = tmpClientData->validate(p->payload, p->payload_size, direction,
 2469                                             session, p, tmpClientData->userData, pConfig);
 2470         if (app_id_debug_session_flag)
 2471             _dpd.logMsg("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
 2472                         tmpClientData->name ? tmpClientData->name:"UNKNOWN", ret);
 2473     }
 2474     else
 2475     {
 2476         SF_LIST * tmpCandidateClientList = session->candidate_client_list;
 2477         if (    (tmpCandidateClientList != NULL)
 2478                   && (sflist_count(tmpCandidateClientList) > 0) )
 2479         {
 2480             SF_LNODE *node;
 2481             tRNAClientAppModule *client;
 2482 
 2483             ret = CLIENT_APP_INPROCESS;
 2484             node = sflist_first_node(tmpCandidateClientList);
 2485             while (node != NULL)
 2486             {
 2487                 int validator_result;
 2488                 SF_LNODE *node_tmp;
 2489 
 2490                 client = (tRNAClientAppModule*)SFLIST_NODE_TO_DATA(node);
 2491                 validator_result = client->validate(p->payload, p->payload_size, direction,
 2492                                           session, p, client->userData, pConfig);
 2493                 if (app_id_debug_session_flag)
 2494                     _dpd.logMsg("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
 2495                                 client->name ? client->name:"UNKNOWN", validator_result);
 2496 
 2497                 if (validator_result == CLIENT_APP_SUCCESS)
 2498                 {
 2499                     ret = CLIENT_APP_SUCCESS;
 2500                     session->clientData = client;
 2501                     sflist_free(tmpCandidateClientList);
 2502                     session->candidate_client_list = NULL;
 2503                     break;    /* done */
 2504                 }
 2505 
 2506                 node_tmp = node;
 2507                 node = sflist_next_node(tmpCandidateClientList);
 2508                 if (validator_result != CLIENT_APP_INPROCESS)    /* fail */
 2509                 {
 2510                     sflist_remove_node(tmpCandidateClientList, node_tmp);
 2511                 }
 2512             }
 2513         }
 2514     }
 2515     return ret;
 2516 }
 2517 
 2518 static inline void synchAppIdWithSnortId(tAppId newAppId, SFSnortPacket *p, tAppIdData *session, tAppIdConfig *pConfig)
 2519 {
 2520     if (newAppId  > APP_ID_NONE && newAppId < SF_APPID_MAX)
 2521     {
 2522         AppInfoTableEntry *entry;
 2523 
 2524         // Certain AppIds are not useful to identifying snort preprocessor choices
 2525         switch (newAppId)
 2526         {
 2527             case APP_ID_FTPS:
 2528             case APP_ID_FTPSDATA:
 2529 
 2530             // These all are variants of HTTPS
 2531             case APP_ID_DDM_SSL:
 2532             case APP_ID_MSFT_GC_SSL:
 2533             case APP_ID_NSIIOPS:
 2534             case APP_ID_SF_APPLIANCE_MGMT:
 2535             case APP_ID_HTTPS:
 2536 
 2537             case APP_ID_IMAPS:
 2538             case APP_ID_IRCS:
 2539             case APP_ID_LDAPS:
 2540             case APP_ID_NNTPS:
 2541             case APP_ID_POP3S:
 2542             case APP_ID_SMTPS:
 2543             case APP_ID_SSHELL:
 2544             case APP_ID_TELNETS:
 2545                 return;
 2546             case APP_ID_HTTP:
 2547                 if (session->is_http2)
 2548                     newAppId = APP_ID_HTTP2;
 2549                 break;
 2550             default:
 2551                 break;
 2552         }
 2553         if ((entry = pAppidActiveConfig->AppInfoTable[newAppId]) != NULL)
 2554         {
 2555             register int16_t tempSnortId = entry->snortId;
 2556             // A particular APP_ID_xxx may not be assigned a service_snort_key: value
 2557             // in the rna_app.yaml file entry; so ignore the tempSnortId == 0 case.
 2558             // Then if the value is different call the api.
 2559             if ((tempSnortId != 0 || (tempSnortId = (newAppId == APP_ID_HTTP2) ? snortId_for_http2 : 0)) &&
 2560                 tempSnortId != session->snortId)
 2561             {
 2562                 session->snortId = tempSnortId; // remember the most recent change
 2563                 // inform Snort so that other preprocessors can be turned on/off
 2564                 if (app_id_debug_session_flag)
 2565                     if (tempSnortId == snortId_for_http2)
 2566                         _dpd.logMsg("AppIdDbg %s Telling Snort that it's HTTP/2\n", app_id_debug_session);
 2567 #ifdef TARGET_BASED
 2568                 _dpd.sessionAPI->set_application_protocol_id(p->stream_session, tempSnortId);
 2569 #endif
 2570                 p->application_protocol_ordinal = tempSnortId;
 2571             }
 2572         }
 2573     }
 2574 }
 2575 
 2576 static inline void checkTerminateTpModule(uint16_t tpPktCount, tAppIdData *session)
 2577 {
 2578     if ((tpPktCount >= appidStaticConfig->max_tp_flow_depth) ||
 2579         (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
 2580                 (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
 2581          session->hsession && session->hsession->uri &&
 2582          (!session->hsession->chp_candidate || session->hsession->chp_finished)))
 2583     {
 2584         if (session->tpAppId == APP_ID_NONE)
 2585             session->tpAppId = APP_ID_UNKNOWN;
 2586         if (session->rnaServiceState == RNA_STATE_FINISHED && session->payloadAppId == APP_ID_NONE)
 2587             session->payloadAppId = APP_ID_UNKNOWN;
 2588         if (thirdparty_appid_module)
 2589             thirdparty_appid_module->session_delete(session->tpsession, 1);
 2590     }
 2591 }
 2592 
 2593 //#define DEBUG_PACKETS
 2594 #ifdef DEBUG_PACKETS
 2595 #define printSnortPacket( SFSnortPacket_ptr ) debug_printSnortPacket(SFSnortPacket_ptr)
 2596 
 2597 #define CHAR_DUMP_WIDTH 60
 2598 static inline void debug_printSnortPacket (SFSnortPacket *p)
 2599 {
 2600 if (app_id_debug_flag) {
 2601     char *tweakedPayload;
 2602     char *hexPayload;
 2603     _dpd.logMsg("AppIdDbg \n");
 2604     _dpd.logMsg("AppIdDbg ------------------------------------------------\n");
 2605     _dpd.logMsg("AppIdDbg \n");
 2606     if (p->payload != NULL && p->payload_size)
 2607     {
 2608         tweakedPayload= (char *)malloc((CHAR_DUMP_WIDTH*2)+1); // room for hex
 2609         if (tweakedPayload)
 2610         {
 2611             int j;
 2612             int i;
 2613             _dpd.logMsg("AppIdDbg payload: (%d chars per line)\n",CHAR_DUMP_WIDTH);
 2614             for (j=0; j<p->payload_size; j+=CHAR_DUMP_WIDTH)
 2615             {
 2616                 for (i=j; i<p->payload_size && i<(j+CHAR_DUMP_WIDTH); i++)
 2617                 {
 2618                     if((int)p->payload[i] >= 32 && (int)p->payload[i] <=126)
 2619                         tweakedPayload[i-j] = p->payload[i];
 2620                     else
 2621                         tweakedPayload[i-j] = '.';
 2622                 }
 2623                 tweakedPayload[i-j] = '\0';
 2624                 _dpd.logMsg("AppIdDbg %s\n", tweakedPayload);
 2625             }
 2626 //#define DUMP_IN_HEX
 2627 #ifdef DUMP_IN_HEX
 2628             _dpd.logMsg("AppIdDbg HEX payload: (%d chars per line)\n",CHAR_DUMP_WIDTH);
 2629             for (j=0; j<p->payload_size; j+=CHAR_DUMP_WIDTH)
 2630             {
 2631                 for (i=j; i<p->payload_size && i<(j+CHAR_DUMP_WIDTH); i++)
 2632                 {
 2633                     sprintf(&tweakedPayload[(i-j)*2], "%02x", (p->payload)[i]);
 2634                 }
 2635                 // terminating '\0' provided by sprintf()
 2636                 _dpd.logMsg("AppIdDbg %s\n", tweakedPayload);
 2637             }
 2638 #endif
 2639             free(tweakedPayload); tweakedPayload = NULL;
 2640         }
 2641         else
 2642         {
 2643             DynamicPreprocessorFatalMessage("debug_printSnortPacket: "
 2644                     "failed to allocate memory for tweakedPayload\n");
 2645         }
 2646     }
 2647     if (p->stream_session)
 2648     {
 2649         _dpd.logMsg("AppIdDbg \nAppIdDbg for p->stream_session=%p is_session_decrypted=%d direction=%d\n",
 2650                 p->stream_session, _dpd.streamAPI->is_session_decrypted(p->stream_session),
 2651                 _dpd.sessionAPI->get_ignore_direction(p->stream_session));
 2652     }
 2653 
 2654     _dpd.logMsg("AppIdDbg src_port: %d\n", p->src_port);
 2655     _dpd.logMsg("AppIdDbg dst_port: %d\n", p->dst_port);
 2656     _dpd.logMsg("AppIdDbg orig_src_port: %d\n", p->orig_src_port);
 2657     _dpd.logMsg("AppIdDbg rig_dst_port: %d\n", p->orig_dst_port);
 2658     _dpd.logMsg("AppIdDbg payloadsize: %d\n", p->payload_size);
 2659 
 2660     if ((p->flags) & 0x00000080)
 2661     {
 2662         _dpd.logMsg("AppIdDbg direction: client\n");
 2663     }
 2664     else if ((p->flags) & 0x00000040)
 2665     {
 2666         _dpd.logMsg("AppIdDbg direction: server\n");
 2667     }
 2668     else
 2669     {
 2670         _dpd.logMsg("AppIdDbg direction: unknown\n");
 2671     }
 2672 
 2673     if ((p->flags) & 0x00000001) _dpd.logMsg("AppIdDbg A rebuilt fragment\n");
 2674     if ((p->flags) & 0x00000002) _dpd.logMsg("AppIdDbg A rebuilt stream\n");
 2675     if ((p->flags) & 0x00000004) _dpd.logMsg("AppIdDbg From an unestablished stream and we've only seen traffic in one direction\n");
 2676     if ((p->flags) & 0x00000008) _dpd.logMsg("AppIdDbg From an established stream\n");
 2677     if ((p->flags) & 0x00000010) _dpd.logMsg("AppIdDbg this packet has been queued for stream reassembly\n");
 2678     if ((p->flags) & 0x00000020) _dpd.logMsg("AppIdDbg packet completes the 3 way handshake\n");
 2679     if ((p->flags) & 0x00000040) _dpd.logMsg("AppIdDbg packet come from server side of a connection(tcp)\n");
 2680     if ((p->flags) & 0x00000080) _dpd.logMsg("AppIdDbg packet come from client side of a connection(tcp)\n");
 2681     if ((p->flags) & 0x00000100) _dpd.logMsg("AppIdDbg start of PDU\n");
 2682     if ((p->flags) & 0x00000200) _dpd.logMsg("AppIdDbg end of PDU\n");
 2683     if ((p->flags) & 0x00800000) _dpd.logMsg("AppIdDbg packet has new size\n");
 2684 }
 2685 }
 2686 #else
 2687 #define printSnortPacket( SFSnortPacket_ptr )
 2688 #endif
 2689 
 2690 // ============================================
 2691 // Protocol and Direction Determination Section
 2692 // ============================================
 2693 // The getIPn_direction() functions are intended to return the direction for
 2694 // the protocols for the respective IP4 and IP6 headers...
 2695 // Except IPPROTO_TCP and IPPROTO_UDP which are handled within a
 2696 // Snort API call in appDetermineProtocol(), below.
 2697 
 2698 static inline APPID_SESSION_DIRECTION getIP4_direction(SFSnortPacket *p)
 2699 {
 2700     switch (p->ip4h->ip_proto)
 2701     {
 2702         case IPPROTO_ICMP:
 2703             if (p->icmp_header)
 2704             {
 2705                 switch (p->icmp_header->type)
 2706                 {
 2707                     case 4:
 2708                     case 5:
 2709                     case 8:
 2710                     case 13:
 2711                     case 15:
 2712                     case 17:
 2713                         // It is a request type
 2714                         return APP_ID_FROM_INITIATOR;
 2715                     default:
 2716                         break;
 2717                 }
 2718             }
 2719             break;
 2720         default:
 2721             break;
 2722     }
 2723     // no differentiation for this protocol; call it a responder
 2724     // so that every packet will be checked.
 2725     return APP_ID_FROM_RESPONDER;
 2726 }
 2727 static inline APPID_SESSION_DIRECTION getIP6_direction(SFSnortPacket *p)
 2728 {
 2729     switch (p->ip6h->next)
 2730     {
 2731         case IPPROTO_ICMPV6:
 2732             if (p->icmp6h)
 2733             {
 2734                 switch (p->icmp6h->type)
 2735                 {
 2736                     case 138:
 2737                         // only code 0 is a request.
 2738                         if (p->icmp6h->code == 0)
 2739                             return APP_ID_FROM_INITIATOR;
 2740                         break;
 2741                     case 128:
 2742                     case 130:
 2743                     case 133:
 2744                     case 135:
 2745                         // It is a request type
 2746                         return APP_ID_FROM_INITIATOR;
 2747                     default:
 2748                         break;
 2749                 }
 2750             }
 2751             break;
 2752         default:
 2753             break;
 2754     }
 2755     // no differentiation for this protocol; call it a responder
 2756     // so that every packet will be checked.
 2757     return APP_ID_FROM_RESPONDER;
 2758 }
 2759 
 2760 static inline int appDetermineProtocol(SFSnortPacket *p, tAppIdData *session, uint8_t *protocolp, uint8_t *outer_protocol, APPID_SESSION_DIRECTION *directionp)
 2761 {
 2762     // 'session' pointer may be NULL. In which case the packet examination is required.
 2763     // But if 'session' is not NULL we use values saved from the initial creation
 2764     if (session)
 2765     {
 2766         sfaddr_t *ip;
 2767 #ifdef DEBUG_APP_ID_SESSIONS
 2768 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 2769         if (session->service_port == DEBUG_FW_APPID_PORT)
 2770 #endif
 2771         {
 2772             char src_ip[INET6_ADDRSTRLEN];
 2773             char dst_ip[INET6_ADDRSTRLEN];
 2774 
 2775             src_ip[0] = 0;
 2776             ip = GET_SRC_IP(p);
 2777             inet_ntop(sfaddr_family(ip), (void *)sfaddr_get_ptr(ip), src_ip, sizeof(src_ip));
 2778             dst_ip[0] = 0;
 2779             ip = GET_DST_IP(p);
 2780             inet_ntop(sfaddr_family(ip), (void *)sfaddr_get_ptr(ip), dst_ip, sizeof(dst_ip));
 2781             fprintf(SF_DEBUG_FILE, "AppId Session %p %p for %s-%u -> %s-%u %d\n", session, session->ssn, src_ip,
 2782                     (unsigned)p->src_port, dst_ip, (unsigned)p->dst_port, IsTCP(p) ? IPPROTO_TCP:IPPROTO_UDP);
 2783         }
 2784 #endif
 2785         if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_IGNORE)
 2786             return 0; // just ignore
 2787         if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL)
 2788         {
 2789             *protocolp = session->proto;
 2790             session->ssn = p->stream_session;
 2791         }
 2792         else if (IsTCP(p))
 2793             *protocolp = IPPROTO_TCP;
 2794         else
 2795             *protocolp = IPPROTO_UDP;
 2796         ip = GET_SRC_IP(p);
 2797         if (session->common.initiator_port)
 2798             *directionp = (session->common.initiator_port == p->src_port) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 2799         else
 2800             *directionp = (memcmp(sfaddr_get_ip6_ptr(ip), &session->common.initiator_ip, sizeof(session->common.initiator_ip))) ? APP_ID_FROM_RESPONDER: APP_ID_FROM_INITIATOR ;
 2801     }
 2802     else
 2803     {
 2804         if (IsTCP(p))
 2805         {
 2806             *protocolp = IPPROTO_TCP;
 2807             *directionp = (_dpd.sessionAPI->get_packet_direction(p) & FLAG_FROM_CLIENT) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 2808         }
 2809         else if (IsUDP(p))
 2810         {
 2811             *protocolp = IPPROTO_UDP;
 2812             *directionp = (_dpd.sessionAPI->get_packet_direction(p) & FLAG_FROM_CLIENT) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 2813         }
 2814         else if (IsIP(p))
 2815         {
 2816             *protocolp = GET_IPH_PROTO(p);
 2817             if (p->outer_iph_api)
 2818             {
 2819                 IP4Hdr *save_ip4h = p->ip4h;
 2820                 IP6Hdr *save_ip6h = p->ip6h;
 2821 
 2822                 p->ip4h = &p->outer_ip4h;
 2823                 p->ip6h = &p->outer_ip6h;
 2824 
 2825                 *outer_protocol = p->outer_iph_api->iph_ret_proto(p);
 2826 
 2827                 p->ip4h = save_ip4h;
 2828                 p->ip6h = save_ip6h;
 2829             }
 2830 
 2831             if (IS_IP4(p) && p->ip4h)
 2832                 *directionp = getIP4_direction(p);
 2833             else if (p->ip6h)
 2834                 *directionp = getIP6_direction(p);
 2835             else
 2836                 *directionp = APP_ID_FROM_RESPONDER;
 2837         }
 2838         else
 2839         {
 2840             // Neither IPv4 nor IPv6 - currently unsupported
 2841             return 0;
 2842         }
 2843     }
 2844     return 1;
 2845 }
 2846 
 2847 static inline bool checkThirdPartyReinspect(const SFSnortPacket* p, tAppIdData* session)
 2848 {
 2849     return getAppIdFlag(session, APPID_SESSION_HTTP_SESSION) && !getAppIdFlag(session, APPID_SESSION_NO_TPI) && TPIsAppIdDone(session->tpsession) && p->payload_size;
 2850 }
 2851 
 2852 static inline int getIpPortFromHttpTunnel(char *url, int url_len, tunnelDest **tunDest)
 2853 {
 2854     char *host = NULL, *host_start, *host_end, *url_end;
 2855     char *portStr = NULL;
 2856     uint16_t port = 0;
 2857     int isIPv6 = 0, family;
 2858 
 2859     if (url_len <= 0 || !url || !tunDest)
 2860     {
 2861         return 1;
 2862     }
 2863 
 2864     url_end = url + url_len - 1;
 2865     host_start = url;
 2866 
 2867     if (url[0] == '[')
 2868     {
 2869         // IPv6 literal
 2870         isIPv6 = 1;
 2871         portStr = strchr(url, ']');
 2872         if (portStr && portStr < url_end)
 2873         {
 2874             if (*(++portStr) != ':')
 2875             {
 2876                 portStr = NULL;
 2877             }
 2878         }
 2879     }
 2880     else if(isdigit(url[0])) // Checking the first character for a possible domain name.
 2881     {
 2882         portStr = strrchr(url, ':');
 2883     }
 2884     else
 2885     {
 2886         return 1;
 2887     }
 2888 
 2889     if (portStr && portStr < url_end )
 2890     {
 2891         host_end = portStr;
 2892         if (*(++portStr) != '\0')
 2893         {
 2894             char *end = NULL;
 2895             long ret = strtol(portStr, &end, 10);
 2896             if (end != portStr && *end == '\0' && ret >= 1 && ret <= PORT_MAX)
 2897             {
 2898                 port = (uint16_t)ret;
 2899             }
 2900         }
 2901     }
 2902 
 2903     if (port)
 2904     {
 2905         if (isIPv6)
 2906         {
 2907             // IPv6 is enclosed in square braces. Adjusting the pointers.
 2908             host_start++;
 2909             host_end--;
 2910         }
 2911 
 2912         if (host_start <= host_end)
 2913         {
 2914             char tmp = *host_end;
 2915             *host_end = '\0';
 2916             host = strdup(host_start);
 2917             *host_end = tmp;
 2918         }
 2919         else
 2920             return 1;
 2921     }
 2922 
 2923     if (host)
 2924     {
 2925         tunnelDest *tDest = malloc(sizeof(*tDest));
 2926         if (!tDest)
 2927         {
 2928             _dpd.errMsg("AppId: Unable to allocate memory for HTTP tunnel information\n");
 2929             free(host);
 2930             return 1;
 2931         }
 2932 
 2933         if (!isIPv6)
 2934         {
 2935             if (inet_pton(AF_INET, host, &(tDest->ip).ip.s6_addr32[3]) <= 0)
 2936             {
 2937                 free(host);
 2938                 free(tDest);
 2939                 return 1;
 2940             }
 2941             (tDest->ip).ip.s6_addr32[0] = (tDest->ip).ip.s6_addr32[1] =  0;
 2942             (tDest->ip).ip.s6_addr32[2] = ntohl(0x0000ffff);
 2943 
 2944             family = AF_INET;
 2945         }
 2946         else
 2947         {
 2948             if (inet_pton(AF_INET6, host, &(tDest->ip).ip) <= 0)
 2949             {
 2950                 free(host);
 2951                 free(tDest);
 2952                 return 1;
 2953             }
 2954             family = AF_INET6;
 2955         }
 2956 
 2957         (tDest->ip).family = family;
 2958         tDest->port = port;
 2959 
 2960         *tunDest = tDest;
 2961 
 2962         free(host);
 2963     }
 2964     else
 2965     {
 2966         return 1;
 2967     }
 2968 
 2969     return 0;
 2970 }
 2971 
 2972 static int checkHostCache(SFSnortPacket *p, tAppIdData *session, sfaddr_t *ip, uint16_t port, uint8_t protocol, tAppIdConfig *pConfig)
 2973 {
 2974     bool checkStatic = false, checkDynamic = false;
 2975     tHostPortVal *hv = NULL;
 2976 
 2977     if (!(session->scan_flags & SCAN_HOST_PORT_FLAG))
 2978         checkStatic = true;
 2979 
 2980     if (isHostCacheUpdated(session->hostCacheVersion))
 2981     {
 2982         if ((session->session_packet_count % appidStaticConfig->host_port_app_cache_lookup_interval == 0) &&
 2983              session->session_packet_count <= appidStaticConfig->host_port_app_cache_lookup_range &&
 2984              appidStaticConfig->is_host_port_app_cache_runtime)
 2985             checkDynamic = true;
 2986     }
 2987 
 2988     if (!(checkStatic || checkDynamic))
 2989         return 0;
 2990 
 2991     if (checkStatic)
 2992     {
 2993         hv = hostPortAppCacheFind(ip, port, protocol, pConfig);
 2994         session->scan_flags |= SCAN_HOST_PORT_FLAG;
 2995     }
 2996 
 2997     if (!hv && checkDynamic)
 2998     {
 2999         hv = hostPortAppCacheDynamicFind(ip, port, protocol);
 3000         updateHostCacheVersion(&(session->hostCacheVersion));
 3001     }
 3002 
 3003     if (hv)
 3004     {
 3005         switch (hv->type)
 3006         {
 3007             case APP_ID_TYPE_SERVICE:
 3008                 session->serviceAppId = hv->appId;
 3009                 synchAppIdWithSnortId(hv->appId, p, session, pConfig);
 3010                 session->rnaServiceState = RNA_STATE_FINISHED;
 3011                 session->rnaClientState = RNA_STATE_FINISHED;
 3012                 setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED);
 3013                 if (thirdparty_appid_module)
 3014                     thirdparty_appid_module->session_delete(session->tpsession, 1);
 3015         if (session->payloadAppId == APP_ID_NONE)
 3016                     session->payloadAppId = APP_ID_UNKNOWN;
 3017             case APP_ID_TYPE_CLIENT:
 3018                 session->clientAppId = hv->appId;
 3019                 session->rnaClientState = RNA_STATE_FINISHED;
 3020                 break;
 3021             case APP_ID_TYPE_PAYLOAD:
 3022                 session->payloadAppId = hv->appId;
 3023                 break;
 3024             default:
 3025                 break;
 3026         }
 3027         setAppIdFlag(session, APPID_SESSION_HOST_CACHE_MATCHED);
 3028         return 1;
 3029     }
 3030     return 0;
 3031 }
 3032 
 3033 static inline bool isCheckHostCacheValid(tAppIdData* session, tAppId serviceAppId, tAppId clientAppId, tAppId payloadAppId, tAppId miscAppId)
 3034 {
 3035     bool isPayloadClientNone = (payloadAppId <= APP_ID_NONE && clientAppId <= APP_ID_NONE);
 3036 
 3037     bool isAppIdNone = isPayloadClientNone && (serviceAppId <= APP_ID_NONE || serviceAppId == APP_ID_UNKNOWN_UI ||
 3038                         (appidStaticConfig->recheck_for_portservice_appid && serviceAppId == session->portServiceAppId));
 3039 
 3040     bool isSslNone = appidStaticConfig->check_host_cache_unknown_ssl && getAppIdFlag(session, APPID_SESSION_SSL_SESSION) &&
 3041                           !(session->tsession && session->tsession->tls_host && session->tsession->tls_cname);
 3042 
 3043     if(isAppIdNone || isSslNone || appidStaticConfig->check_host_port_app_cache)
 3044     {
 3045         return true;
 3046     }
 3047     return false;
 3048 }
 3049 
 3050 void fwAppIdInit(void)
 3051 {
 3052     /* init globals for snortId compares etc. */
 3053 #ifdef TARGET_BASED
 3054     snortId_for_unsynchronized = _dpd.addProtocolReference("unsynchronized");
 3055     snortId_for_ftp_data = _dpd.findProtocolReference("ftp-data");
 3056     snortId_for_http2    = _dpd.findProtocolReference("http2");
 3057 #endif
 3058     snortInstance = _dpd.getSnortInstance();
 3059 }
 3060 
 3061 static inline tAppId processThirdParty(SFSnortPacket* p, tAppIdData* session, APPID_SESSION_DIRECTION direction, uint8_t protocol, bool* isTpAppidDiscoveryDone,
 3062                                        tAppIdConfig *pConfig)
 3063 {
 3064     tAppId tpAppId = session->tpAppId;
 3065     int tp_confidence;
 3066     tAppId* tp_proto_list;
 3067     ThirdPartyAppIDAttributeData* tp_attribute_data;
 3068     sfaddr_t *ip;
 3069 
 3070     /*** Start of third-party processing. ***/
 3071     PROFILE_VARS;
 3072     PREPROC_PROFILE_START(tpPerfStats);
 3073     if (p->payload_size || appidStaticConfig->tp_allow_probes)
 3074     {
 3075         //restart inspection by 3rd party
 3076         if (!session->tpReinspectByInitiator && (direction == APP_ID_FROM_INITIATOR) && checkThirdPartyReinspect(p, session))
 3077         {
 3078             session->tpReinspectByInitiator = 1;     //once per request
 3079             setAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
 3080             if (app_id_debug_session_flag)
 3081                 _dpd.logMsg("AppIdDbg %s 3rd party allow reinspect http\n", app_id_debug_session);
 3082             session->init_tpPackets = 0;
 3083             session->resp_tpPackets = 0;
 3084             appHttpFieldClear(session->hsession);
 3085         }
 3086 
 3087         if (!isTPProcessingDone(session))
 3088         {
 3089             if (protocol != IPPROTO_TCP || (p->flags & FLAG_STREAM_ORDER_OK) || appidStaticConfig->tp_allow_probes)
 3090             {
 3091                 PREPROC_PROFILE_START(tpLibPerfStats);
 3092                 if (!session->tpsession)
 3093                 {
 3094                     if (!(session->tpsession = thirdparty_appid_module->session_create()))
 3095                         DynamicPreprocessorFatalMessage("Could not allocate tAppIdData->tpsession data");
 3096                 }
 3097                 printSnortPacket(p); // debug output of packet content
 3098                 thirdparty_appid_module->session_process(session->tpsession, p, direction,
 3099                                                          &tpAppId, &tp_confidence, &tp_proto_list, &tp_attribute_data);
 3100                 PREPROC_PROFILE_END(tpLibPerfStats);
 3101 
 3102                 // First SSL decrypted packet is now being inspected. Reset the flag so that SSL decrypted traffic
 3103                 // gets processed like regular traffic from next packet onwards
 3104                 if (getAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL))
 3105                     clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL);
 3106 
 3107                 *isTpAppidDiscoveryDone = true;
 3108 
 3109                 if (thirdparty_appid_module->session_state_get(session->tpsession) == TP_STATE_CLASSIFIED)
 3110                     clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
 3111 
 3112                 if (app_id_debug_session_flag)
 3113                     _dpd.logMsg("AppIdDbg %s 3rd party returned %d\n", app_id_debug_session, tpAppId);
 3114 #ifdef DEBUG_FW_APPID
 3115 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3116                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3117 #endif
 3118                     fprintf(SF_DEBUG_FILE, "%u -> %u %u 3rd party returned %d\n",
 3119                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, tpAppId);
 3120 #endif
 3121 
 3122                 // For now, third party can detect HTTP/2 (w/o metadata) for
 3123                 // some cases.  Treat it like HTTP w/ is_http2 flag set.
 3124                 if ((tpAppId == APP_ID_HTTP2) && (tp_confidence == 100))
 3125                 {
 3126                     if (app_id_debug_session_flag)
 3127                         _dpd.logMsg("AppIdDbg %s 3rd party saw HTTP/2\n", app_id_debug_session);
 3128                     tpAppId = APP_ID_HTTP;
 3129                     session->is_http2 = true;
 3130                 }
 3131 
 3132                 // if the third-party appId must be treated as a client, do it now
 3133                 uint32_t entryFlags = appInfoEntryFlags(tpAppId, pConfig);
 3134                 if (entryFlags & APPINFO_FLAG_TP_CLIENT)
 3135                     session->clientAppId = tpAppId;
 3136 
 3137                 ProcessThirdPartyResults(p, direction, session, tp_confidence, tp_proto_list, tp_attribute_data);
 3138 
 3139                 if ((entryFlags & APPINFO_FLAG_SSL_SQUELCH) &&
 3140                     getAppIdFlag(session, APPID_SESSION_SSL_SESSION) &&
 3141                     !(session->scan_flags & SCAN_SSL_HOST_FLAG))
 3142                 {
 3143                     if (!(session->scan_flags & SCAN_SPOOFED_SNI_FLAG))
 3144                     {
 3145                         setSSLSquelch(p, 1, tpAppId);
 3146                     }
 3147                     else
 3148                     {
 3149                         if (app_id_debug_session_flag)
 3150                             _dpd.logMsg("AppIdDbg %s Ignored 3rd party returned %d, SNI is spoofed\n",
 3151                                 app_id_debug_session, tpAppId);
 3152                     }
 3153                 }
 3154 
 3155                 if (entryFlags & APPINFO_FLAG_IGNORE)
 3156                 {
 3157                     if (app_id_debug_session_flag)
 3158                         _dpd.logMsg("AppIdDbg %s 3rd party ignored\n", app_id_debug_session);
 3159                     if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION))
 3160                         tpAppId = APP_ID_HTTP;
 3161                     else if(getAppIdFlag(session, APPID_SESSION_SSL_SESSION))
 3162                         tpAppId = APP_ID_SSL;
 3163                     else
 3164                         tpAppId = APP_ID_NONE;
 3165                 }
 3166             }
 3167             else
 3168             {
 3169                 tpAppId = APP_ID_NONE;
 3170 #ifdef DEBUG_FW_APPID
 3171 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3172                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3173 #endif
 3174                     fprintf(SF_DEBUG_FILE, "%u -> %u %u Skipping ooo\n",
 3175                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol);
 3176 #endif
 3177             }
 3178 
 3179             if (thirdparty_appid_module->session_state_get(session->tpsession) == TP_STATE_MONITORING)
 3180             {
 3181                 thirdparty_appid_module->disable_flags(session->tpsession, TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING | TP_SESSION_FLAG_FUTUREFLOW);
 3182             }
 3183 #ifdef TARGET_BASED
 3184             if(tpAppId == APP_ID_SSL && (_dpd.sessionAPI->get_application_protocol_id(p->stream_session) == snortId_for_ftp_data))
 3185             {
 3186                 //  If we see SSL on an FTP data channel set tpAppId back
 3187                 //  to APP_ID_NONE so the FTP preprocessor picks up the flow.
 3188                 tpAppId = APP_ID_NONE;
 3189             }
 3190 #endif
 3191             if (tpAppId > APP_ID_NONE && (!getAppIdFlag(session, APPID_SESSION_APP_REINSPECT) || session->payloadAppId > APP_ID_NONE))
 3192             {
 3193 #ifdef TARGET_BASED
 3194                 tAppId snortAppId;
 3195 #endif
 3196 
 3197                 // if the packet is HTTP, then search for via pattern
 3198                 if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION) && session->hsession)
 3199                 {
 3200 #ifdef TARGET_BASED
 3201                     snortAppId = APP_ID_HTTP;
 3202 #endif
 3203                     //payload should never be APP_ID_HTTP
 3204                     if (tpAppId != APP_ID_HTTP)
 3205                         setTPPayloadAppIdData(p, direction, session, tpAppId);
 3206 
 3207 #ifdef DEBUG_FW_APPID
 3208 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3209                     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3210 #endif
 3211                         fprintf(SF_DEBUG_FILE, "%u -> %u %u tp identified http payload %d\n",
 3212                                 (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, tpAppId);
 3213 #endif
 3214 
 3215                     session->tpAppId = APP_ID_HTTP;
 3216 
 3217                     processHTTPPacket(p, session, direction, NULL, pConfig);
 3218 
 3219                     if (TPIsAppIdAvailable(session->tpsession) && session->tpAppId == APP_ID_HTTP
 3220                                                         && !getAppIdFlag(session, APPID_SESSION_APP_REINSPECT))
 3221                     {
 3222                         session->rnaClientState = RNA_STATE_FINISHED;
 3223                         setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_SERVICE_DETECTED);
 3224                         session->rnaServiceState = RNA_STATE_FINISHED;
 3225                         clearAppIdFlag(session, APPID_SESSION_CONTINUE);
 3226 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3227                         session->carrierId = p->pkt_header->carrier_id;
 3228 #endif
 3229                         if (direction == APP_ID_FROM_INITIATOR)
 3230                         {
 3231                             ip = GET_DST_IP(p);
 3232                             session->service_ip = *ip;
 3233                             session->service_port = p->dst_port;
 3234 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3235                             session->serviceAsId = p->pkt_header->address_space_id_dst;
 3236 #endif
 3237                         }
 3238                         else
 3239                         {
 3240                             ip = GET_SRC_IP(p);
 3241                             session->service_ip = *ip;
 3242                             session->service_port = p->src_port;
 3243 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3244                             session->serviceAsId = p->pkt_header->address_space_id_src;
 3245 #endif
 3246                         }
 3247                     }
 3248                 }
 3249                 else if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) && session->tsession)
 3250                 {
 3251                     ExamineSslMetadata(p, direction, session, pConfig);
 3252 
 3253                     uint16_t serverPort;
 3254                     tAppId portAppId;
 3255 
 3256                     serverPort = (direction == APP_ID_FROM_INITIATOR)? p->dst_port:p->src_port;
 3257 
 3258                     portAppId = getSslServiceAppId(serverPort);
 3259                     if (tpAppId == APP_ID_SSL )
 3260                     {
 3261                         tpAppId = portAppId;
 3262 
 3263                         //SSL policy needs to determine IMAPS/POP3S etc before appId sees first server packet
 3264                         session->portServiceAppId = portAppId;
 3265 
 3266                         if (app_id_debug_session_flag)
 3267                             _dpd.logMsg("AppIdDbg %s SSL is service %d, portServiceAppId %d\n",
 3268                                     app_id_debug_session, tpAppId, session->portServiceAppId);
 3269                     }
 3270                     else
 3271                     {
 3272                         if (!(session->scan_flags & SCAN_SPOOFED_SNI_FLAG))
 3273                         {
 3274                             setTPPayloadAppIdData(p, direction, session, tpAppId);
 3275                         }
 3276                         else
 3277                         {
 3278                             if (app_id_debug_session_flag)
 3279                                 _dpd.logMsg("AppIdDbg %s Ignoring 3rd party returned %d, SNI is spoofed\n",
 3280                                     app_id_debug_session, tpAppId);
 3281                         }
 3282                         tpAppId = portAppId;
 3283                         if (app_id_debug_session_flag)
 3284                             _dpd.logMsg("AppIdDbg %s SSL is %d\n", app_id_debug_session, tpAppId);
 3285                     }
 3286             setTPAppIdData(p, direction, session, tpAppId);
 3287 #ifdef TARGET_BASED
 3288                     snortAppId = APP_ID_SSL;
 3289 #endif
 3290 
 3291 #ifdef DEBUG_FW_APPID
 3292 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3293                     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3294 #endif
 3295                         fprintf(SF_DEBUG_FILE, "%u -> %u %u tp identified ssl service %d\n",
 3296                                 (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, tpAppId);
 3297 #endif
 3298                 }
 3299                 else
 3300                 {
 3301                     //for non-http protocols, tp id is treated like serviceId
 3302 
 3303 #ifdef TARGET_BASED
 3304                     snortAppId = tpAppId;
 3305 #endif
 3306 
 3307 #ifdef DEBUG_FW_APPID
 3308 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3309                     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3310 #endif
 3311                         fprintf(SF_DEBUG_FILE, "%u -> %u %u tp identified non-http service %d\n",
 3312                                 (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, tpAppId);
 3313 #endif
 3314                     setTPAppIdData(p, direction, session, tpAppId);
 3315                 }
 3316 
 3317 #ifdef TARGET_BASED
 3318                 synchAppIdWithSnortId(snortAppId, p, session, pConfig);
 3319 #endif
 3320             }
 3321             else
 3322             {
 3323                 if ((session->serviceAppId != APP_ID_ENIP && session->serviceAppId != APP_ID_CIP) &&
 3324                    (protocol != IPPROTO_TCP || (p->flags & (FLAG_STREAM_ORDER_OK | FLAG_STREAM_ORDER_BAD))))
 3325                 {
 3326                     if (direction == APP_ID_FROM_INITIATOR)
 3327                     {
 3328                         session->init_tpPackets++;
 3329                         checkTerminateTpModule(session->init_tpPackets, session);
 3330                     }
 3331                     else
 3332                     {
 3333                         session->resp_tpPackets++;
 3334                         checkTerminateTpModule(session->resp_tpPackets, session);
 3335                     }
 3336                 }
 3337             }
 3338         }
 3339 
 3340         else if (session->hsession && (direction == APP_ID_FROM_RESPONDER) &&
 3341             getAppIdFlag(session, APPID_SESSION_HTTP_CONNECT))
 3342         {
 3343             if ((p->payload_size >= 13) && !strncasecmp((char *)p->payload, "HTTP/1.1 200 ", 13))
 3344                 session->hsession->is_tunnel = true;
 3345         }
 3346         if (session->tpReinspectByInitiator && checkThirdPartyReinspect(p, session))
 3347         {
 3348             if (*isTpAppidDiscoveryDone)
 3349                 clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
 3350             if (direction == APP_ID_FROM_RESPONDER)
 3351                 session->tpReinspectByInitiator = 0; //toggle at OK response
 3352         }
 3353     }
 3354     PREPROC_PROFILE_END(tpPerfStats);
 3355     /*** End of third-party processing. ***/
 3356 
 3357     return tpAppId;
 3358 }
 3359 
 3360 void fwAppIdSearch(SFSnortPacket *p)
 3361 {
 3362     tAppIdData *session;
 3363     uint8_t protocol, outer_protocol = 0;
 3364     APPID_SESSION_DIRECTION direction;
 3365     tAppId tpAppId = 0;
 3366     tAppId serviceAppId = 0;
 3367     tAppId clientAppId = 0;
 3368     tAppId payloadAppId = 0;
 3369     tAppId miscAppId = 0;
 3370     bool isTpAppidDiscoveryDone = false;
 3371     uint64_t flow_flags;
 3372     sfaddr_t *ip;
 3373     uint16_t port;
 3374     size_t size;
 3375 #ifdef TARGET_BASED
 3376     AppInfoTableEntry *entry;
 3377 #endif
 3378     tAppIdConfig *pConfig = appIdActiveConfigGet();
 3379 
 3380 #ifdef UNIT_TEST_FIRST_DECRYPTED_PACKET
 3381     if(app_id_raw_packet_count==0)
 3382         _dpd.streamAPI->is_session_decrypted=is_session_decrypted_unit_test;
 3383 #endif
 3384 
 3385     app_id_raw_packet_count++;
 3386 
 3387     if (!p->stream_session || (p->payload_size && !p->payload))
 3388     {
 3389         app_id_ignored_packet_count++;
 3390         return;
 3391     }
 3392 
 3393     SetPacketRealTime(p->pkt_header->ts.tv_sec);
 3394 
 3395     session = appSharedGetData(p);
 3396     if (!appDetermineProtocol(p, session, &protocol, &outer_protocol, &direction))
 3397     {
 3398         // unsupported protocol or other ignore
 3399         app_id_ignored_packet_count++;
 3400         return;
 3401     }
 3402 
 3403     if (pConfig->debugHostIp)
 3404     {
 3405         AppIdDebugHostInfo.session = session;
 3406         AppIdDebugHostInfo.protocol = protocol;
 3407         AppIdDebugHostInfo.direction = direction;
 3408         if (session)
 3409         {
 3410             memcpy(&AppIdDebugHostInfo.initiatorIp, &session->common.initiator_ip, sizeof(session->common.initiator_ip));
 3411             AppIdDebugHostInfo.initiatorPort = session->common.initiator_port;
 3412             AppIdDebugHostInfo.family = sfaddr_family(GET_SRC_IP(p));
 3413         }
 3414         else
 3415         {
 3416             memset(&AppIdDebugHostInfo.initiatorIp, 0, sizeof(session->common.initiator_ip));
 3417             AppIdDebugHostInfo.initiatorPort = 0;
 3418             AppIdDebugHostInfo.family = AF_INET;
 3419         }
 3420         AppIdDebugHostInfo.monitorType = APPID_DEBUG_HOST_NOT_MONITORED;
 3421     }
 3422 
 3423     app_id_debug_session_flag = fwAppIdDebugCheck(p->stream_session, session, app_id_debug_flag,
 3424             &app_id_debug_info, app_id_debug_session, direction);
 3425 
 3426 #ifdef DEBUG_FW_APPID
 3427 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3428     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3429 #endif
 3430     {
 3431         char sipstr[INET6_ADDRSTRLEN];
 3432         char dipstr[INET6_ADDRSTRLEN];
 3433 
 3434         sipstr[0] = 0;
 3435         ip = GET_SRC_IP(p);
 3436         inet_ntop(sfaddr_family(ip), (void *)sfaddr_get_ptr(ip), sipstr, sizeof(sipstr));
 3437         dipstr[0] = 0;
 3438         ip = GET_DST_IP(p);
 3439         inet_ntop(sfaddr_family(ip), (void *)sfaddr_get_ptr(ip), dipstr, sizeof(dipstr));
 3440 
 3441 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3442         uint32_t cid = p->pkt_header->carrier_id;
 3443 
 3444 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3445         uint16_t sAsId = p->pkt_header->address_space_id_src;
 3446         uint16_t dAsId = p->pkt_header->address_space_id_dst;
 3447 
 3448         fprintf(SF_DEBUG_FILE, "%s-%u -> %s-%u  AS %u-%u CID %u %u\n", sipstr,
 3449                 (unsigned)p->src_port, dipstr, (unsigned)p->dst_port,
 3450                 sAsId, dAsId, (unsigned)cid, (unsigned)protocol);
 3451 #else
 3452         fprintf(SF_DEBUG_FILE, "%s-%u -> %s-%u CID %u %u\n", sipstr, (unsigned)p->src_port, dipstr, (unsigned)p->dst_port, (unsigned)cid,
 3453                 (unsigned)protocol);
 3454 #endif /* No Carrierid support*/
 3455 #else
 3456 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3457         uint16_t sAsId = p->pkt_header->address_space_id_src;
 3458         uint16_t dAsId = p->pkt_header->address_space_id_dst;
 3459         fprintf(SF_DEBUG_FILE, "%s-%u -> %s-%u  AS %u-%u %u\n", sipstr,
 3460                 (unsigned)p->src_port, dipstr, (unsigned)p->dst_port,
 3461                 sAsId, dAsId, (unsigned)protocol);
 3462 #else
 3463         fprintf(SF_DEBUG_FILE, "%s-%u -> %s-%u %u\n", sipstr, (unsigned)p->src_port, dipstr, (unsigned)p->dst_port, (unsigned)protocol);
 3464 #endif
 3465 #endif
 3466 
 3467         /*DumpHex(SF_DEBUG_FILE, p->payload, p->payload_size); */
 3468     }
 3469 #endif
 3470 
 3471     if (protocol == IPPROTO_TCP) // HTTP is a subset of TCP
 3472     {
 3473         if (_dpd.streamAPI->is_session_http2(p->stream_session))
 3474         {
 3475             if (session)
 3476                 session->is_http2 = true;
 3477             if (!(p->flags & FLAG_REBUILT_STREAM))
 3478             {
 3479                 // For HTTP/2, we only want to look at the ones that are rebuilt from
 3480                 // Stream / HTTP Inspect as HTTP/1 packets.
 3481                 app_id_ignored_packet_count++;
 3482                 return;
 3483             }
 3484         }
 3485         else    // not HTTP/2
 3486         {
 3487             if (p->flags & FLAG_REBUILT_STREAM && !_dpd.streamAPI->is_session_decrypted(p->stream_session))
 3488             {
 3489                 if (direction == APP_ID_FROM_INITIATOR && session && session->hsession && session->hsession->get_offsets_from_rebuilt)
 3490                 {
 3491                     httpGetNewOffsetsFromPacket(p, session->hsession, pConfig);
 3492                     if (app_id_debug_session_flag)
 3493                         _dpd.logMsg("AppIdDbg %s offsets from rebuilt packet: uri: %u-%u cookie: %u-%u\n", app_id_debug_session, session->hsession->fieldOffset[REQ_URI_FID], session->hsession->fieldEndOffset[REQ_URI_FID], session->hsession->fieldOffset[REQ_COOKIE_FID], session->hsession->fieldEndOffset[REQ_COOKIE_FID]);
 3494                 }
 3495                 app_id_ignored_packet_count++;
 3496                 return;
 3497             }
 3498         }
 3499     }
 3500     // fwAppIdSearch() is a top-level function that is called by AppIdProcess().
 3501     // At this point, we know that we need to use the current active config -
 3502     // pAppidActiveConfig. This function uses pAppidActiveConfig and passes it
 3503     // to all the functions that need to look at AppId config.
 3504     flow_flags = isSessionMonitored(p, direction, session);
 3505     if (!(flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)))
 3506     {
 3507         if (!session)
 3508         {
 3509             if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) == APPID_SESSION_BIDIRECTIONAL_CHECKED)
 3510             {
 3511                 static APPID_SESSION_STRUCT_FLAG ignore_fsf = {.flow_type = APPID_SESSION_TYPE_IGNORE};
 3512                 _dpd.sessionAPI->set_application_data(p->stream_session, PP_APP_ID, &ignore_fsf, NULL);
 3513                 if (app_id_debug_session_flag)
 3514                     _dpd.logMsg("AppIdDbg %s not monitored\n", app_id_debug_session);
 3515             }
 3516             else
 3517             {
 3518                 tTmpAppIdData *tmp_session;
 3519 
 3520                 if (tmp_app_id_free_list)
 3521                 {
 3522                     tmp_session = tmp_app_id_free_list;
 3523                     tmp_app_id_free_list = tmp_session->next;
 3524                 }
 3525                 else if (!(tmp_session = malloc(sizeof(*tmp_session))))
 3526                     DynamicPreprocessorFatalMessage("Could not allocate tTmpAppIdData data");
 3527                 tmp_session->common.fsf_type.flow_type = APPID_SESSION_TYPE_TMP;
 3528                 tmp_session->common.flags = flow_flags;
 3529                 ip = (direction == APP_ID_FROM_INITIATOR) ? GET_SRC_IP(p) : GET_DST_IP(p);
 3530                 sfaddr_copy_to_raw(&tmp_session->common.initiator_ip, ip);
 3531                 if ((protocol == IPPROTO_TCP || protocol == IPPROTO_UDP) && p->src_port != p->dst_port)
 3532                     tmp_session->common.initiator_port = (direction == APP_ID_FROM_INITIATOR) ? p->src_port : p->dst_port;
 3533                 else
 3534                     tmp_session->common.initiator_port = 0;
 3535                 tmp_session->common.policyId = appIdPolicyId;
 3536                 _dpd.sessionAPI->set_application_data(p->stream_session, PP_APP_ID,
 3537                         tmp_session, (void (*)(void*))appTmpSharedDataFree);
 3538                 if (app_id_debug_session_flag)
 3539                     _dpd.logMsg("AppIdDbg %s unknown monitoring\n", app_id_debug_session);
 3540             }
 3541         }
 3542         else
 3543         {
 3544             session->common.flags = flow_flags;
 3545             if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) == APPID_SESSION_BIDIRECTIONAL_CHECKED)
 3546                 session->common.fsf_type.flow_type = APPID_SESSION_TYPE_IGNORE;
 3547             session->common.policyId = appIdPolicyId;
 3548             if (app_id_debug_session_flag)
 3549                 _dpd.logMsg("AppIdDbg %s not monitored\n", app_id_debug_session);
 3550         }
 3551         return;
 3552     }
 3553 
 3554     if (!session || session->common.fsf_type.flow_type == APPID_SESSION_TYPE_TMP)
 3555     {
 3556         /* This call will free the existing temporary session, if there is one */
 3557         session = appSharedCreateData(p, protocol, direction);
 3558         if (_dpd.sessionAPI->get_session_flags(p->stream_session) & SSNFLAG_MIDSTREAM)
 3559         {
 3560             flow_flags |= APPID_SESSION_MID; // set once per flow
 3561             if (app_id_debug_session_flag)
 3562                 _dpd.logMsg("AppIdDbg %s new mid-stream session\n", app_id_debug_session);
 3563         }
 3564         else if (app_id_debug_session_flag)
 3565             _dpd.logMsg("AppIdDbg %s new session\n", app_id_debug_session);
 3566     }
 3567 
 3568     app_id_processed_packet_count++;
 3569     session->session_packet_count++;
 3570 
 3571     if (direction == APP_ID_FROM_INITIATOR)
 3572     {
 3573         session->stats.initiatorBytes += p->pkt_header->pktlen;
 3574         if ( p->payload_size)
 3575         {
 3576             session->initiatorPcketCountWithoutReply ++;
 3577             session->initiatorBytesWithoutServerReply += p->payload_size;
 3578         }
 3579     }
 3580     else
 3581     {
 3582         session->stats.responderBytes += p->pkt_header->pktlen;
 3583         if(p->payload_size)
 3584         {
 3585             session->initiatorPcketCountWithoutReply = 0;
 3586             session->initiatorBytesWithoutServerReply = 0;
 3587         }
 3588     }
 3589     session->common.flags = flow_flags;
 3590     session->common.policyId = appIdPolicyId;
 3591 
 3592     tpAppId = session->tpAppId;
 3593 
 3594     session->common.policyId = appIdPolicyId;
 3595 
 3596 #ifdef DEBUG_FW_APPID
 3597 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3598     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3599     {
 3600 #endif
 3601         fprintf(SF_DEBUG_FILE, "%u %u -> %u %u Begin %d %u - (%d %d %d %d %d) %u %" PRIx64 " %" PRIx64 " (%u %u %u)\n",
 3602                 (unsigned )session->session_packet_count, (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, direction,
 3603                 (unsigned)p->payload_size, session->serviceAppId, session->clientAppId, session->payloadAppId, tpAppId, session->miscAppId,
 3604                 session->rnaServiceState, session->common.flags, p->flags, thirdparty_appid_module->session_state_get(session->tpsession),
 3605                 (unsigned)session->init_tpPackets, (unsigned)session->resp_tpPackets);
 3606         /*DumpHex(SF_DEBUG_FILE, p->payload, p->payload_size); */
 3607 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3608     }
 3609 #endif
 3610 #endif
 3611 
 3612     if (getAppIdFlag(session, APPID_SESSION_IGNORE_FLOW))
 3613     {
 3614         if (app_id_debug_session_flag && !getAppIdFlag(session, APPID_SESSION_IGNORE_FLOW_LOGGED))
 3615         {
 3616             setAppIdFlag(session, APPID_SESSION_IGNORE_FLOW_LOGGED);
 3617             _dpd.logMsg("AppIdDbg %s Ignoring flow with service %d\n", app_id_debug_session, session->serviceAppId);
 3618         }
 3619         return;
 3620     }
 3621 
 3622     if (p->tcp_header && !getAppIdFlag(session, APPID_SESSION_OOO))
 3623     {
 3624         if ((p->flags & FLAG_STREAM_ORDER_BAD) ||
 3625             (p->payload_size && !(p->flags & (FLAG_STREAM_ORDER_OK | FLAG_RETRANSMIT | FLAG_REBUILT_STREAM))))
 3626         {
 3627             setAppIdFlag(session, APPID_SESSION_OOO | APPID_SESSION_OOO_CHECK_TP);
 3628             if (app_id_debug_session_flag)
 3629                 _dpd.logMsg("AppIdDbg %s Packet out-of-order, %s%sflow\n", app_id_debug_session,
 3630                     (p->flags & FLAG_STREAM_ORDER_BAD)? "bad ":"not-ok ",
 3631                     getAppIdFlag(session, APPID_SESSION_MID)? "mid-stream ":"");
 3632 
 3633             /* Shut off service/client discoveries, since they skip not-ok data packets and
 3634                may keep failing on subsequent data packets causing performance degradation. */
 3635             if (!getAppIdFlag(session, APPID_SESSION_MID) || (p->src_port != 21 && p->dst_port != 21)) // exception for ftp-control
 3636             {
 3637                 session->rnaServiceState = RNA_STATE_FINISHED;
 3638                 session->rnaClientState = RNA_STATE_FINISHED;
 3639                 if ((TPIsAppIdAvailable(session->tpsession) || getAppIdFlag(session, APPID_SESSION_NO_TPI)) &&
 3640                     session->payloadAppId == APP_ID_NONE)
 3641                     session->payloadAppId = APP_ID_UNKNOWN;
 3642                 setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CLIENT_DETECTED);
 3643                 if (app_id_debug_session_flag)
 3644                     _dpd.logMsg("AppIdDbg %s stopped service/client discovery\n", app_id_debug_session);
 3645             }
 3646         }
 3647         else
 3648         {
 3649             if ((p->tcp_header->flags & TCPHEADER_RST) && session->previous_tcp_flags == TCPHEADER_SYN)
 3650             {
 3651                 AppIdServiceIDState *id_state;
 3652 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3653                 uint16_t asId;
 3654 #endif
 3655 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3656                 uint32_t cid = 0;
 3657 #endif
 3658                 setAppIdFlag(session, APPID_SESSION_SYN_RST);
 3659                 if (sfaddr_is_set(&session->service_ip))
 3660                 {
 3661                     ip = &session->service_ip;
 3662                     port = session->service_port;
 3663 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3664                     asId = session->serviceAsId; 
 3665 #endif
 3666 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3667                     cid = session->carrierId;
 3668 #endif
 3669                 }
 3670                 else
 3671                 {
 3672                     ip = GET_SRC_IP(p);
 3673                     port = p->src_port;
 3674 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3675                     asId = p->pkt_header->address_space_id_src;
 3676 #endif
 3677 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3678                     cid = p->pkt_header->carrier_id;
 3679 #endif
 3680                 }
 3681 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID) 
 3682 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3683                 id_state = AppIdGetServiceIDState(ip, IPPROTO_TCP, port, 
 3684                                                   AppIdServiceDetectionLevel(session), asId, cid);
 3685 #else
 3686                 id_state = AppIdGetServiceIDState(ip, IPPROTO_TCP, port, AppIdServiceDetectionLevel(session), cid);
 3687 #endif  
 3688 #else /* No Carrierid support */
 3689 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3690                 id_state = AppIdGetServiceIDState(ip, IPPROTO_TCP, port,
 3691                                                   AppIdServiceDetectionLevel(session), asId);
 3692 #else
 3693                 id_state = AppIdGetServiceIDState(ip, IPPROTO_TCP, port, AppIdServiceDetectionLevel(session));
 3694 #endif
 3695 #endif
 3696                 if (id_state)
 3697                 {
 3698                     if (!id_state->reset_time)
 3699                         id_state->reset_time = GetPacketRealTime;
 3700                     else if ((GetPacketRealTime - id_state->reset_time) >= 60)
 3701                     {
 3702 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 3703 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3704                         AppIdRemoveServiceIDState(ip, IPPROTO_TCP, port, 
 3705                                                   AppIdServiceDetectionLevel(session),
 3706                                                   asId, cid);
 3707 #else
 3708                         AppIdRemoveServiceIDState(ip, IPPROTO_TCP, port, AppIdServiceDetectionLevel(session), cid);
 3709 #endif
 3710 #else /* No carrier id support */
 3711 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 3712                         AppIdRemoveServiceIDState(ip, IPPROTO_TCP, port,
 3713                                                   AppIdServiceDetectionLevel(session),
 3714                                                   asId);
 3715 #else
 3716 
 3717                         AppIdRemoveServiceIDState(ip, IPPROTO_TCP, port, AppIdServiceDetectionLevel(session));
 3718 #endif
 3719 #endif
 3720                         setAppIdFlag(session, APPID_SESSION_SERVICE_DELETED);
 3721                     }
 3722                 }
 3723             }
 3724             session->previous_tcp_flags = p->tcp_header->flags;
 3725         }
 3726     }
 3727 
 3728     checkRestartAppDetection(session);
 3729 
 3730     if (outer_protocol)
 3731     {
 3732         session->miscAppId = pConfig->ip_protocol[outer_protocol];
 3733         if (app_id_debug_session_flag)
 3734             _dpd.logMsg("AppIdDbg %s outer protocol service %d\n", app_id_debug_session, session->miscAppId);
 3735     }
 3736 
 3737     if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
 3738     {
 3739         if (!getAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE))
 3740         {
 3741             session->serviceAppId = session->portServiceAppId = getProtocolServiceId(protocol, pConfig);
 3742             if (app_id_debug_session_flag)
 3743                 _dpd.logMsg("AppIdDbg %s protocol service %d\n", app_id_debug_session, session->portServiceAppId);
 3744             setAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE);
 3745             session->rnaServiceState = RNA_STATE_FINISHED;
 3746             _dpd.streamAPI->set_application_id(p->stream_session, session->serviceAppId, clientAppId, payloadAppId, session->miscAppId);
 3747         }
 3748         return;
 3749     }
 3750 
 3751     if (session->tpAppId == APP_ID_SSH && session->payloadAppId != APP_ID_SFTP && session->session_packet_count >= MIN_SFTP_PACKET_COUNT && session->session_packet_count < MAX_SFTP_PACKET_COUNT)
 3752     {
 3753         if (GET_IPH_TOS(p) == 8)
 3754         {
 3755             session->payloadAppId = APP_ID_SFTP;
 3756             if (app_id_debug_session_flag)
 3757                 _dpd.logMsg("AppIdDbg %s payload is SFTP\n", app_id_debug_session);
 3758         }
 3759     }
 3760 
 3761     tpAppId = processThirdParty(p, session, direction, protocol, &isTpAppidDiscoveryDone, pConfig);
 3762 
 3763     if (!getAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE))
 3764     {
 3765         switch (protocol)
 3766         {
 3767         case IPPROTO_TCP:
 3768             // TCP-specific checks. No SYN/RST, and no SYN/ACK
 3769             // we have to check for SYN/ACK here explicitly in case of TCP Fast Open
 3770             if (getAppIdFlag(session, APPID_SESSION_SYN_RST) ||
 3771                 (p->tcp_header && (p->tcp_header->flags & TCPHEADER_SYN) &&
 3772                 (p->tcp_header->flags & TCPHEADER_ACK)))
 3773                 break;
 3774             // fall through to next test
 3775         case IPPROTO_UDP:
 3776             // Both TCP and UDP need these tests to be made
 3777             // packet must be from responder, and with a non-zero payload size
 3778             // For all other cases the port parameter is never checked.
 3779             if (p->payload_size < 1 || direction != APP_ID_FROM_RESPONDER)
 3780                 break;
 3781             // fall through to all other cases
 3782         default:
 3783             {
 3784                 session->portServiceAppId = getPortServiceId(protocol, p->src_port, pConfig);
 3785                 if (app_id_debug_session_flag)
 3786                     _dpd.logMsg("AppIdDbg %s port service %d\n", app_id_debug_session, session->portServiceAppId);
 3787                 setAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE);
 3788             }
 3789             break;
 3790         }
 3791     }
 3792 
 3793     /* Length-based detectors. */
 3794     /* Only check if:
 3795      *  - Port service didn't find anything (and we haven't yet either).
 3796      *  - We haven't hit the max packets allowed for detector sequence matches.
 3797      *  - Packet has in-order data (we'll ignore 0-sized packets in sequencing). */
 3798     if (   (p->payload_size > 0)
 3799         && (session->portServiceAppId <= APP_ID_NONE)
 3800         && (session->length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX)
 3801         && !getAppIdFlag(session, APPID_SESSION_OOO))
 3802     {
 3803         uint8_t index = session->length_sequence.sequence_cnt;
 3804         session->length_sequence.proto = protocol;
 3805         session->length_sequence.sequence_cnt++;
 3806         session->length_sequence.sequence[index].direction = direction;
 3807         session->length_sequence.sequence[index].length    = p->payload_size;
 3808         session->portServiceAppId = lengthAppCacheFind(&session->length_sequence, pConfig);
 3809         if (session->portServiceAppId > APP_ID_NONE)
 3810         {
 3811             setAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE);
 3812         }
 3813     }
 3814 
 3815     /* exceptions for rexec and any other service detector that needs to see SYN and SYN/ACK */
 3816     if (getAppIdFlag(session, APPID_SESSION_REXEC_STDERR))
 3817     {
 3818         AppIdDiscoverService(p, direction, session, pConfig);
 3819 
 3820         if (getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE) ==
 3821             APPID_SESSION_SERVICE_DETECTED)
 3822         {
 3823             session->rnaServiceState = RNA_STATE_FINISHED;
 3824             if (session->payloadAppId == APP_ID_NONE)
 3825                 session->payloadAppId = APP_ID_UNKNOWN;
 3826         }
 3827     }
 3828 
 3829     else if (protocol != IPPROTO_TCP || (p->flags & FLAG_STREAM_ORDER_OK) || getAppIdFlag(session, APPID_SESSION_MID))
 3830     {
 3831         /*** Start of service discovery. ***/
 3832         if (session->rnaServiceState != RNA_STATE_FINISHED)
 3833         {
 3834             PROFILE_VARS;
 3835             RNA_INSPECTION_STATE prevRnaServiceState;
 3836             PREPROC_PROFILE_START(serviceMatchPerfStats);
 3837 
 3838             tpAppId = session->tpAppId;
 3839             prevRnaServiceState = session->rnaServiceState;
 3840 
 3841             //decision to directly call validator or go through elaborate service_state tracking
 3842             //is made once at the beginning of session.
 3843             if (session->rnaServiceState == RNA_STATE_NONE && p->payload_size)
 3844             {
 3845                 if (getAppIdFlag(session, APPID_SESSION_MID))
 3846                 {
 3847                     // Unless it could be ftp control
 3848                     if (protocol == IPPROTO_TCP && (p->src_port == 21 || p->dst_port == 21) &&
 3849                             !(p->tcp_header->flags & (TCPHEADER_FIN | TCPHEADER_RST)))
 3850                     {
 3851                         setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
 3852                         if (!AddFTPServiceState(session))
 3853                         {
 3854                             setAppIdFlag(session, APPID_SESSION_CONTINUE);
 3855                             if (p->dst_port != 21)
 3856                                 setAppIdFlag(session, APPID_SESSION_RESPONDER_SEEN);
 3857                         }
 3858                         session->rnaServiceState = RNA_STATE_STATEFUL;
 3859                     }
 3860                     else
 3861                     {
 3862                         setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED);
 3863                         session->rnaServiceState = RNA_STATE_FINISHED;
 3864                         if ((TPIsAppIdAvailable(session->tpsession) || getAppIdFlag(session, APPID_SESSION_NO_TPI)) &&
 3865                             session->payloadAppId == APP_ID_NONE)
 3866                             session->payloadAppId = APP_ID_UNKNOWN;
 3867                     }
 3868                 }
 3869                 else if (TPIsAppIdAvailable(session->tpsession))
 3870                 {
 3871                     if (tpAppId > APP_ID_NONE)
 3872                     {
 3873                         //tp has positively identified appId, Dig deeper only if sourcefire detector
 3874                         //identifies additional information or flow is UDP reveresed.
 3875 #ifdef TARGET_BASED
 3876                         if ((entry = appInfoEntryGet(tpAppId, pConfig))
 3877                                 && entry->svrValidator &&
 3878                                 ((entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL) ||
 3879                                  ((entry->flags & APPINFO_FLAG_SERVICE_UDP_REVERSED) && protocol == IPPROTO_UDP &&
 3880                                   getAppIdFlag(session, APPID_SESSION_INITIATOR_MONITORED | APPID_SESSION_RESPONDER_MONITORED))))
 3881                         {
 3882                             AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
 3883 
 3884 #ifdef DEBUG_FW_APPID
 3885                             if (session->serviceData && compareServiceElements(session->serviceData, entry->svrValidator))
 3886                             {
 3887                                 fprintf(stderr, "Mismatched validator Original %s, new tp %s",
 3888                                         session->serviceData->name, entry->svrValidator->name);
 3889                             }
 3890 #endif
 3891                             session->serviceData = entry->svrValidator;
 3892                             session->rnaServiceState = RNA_STATE_STATEFUL;
 3893 #ifdef DEBUG_FW_APPID
 3894 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3895                             if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3896 #endif
 3897                                 fprintf(SF_DEBUG_FILE, "%u -> %u %u RNA doing deeper inspection\n",
 3898                                         (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol);
 3899 #endif
 3900                         }
 3901                         else
 3902                         {
 3903                             stopRnaServiceInspection(p, session, direction);
 3904                         }
 3905 #endif
 3906                     }
 3907                     else
 3908                         session->rnaServiceState = RNA_STATE_STATEFUL;
 3909                 }
 3910                 else
 3911                     session->rnaServiceState = RNA_STATE_STATEFUL;
 3912             }
 3913 
 3914             //stop rna inspection as soon as tp has classified a valid AppId later in the session
 3915             if (session->rnaServiceState == RNA_STATE_STATEFUL &&
 3916                 prevRnaServiceState == RNA_STATE_STATEFUL &&
 3917                 !getAppIdFlag(session, APPID_SESSION_NO_TPI) &&
 3918                 TPIsAppIdAvailable(session->tpsession) &&
 3919                 tpAppId > APP_ID_NONE  && tpAppId < SF_APPID_MAX)
 3920             {
 3921 #ifdef TARGET_BASED
 3922                 entry = appInfoEntryGet(tpAppId, pConfig);
 3923 
 3924                 if (entry && entry->svrValidator && !(entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL))
 3925                 {
 3926                     if (app_id_debug_session_flag)
 3927                         _dpd.logMsg("AppIdDbg %s Stopping service detection\n", app_id_debug_session);
 3928                     stopRnaServiceInspection(p, session, direction);
 3929                 }
 3930 #endif
 3931             }
 3932 
 3933             // Check to see if we want to stop any detectors for SIP/RTP.
 3934             if (session->rnaServiceState != RNA_STATE_FINISHED)
 3935             {
 3936                 if (tpAppId == APP_ID_SIP)
 3937                 {
 3938                     // TP needs to see its own future flows and does a better
 3939                     // job of it than we do, so stay out of its way, and don't
 3940                     // waste time (but we will still get the Snort callbacks
 3941                     // for any of our own future flows).
 3942                     //  - Shut down our detectors.
 3943                     session->serviceAppId = APP_ID_SIP;
 3944                     stopRnaServiceInspection(p, session, direction);
 3945                     session->rnaClientState = RNA_STATE_FINISHED;
 3946                 }
 3947                 else if ((tpAppId == APP_ID_RTP) || (tpAppId == APP_ID_RTP_AUDIO) || (tpAppId == APP_ID_RTP_VIDEO))
 3948                 {
 3949                     // No need for anybody to keep wasting time once we've
 3950                     // found RTP.
 3951                     //  - Shut down our detectors.
 3952                     session->serviceAppId = tpAppId;
 3953                     stopRnaServiceInspection(p, session, direction);
 3954                     session->rnaClientState = RNA_STATE_FINISHED;
 3955                     //  - Shut down TP.
 3956                     thirdparty_appid_module->session_state_set(session->tpsession, TP_STATE_TERMINATED);
 3957                     //  - Just ignore everything from now on.
 3958                     setAppIdFlag(session, APPID_SESSION_IGNORE_FLOW);
 3959                 }
 3960             }
 3961 
 3962             if (session->rnaServiceState == RNA_STATE_STATEFUL)
 3963             {
 3964 #ifdef DEBUG_FW_APPID
 3965 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 3966                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 3967 #endif
 3968                     fprintf(SF_DEBUG_FILE, "%u -> %u %u RNA identifying service\n",
 3969                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol);
 3970 #endif
 3971                 AppIdDiscoverService(p, direction, session, pConfig);
 3972                 isTpAppidDiscoveryDone = true;
 3973                 //to stop executing validator after service has been detected by RNA.
 3974                 if (getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
 3975         {
 3976                     session->rnaServiceState = RNA_STATE_FINISHED;
 3977                     if ((TPIsAppIdAvailable(session->tpsession) || getAppIdFlag(session, APPID_SESSION_NO_TPI)) &&
 3978                         session->payloadAppId == APP_ID_NONE)
 3979                         session->payloadAppId = APP_ID_UNKNOWN;
 3980         }
 3981                 if (session->rnaServiceState == RNA_STATE_STATEFUL && session->serviceAppId == APP_ID_NONE && svcTakingTooMuchTime(session))
 3982                 {
 3983                     stopRnaServiceInspection(p, session, direction);
 3984                     session->serviceAppId = APP_ID_UNKNOWN;
 3985                 }
 3986                 else if(session->serviceAppId == APP_ID_DNS && appidStaticConfig->dns_host_reporting && session->dsession && session->dsession->host  )
 3987                 {
 3988                     size = session->dsession->host_len;
 3989                     dns_host_scan_hostname((const u_int8_t *)session->dsession->host , size, &clientAppId, &payloadAppId, &pConfig->serviceDnsConfig);
 3990                     setClientAppIdData(p, direction, session, clientAppId, NULL);
 3991                 }
 3992                 else if (session->serviceAppId == APP_ID_RTMP)
 3993                     ExamineRtmpMetadata(p, direction, session);
 3994                 else if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) && session->tsession)
 3995                     ExamineSslMetadata(p, direction, session, pConfig);
 3996 
 3997 #ifdef TARGET_BASED
 3998                 if (tpAppId <= APP_ID_NONE &&
 3999                     getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_IGNORE_HOST) == APPID_SESSION_SERVICE_DETECTED)
 4000                 {
 4001                     synchAppIdWithSnortId(session->serviceAppId, p, session, pConfig);
 4002                 }
 4003 #endif
 4004             }
 4005             PREPROC_PROFILE_END(serviceMatchPerfStats);
 4006         }
 4007         /*** End of service discovery. ***/
 4008 
 4009         /*** Start of client discovery. ***/
 4010         if (session->rnaClientState != RNA_STATE_FINISHED)
 4011         {
 4012             PROFILE_VARS;
 4013             PREPROC_PROFILE_START(clientMatchPerfStats);
 4014             RNA_INSPECTION_STATE prevRnaClientState = session->rnaClientState;
 4015             bool was_http2 = session->is_http2;
 4016 #ifdef TARGET_BASED
 4017             bool was_service = getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED) ? true : false;
 4018 #endif
 4019 
 4020             //decision to directly call validator or go through elaborate service_state tracking
 4021             //is made once at the beginning of session.
 4022             if (session->rnaClientState == RNA_STATE_NONE && p->payload_size && direction == APP_ID_FROM_INITIATOR)
 4023             {
 4024                 if (getAppIdFlag(session, APPID_SESSION_MID))
 4025                     session->rnaClientState = RNA_STATE_FINISHED;
 4026                 else if (TPIsAppIdAvailable(session->tpsession) && (tpAppId = session->tpAppId) > APP_ID_NONE && tpAppId < SF_APPID_MAX)
 4027                 {
 4028 #ifdef TARGET_BASED
 4029                     if ((entry = appInfoEntryGet(tpAppId, pConfig)) && entry->clntValidator &&
 4030                             ((entry->flags & APPINFO_FLAG_CLIENT_ADDITIONAL) ||
 4031                              ((entry->flags & APPINFO_FLAG_CLIENT_USER) &&
 4032                               getAppIdFlag(session, APPID_SESSION_DISCOVER_USER))))
 4033                     {
 4034                         //tp has positively identified appId, Dig deeper only if sourcefire detector
 4035                         //identifies additional information
 4036                         session->clientData = entry->clntValidator;
 4037                         session->rnaClientState = RNA_STATE_DIRECT;
 4038                     }
 4039                     else
 4040                     {
 4041                         setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
 4042                         session->rnaClientState = RNA_STATE_FINISHED;
 4043                     }
 4044 #endif
 4045                 }
 4046                 else if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION))
 4047                     session->rnaClientState = RNA_STATE_FINISHED;
 4048                 else
 4049                     session->rnaClientState = RNA_STATE_STATEFUL;
 4050             }
 4051 
 4052             //stop rna inspection as soon as tp has classified a valid AppId later in the session
 4053             if ((session->rnaClientState == RNA_STATE_STATEFUL ||
 4054                  session->rnaClientState == RNA_STATE_DIRECT) &&
 4055                 session->rnaClientState == prevRnaClientState &&
 4056                 !getAppIdFlag(session, APPID_SESSION_NO_TPI) &&
 4057                 TPIsAppIdAvailable(session->tpsession) &&
 4058                 tpAppId > APP_ID_NONE  && tpAppId < SF_APPID_MAX)
 4059             {
 4060 #ifdef TARGET_BASED
 4061                 entry = appInfoEntryGet(tpAppId, pConfig);
 4062 
 4063                 if (!(entry && entry->clntValidator && entry->clntValidator == session->clientData && (entry->flags & (APPINFO_FLAG_CLIENT_ADDITIONAL|APPINFO_FLAG_CLIENT_USER))))
 4064                 {
 4065                     session->rnaClientState = RNA_STATE_FINISHED;
 4066                     setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
 4067                 }
 4068 #endif
 4069             }
 4070 
 4071             if (session->rnaClientState == RNA_STATE_DIRECT)
 4072             {
 4073                 int ret = CLIENT_APP_INPROCESS;
 4074 
 4075 #ifdef DEBUG_FW_APPID
 4076 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4077                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 4078 #endif
 4079                     fprintf(SF_DEBUG_FILE, "%u -> %u %u RNA identifying additional client info\n",
 4080                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol);
 4081 #endif
 4082                 if (direction == APP_ID_FROM_INITIATOR)
 4083                 {
 4084                     /* get out if we've already tried to validate a client app */
 4085                     if (!getAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED))
 4086                     {
 4087                         ret = RunClientDetectors(session, p, direction, pConfig);
 4088                     }
 4089                 }
 4090                 else if (session->rnaServiceState != RNA_STATE_STATEFUL &&
 4091                          getAppIdFlag(session, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
 4092                 {
 4093                     ret = RunClientDetectors(session, p, direction, pConfig);
 4094                 }
 4095 
 4096 #ifdef DEBUG_FW_APPID
 4097 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4098                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 4099 #endif
 4100                     fprintf(SF_DEBUG_FILE, "%u -> %u %u direct client validate returned %d\n",
 4101                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol, ret);
 4102 #endif
 4103                 switch (ret)
 4104                 {
 4105                     case CLIENT_APP_INPROCESS:
 4106                         break;
 4107                     default:
 4108                         session->rnaClientState = RNA_STATE_FINISHED;
 4109                         break;
 4110                 }
 4111             }
 4112             else if (session->rnaClientState == RNA_STATE_STATEFUL)
 4113             {
 4114 #ifdef DEBUG_FW_APPID
 4115 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4116                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 4117 #endif
 4118                     fprintf(SF_DEBUG_FILE, "%u -> %u %u RNA identifying client\n",
 4119                             (unsigned)p->src_port, (unsigned)p->dst_port, (unsigned)protocol);
 4120 #endif
 4121                 AppIdDiscoverClientApp(p, direction, session, pConfig);
 4122                 isTpAppidDiscoveryDone = true;
 4123                 if (session->candidate_client_list != NULL)
 4124                 {
 4125                     if (sflist_count(session->candidate_client_list) > 0)
 4126                     {
 4127                         int ret = 0;
 4128                         if (direction == APP_ID_FROM_INITIATOR)
 4129                         {
 4130                             /* get out if we've already tried to validate a client app */
 4131                             if (!getAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED))
 4132                             {
 4133                                 ret = RunClientDetectors(session, p, direction, pConfig);
 4134                             }
 4135                         }
 4136                         else if (session->rnaServiceState != RNA_STATE_STATEFUL &&
 4137                                  getAppIdFlag(session, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
 4138                         {
 4139                             ret = RunClientDetectors(session, p, direction, pConfig);
 4140                         }
 4141                         if (ret < 0)
 4142                         {
 4143                             setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
 4144                             session->rnaClientState = RNA_STATE_FINISHED;
 4145                         }
 4146                     }
 4147                     else
 4148                     {
 4149                         setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
 4150                         session->rnaClientState = RNA_STATE_FINISHED;
 4151                     }
 4152                 }
 4153             }
 4154             if (app_id_debug_session_flag)
 4155                 if (!was_http2 && session->is_http2)
 4156                     _dpd.logMsg("AppIdDbg %s Got a preface for HTTP/2\n", app_id_debug_session);
 4157 #ifdef TARGET_BASED
 4158             if (!was_service && getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED))
 4159                 synchAppIdWithSnortId(session->serviceAppId, p, session, pConfig);
 4160 #endif
 4161             PREPROC_PROFILE_END(clientMatchPerfStats);
 4162         }
 4163         /*** End of client discovery. ***/
 4164 
 4165         setAppIdFlag(session, APPID_SESSION_ADDITIONAL_PACKET);
 4166     }
 4167     else
 4168     {
 4169 #ifdef DEBUG_FW_APPID
 4170 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4171                 if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 4172 #endif
 4173         fprintf(SF_DEBUG_FILE, "Packet not okay\n");
 4174 #endif
 4175     }
 4176 
 4177     serviceAppId = fwPickServiceAppId(session);
 4178     payloadAppId = fwPickPayloadAppId(session);
 4179 
 4180     if (serviceAppId > APP_ID_NONE)
 4181     {
 4182         if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
 4183         {
 4184             if (session->miscAppId == APP_ID_NONE)
 4185                 updateEncryptedAppId(session, serviceAppId);
 4186         }
 4187         else if (isTpAppidDiscoveryDone && isSslServiceAppId(serviceAppId) && _dpd.isSSLPolicyEnabled(NULL))
 4188             setAppIdFlag(session, APPID_SESSION_CONTINUE);
 4189     }
 4190 
 4191     clientAppId = fwPickClientAppId(session);
 4192     miscAppId = fwPickMiscAppId(session);
 4193 
 4194     if (!getAppIdFlag(session, APPID_SESSION_HOST_CACHE_MATCHED))
 4195     {
 4196         bool isHttpTunnel = (payloadAppId == APP_ID_HTTP_TUNNEL || payloadAppId == APP_ID_HTTP_SSL_TUNNEL) ? true : false;
 4197         if(isCheckHostCacheValid(session, serviceAppId, clientAppId, payloadAppId, miscAppId) || isHttpTunnel)
 4198         {
 4199             bool isCheckHostCache =  true;
 4200             sfaddr_t *srv_ip;
 4201             uint16_t srv_port;
 4202 
 4203             if (isHttpTunnel)
 4204             {
 4205                 if (session->hsession)
 4206                 {
 4207                     if (session->scan_flags & SCAN_HTTP_URI_FLAG)
 4208                     {
 4209                         if (session->hsession->tunDest)
 4210                         {
 4211                             free(session->hsession->tunDest);
 4212                             session->hsession->tunDest = NULL;
 4213                         }
 4214                         getIpPortFromHttpTunnel(session->hsession->uri, session->hsession->uri_buflen, &session->hsession->tunDest);
 4215                         session->scan_flags &= ~SCAN_HTTP_URI_FLAG;
 4216                     }
 4217 
 4218                     if (session->hsession->tunDest)
 4219                     {
 4220                         srv_ip = &(session->hsession->tunDest->ip);
 4221                         srv_port = session->hsession->tunDest->port;
 4222                     }
 4223                     else
 4224                     {
 4225                         isCheckHostCache =  false;
 4226                     }
 4227                 }
 4228                 else
 4229                 {
 4230                     isCheckHostCache =  false;
 4231                 }
 4232             }
 4233             else
 4234             {
 4235                 if (direction == APP_ID_FROM_INITIATOR)
 4236                 {
 4237                     srv_ip = GET_DST_IP(p);
 4238                     srv_port = p->dst_port;
 4239                 }
 4240                 else
 4241                 {
 4242                     srv_ip = GET_SRC_IP(p);
 4243                     srv_port = p->src_port;
 4244                 }
 4245             }
 4246 
 4247             if (isCheckHostCache && checkHostCache(p, session, srv_ip, srv_port, protocol, pConfig))
 4248             {
 4249                 session->portServiceAppId = APP_ID_NONE; // overriding the portServiceAppId in case of a cache hit
 4250                 serviceAppId = pickServiceAppId(session);
 4251                 payloadAppId = pickPayloadId(session);
 4252                 clientAppId = pickClientAppId(session);
 4253             }
 4254         }
 4255     }
 4256 
 4257     /* For OOO flow, disable third party if checkHostCache is done and appid is found.
 4258        Not sure if it is safe to set APPID_SESSION_IGNORE_FLOW here. */
 4259     if ((getAppIdFlag(session, APPID_SESSION_OOO_CHECK_TP | APPID_SESSION_HOST_CACHE_MATCHED) ==
 4260             (APPID_SESSION_OOO_CHECK_TP | APPID_SESSION_HOST_CACHE_MATCHED)) &&
 4261         (serviceAppId || payloadAppId || clientAppId) && thirdparty_appid_module)
 4262     {
 4263         clearAppIdFlag(session, APPID_SESSION_OOO_CHECK_TP); // don't repeat this block
 4264         if (!TPIsAppIdDone(session->tpsession))
 4265         {
 4266             thirdparty_appid_module->session_state_set(session->tpsession, TP_STATE_TERMINATED);
 4267             if (app_id_debug_session_flag)
 4268                 _dpd.logMsg("AppIdDbg %s stopped third party detection\n", app_id_debug_session);
 4269         }
 4270     }
 4271 
 4272     _dpd.streamAPI->set_application_id(p->stream_session, serviceAppId, clientAppId, payloadAppId, miscAppId);
 4273 
 4274     /* Set the field that the Firewall queries to see if we have a search engine. */
 4275     if (session->search_support_type == SEARCH_SUPPORT_TYPE_UNKNOWN && payloadAppId > APP_ID_NONE)
 4276     {
 4277         uint flags = appInfoEntryFlagGet(payloadAppId, APPINFO_FLAG_SEARCH_ENGINE | APPINFO_FLAG_SUPPORTED_SEARCH, pConfig);
 4278         session->search_support_type =
 4279             (flags & APPINFO_FLAG_SEARCH_ENGINE) ?
 4280                 ((flags & APPINFO_FLAG_SUPPORTED_SEARCH) ? SUPPORTED_SEARCH_ENGINE : UNSUPPORTED_SEARCH_ENGINE )
 4281                 : NOT_A_SEARCH_ENGINE;
 4282         if (app_id_debug_session_flag)
 4283         {
 4284             char *typeString;
 4285             switch (session->search_support_type)
 4286             {
 4287                 case NOT_A_SEARCH_ENGINE: typeString = "NOT_A_SEARCH_ENGINE"; break;
 4288                 case SUPPORTED_SEARCH_ENGINE: typeString = "SUPPORTED_SEARCH_ENGINE"; break;
 4289                 case UNSUPPORTED_SEARCH_ENGINE: typeString = "UNSUPPORTED_SEARCH_ENGINE"; break;
 4290                 default: break;
 4291             }
 4292             _dpd.logMsg("AppIdDbg %s appId: %u (safe)search_support_type=%s\n", app_id_debug_session, payloadAppId, typeString);
 4293         }
 4294     }
 4295 
 4296     if (serviceAppId > APP_ID_NONE)
 4297     {
 4298         if (session->pastIndicator != payloadAppId && payloadAppId > APP_ID_NONE)
 4299         {
 4300             session->pastIndicator = payloadAppId;
 4301             checkSessionForAFIndicator(p, direction, pConfig, payloadAppId);
 4302         }
 4303 
 4304         if (session->pastForecast != serviceAppId && session->payloadAppId == APP_ID_NONE && session->pastForecast != APP_ID_UNKNOWN)
 4305         {
 4306             session->pastForecast = checkSessionForAFForecast(session, p, direction, pConfig, serviceAppId);
 4307         }
 4308     }
 4309 
 4310     if (*_dpd.pkt_tracer_enabled)
 4311     {
 4312         const char *serviceName = appGetAppName(serviceAppId);
 4313         const char *appName = appGetAppName(payloadAppId);
 4314         _dpd.addPktTrace(VERDICT_REASON_APPID, snprintf(_dpd.trace, _dpd.traceMax, "AppID: service %s (%d), application %s (%d)%s\n",
 4315             serviceName? serviceName : "unknown", serviceAppId, appName? appName : "unknown", payloadAppId,
 4316             getAppIdFlag(session, APPID_SESSION_OOO)? ", out-of-order":""));
 4317     }
 4318 
 4319 #ifdef DEBUG_FW_APPID
 4320 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4321     if (p->dst_port == DEBUG_FW_APPID_PORT || p->src_port == DEBUG_FW_APPID_PORT)
 4322     {
 4323 #endif
 4324         fprintf(SF_DEBUG_FILE, "%u %u -> %u %u End %d %u - (%d %d %d %d %d) %u %" PRIx64 " %u %u %u\n", (unsigned)session->session_packet_count, (unsigned)p->src_port, (unsigned)p->dst_port,
 4325                 (unsigned)protocol, direction, (unsigned)p->payload_size,
 4326                 session->serviceAppId, session->clientAppId, session->payloadAppId,
 4327                 session->tpAppId, session->miscAppId, session->rnaServiceState, session->common.flags, thirdparty_appid_module->session_state_get(session->tpsession),
 4328                 (unsigned)session->init_tpPackets, (unsigned)session->resp_tpPackets);
 4329         //DumpHex(SF_DEBUG_FILE, p->payload, p->payload_size);
 4330 #if defined(DEBUG_FW_APPID_PORT) && DEBUG_FW_APPID_PORT
 4331     }
 4332 #endif
 4333 #endif
 4334 }
 4335 
 4336 STATIC INLINE void pickHttpXffAddress(SFSnortPacket* p, tAppIdData* appIdSession, ThirdPartyAppIDAttributeData* attribute_data)
 4337 {
 4338     int i;
 4339     static char* defaultXffPrecedence[] = {HTTP_XFF_FIELD_X_FORWARDED_FOR, HTTP_XFF_FIELD_TRUE_CLIENT_IP};
 4340 
 4341     // XFF precedence configuration cannot change for a session. Do not get it again if we already got it.
 4342     if (!appIdSession->hsession->xffPrecedence)
 4343     {
 4344         char** xffPrecedence = _dpd.sessionAPI->get_http_xff_precedence(p->stream_session, p->flags, &appIdSession->hsession->numXffFields);
 4345         int j;
 4346 
 4347         if (!xffPrecedence)
 4348         {
 4349             xffPrecedence = defaultXffPrecedence;
 4350             appIdSession->hsession->numXffFields = sizeof(defaultXffPrecedence) / sizeof(defaultXffPrecedence[0]);
 4351         }
 4352 
 4353         appIdSession->hsession->xffPrecedence = malloc(appIdSession->hsession->numXffFields * sizeof(char*));
 4354         if(!appIdSession->hsession->xffPrecedence)
 4355         {
 4356             DynamicPreprocessorFatalMessage("pickHttpXffAddress: "
 4357                     "failed to allocate memory for xffPrecedence in appIdSession\n");
 4358         }
 4359 
 4360         for (j = 0; j < appIdSession->hsession->numXffFields; j++)
 4361             appIdSession->hsession->xffPrecedence[j] = strndup(xffPrecedence[j], UINT8_MAX);
 4362     }
 4363 
 4364     if (app_id_debug_session_flag)
 4365     {
 4366         for (i = 0; i < attribute_data->numXffFields; i++)
 4367             _dpd.logMsg("AppIdDbg %s %s : %s\n", app_id_debug_session, attribute_data->xffFieldValue[i].field,
 4368                         attribute_data->xffFieldValue[i].value ? attribute_data->xffFieldValue[i].value : "(empty)");
 4369     }
 4370 
 4371     // xffPrecedence array is sorted based on precedence
 4372     for (i = 0; (i < appIdSession->hsession->numXffFields) && appIdSession->hsession->xffPrecedence[i]; i++)
 4373     {
 4374         int j;
 4375         for (j = 0; j < attribute_data->numXffFields; j++)
 4376         {
 4377             if (appIdSession->hsession->xffAddr)
 4378             {
 4379                 sfaddr_free(appIdSession->hsession->xffAddr);
 4380                 appIdSession->hsession->xffAddr = NULL;
 4381             }
 4382 
 4383             if (strncasecmp(attribute_data->xffFieldValue[j].field, appIdSession->hsession->xffPrecedence[i], UINT8_MAX) == 0)
 4384             {
 4385                 if (!attribute_data->xffFieldValue[j].value || (attribute_data->xffFieldValue[j].value[0] == '\0')) return;
 4386 
 4387                 char* tmp = strrchr(attribute_data->xffFieldValue[j].value, ',');
 4388                 SFIP_RET status;
 4389 
 4390                 if (!tmp)
 4391                 {
 4392                     appIdSession->hsession->xffAddr = sfaddr_alloc(attribute_data->xffFieldValue[j].value, &status);
 4393                 }
 4394                 // For a comma-separated list of addresses, pick the last address
 4395                 else
 4396                 {
 4397                     appIdSession->hsession->xffAddr = sfaddr_alloc(tmp + 1, &status);
 4398                 }
 4399                 break;
 4400             }
 4401         }
 4402         if (appIdSession->hsession->xffAddr) break;
 4403     }
 4404 }
 4405 
 4406 static inline void ProcessThirdPartyResults(SFSnortPacket* p, APPID_SESSION_DIRECTION direction, tAppIdData* appIdSession, int confidence, tAppId* proto_list, ThirdPartyAppIDAttributeData* attribute_data)
 4407 {
 4408     int size;
 4409     tAppId serviceAppId = 0;
 4410     tAppId clientAppId = 0;
 4411     tAppId payloadAppId = 0;
 4412     tAppId referredPayloadAppId = 0;
 4413     tAppIdConfig *pConfig = appIdActiveConfigGet();
 4414 #ifdef TARGET_BASED
 4415     AppInfoTableEntry *entry = NULL;
 4416 #endif
 4417 
 4418     if (!appIdSession->payloadAppId && ThirdPartyAppIDFoundProto(APP_ID_EXCHANGE, proto_list))
 4419         appIdSession->payloadAppId = APP_ID_EXCHANGE;
 4420 
 4421     if (ThirdPartyAppIDFoundProto(APP_ID_HTTP, proto_list))
 4422     {
 4423         setAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION);
 4424     }
 4425     if (ThirdPartyAppIDFoundProto(APP_ID_SPDY, proto_list))
 4426     {
 4427         setAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
 4428     }
 4429     if (ThirdPartyAppIDFoundProto(APP_ID_SSL, proto_list))
 4430     {
 4431         if (getAppIdFlag(appIdSession, APPID_SESSION_HTTP_TUNNEL))
 4432         {
 4433             if (!appIdSession->serviceData)
 4434             {
 4435 #ifdef TARGET_BASED
 4436                 entry = appInfoEntryGet(APP_ID_SSL, pConfig);
 4437                 appIdSession->serviceData = entry->svrValidator;
 4438 #endif
 4439             }
 4440             if (getAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION))
 4441                 clearAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
 4442         }
 4443         setAppIdFlag(appIdSession, APPID_SESSION_SSL_SESSION);
 4444     }
 4445 
 4446     if (getAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION))
 4447     {
 4448         if (!appIdSession->hsession)
 4449         {
 4450             if (!(appIdSession->hsession = calloc(1, sizeof(*appIdSession->hsession))))
 4451                 DynamicPreprocessorFatalMessage("Could not allocate httpSession data");
 4452             memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
 4453         }
 4454 
 4455         if (getAppIdFlag(appIdSession, APPID_SESSION_SPDY_SESSION))
 4456         {
 4457             if (app_id_debug_session_flag)
 4458                 _dpd.logMsg("AppIdDbg %s flow is SPDY\n", app_id_debug_session);
 4459 
 4460             if (attribute_data->spdyRequestScheme &&
 4461                 attribute_data->spdyRequestHost &&
 4462                 attribute_data->spdyRequestPath)
 4463             {
 4464                 static const char httpsScheme[] = "https";
 4465                 static const char httpScheme[] = "http";
 4466                 const char *scheme;
 4467 
 4468                 if (appIdSession->hsession->url)
 4469                 {
 4470                     free(appIdSession->hsession->url);
 4471                     appIdSession->hsession->chp_finished = 0;
 4472                 }
 4473                 if (getAppIdFlag(appIdSession, APPID_SESSION_DECRYPTED)
 4474                         && memcmp(attribute_data->spdyRequestScheme, httpScheme, sizeof(httpScheme)-1) == 0)
 4475                 {
 4476                     scheme = httpsScheme;
 4477                 }
 4478                 else
 4479                 {
 4480                     scheme = attribute_data->spdyRequestScheme;
 4481                 }
 4482 
 4483                 size = strlen(scheme) +
 4484                        strlen(attribute_data->spdyRequestHost) +
 4485                        strlen(attribute_data->spdyRequestPath) +
 4486                        sizeof("://"); // see sprintf() format
 4487                 if (NULL != (appIdSession->hsession->url = malloc(size)))
 4488                 {
 4489                     sprintf(appIdSession->hsession->url, "%s://%s%s",
 4490                          scheme, attribute_data->spdyRequestHost,
 4491                          attribute_data->spdyRequestPath);
 4492                     appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
 4493                 }
 4494                 free(attribute_data->spdyRequestScheme);
 4495                 attribute_data->spdyRequestScheme = NULL;
 4496             }
 4497             else if (attribute_data->spdyRequestScheme)
 4498             {
 4499                 free(attribute_data->spdyRequestScheme);
 4500                 attribute_data->spdyRequestScheme = NULL;
 4501             }
 4502             if (attribute_data->spdyRequestHost)
 4503             {
 4504                 if (appIdSession->hsession->host)
 4505                 {
 4506                     free(appIdSession->hsession->host);
 4507                     appIdSession->hsession->chp_finished = 0;
 4508                 }
 4509                 appIdSession->hsession->host = attribute_data->spdyRequestHost;
 4510                 attribute_data->spdyRequestHost = NULL;
 4511                 appIdSession->hsession->fieldOffset[REQ_HOST_FID] = attribute_data->spdyRequestHostOffset;
 4512                 appIdSession->hsession->fieldEndOffset[REQ_HOST_FID] = attribute_data->spdyRequestHostEndOffset;
 4513                 if (app_id_debug_session_flag)
 4514                     _dpd.logMsg("AppIdDbg %s SPDY Host (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_HOST_FID], appIdSession->hsession->fieldEndOffset[REQ_HOST_FID], appIdSession->hsession->host);
 4515                 appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
 4516             }
 4517             if (attribute_data->spdyRequestPath)
 4518             {
 4519                 if (appIdSession->hsession->uri)
 4520                 {
 4521                     free(appIdSession->hsession->uri);
 4522                     appIdSession->hsession->chp_finished = 0;
 4523                 }
 4524                 appIdSession->hsession->uri = attribute_data->spdyRequestPath;
 4525                 attribute_data->spdyRequestPath = NULL;
 4526                 appIdSession->hsession->fieldOffset[REQ_URI_FID] = attribute_data->spdyRequestPathOffset;
 4527                 appIdSession->hsession->fieldEndOffset[REQ_URI_FID] = attribute_data->spdyRequestPathEndOffset;
 4528                 if (app_id_debug_session_flag)
 4529                     _dpd.logMsg("AppIdDbg %s SPDY URI (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_URI_FID], appIdSession->hsession->fieldEndOffset[REQ_URI_FID], appIdSession->hsession->uri);
 4530             }
 4531         }
 4532         else
 4533         {
 4534             if (app_id_debug_session_flag)
 4535                 _dpd.logMsg("AppIdDbg %s flow is HTTP\n", app_id_debug_session);
 4536 
 4537             if (attribute_data->httpRequestHost)
 4538             {
 4539                 if (appIdSession->hsession->host)
 4540                 {
 4541                     free(appIdSession->hsession->host);
 4542                     if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4543                         appIdSession->hsession->chp_finished = 0;
 4544                 }
 4545                 appIdSession->hsession->host = attribute_data->httpRequestHost;
 4546                 appIdSession->hsession->host_buflen = attribute_data->httpRequestHostLen;
 4547                 appIdSession->hsession->fieldOffset[REQ_HOST_FID] = attribute_data->httpRequestHostOffset;
 4548                 appIdSession->hsession->fieldEndOffset[REQ_HOST_FID] = attribute_data->httpRequestHostEndOffset;
 4549                 attribute_data->httpRequestHost = NULL;
 4550                 if (app_id_debug_session_flag)
 4551                     _dpd.logMsg("AppIdDbg %s HTTP Host (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_HOST_FID], appIdSession->hsession->fieldEndOffset[REQ_HOST_FID], appIdSession->hsession->host);
 4552                 appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
 4553             }
 4554             if (attribute_data->httpRequestUrl)
 4555             {
 4556                 static const char httpScheme[] = "http://";
 4557 
 4558                 if (appIdSession->hsession->url)
 4559                 {
 4560                     free(appIdSession->hsession->url);
 4561                     if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4562                         appIdSession->hsession->chp_finished = 0;
 4563                 }
 4564 
 4565                 //change http to https if session was decrypted.
 4566                 if (getAppIdFlag(appIdSession, APPID_SESSION_DECRYPTED)
 4567                         && memcmp(attribute_data->httpRequestUrl, httpScheme, sizeof(httpScheme)-1) == 0)
 4568                 {
 4569                     appIdSession->hsession->url = malloc(strlen(attribute_data->httpRequestUrl) + 2);
 4570                     if(!appIdSession->hsession->url)
 4571                     {
 4572                          DynamicPreprocessorFatalMessage("ProcessThirdPartyResults: "
 4573                                  "Failed to allocate URL memory in AppID session\n");
 4574                     }
 4575 
 4576                     if (appIdSession->hsession->url)
 4577                         sprintf(appIdSession->hsession->url, "https://%s", attribute_data->httpRequestUrl + sizeof(httpScheme)-1);
 4578 
 4579                     free(attribute_data->httpRequestUrl);
 4580                     attribute_data->httpRequestUrl = NULL;
 4581                 }
 4582                 else
 4583                 {
 4584                     appIdSession->hsession->url = attribute_data->httpRequestUrl;
 4585                     attribute_data->httpRequestUrl = NULL;
 4586                 }
 4587 
 4588                 appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
 4589             }
 4590             if (attribute_data->httpRequestUri)
 4591             {
 4592                 if (appIdSession->hsession->uri)
 4593                 {
 4594                     free(appIdSession->hsession->uri);
 4595                     if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4596                         appIdSession->hsession->chp_finished = 0;
 4597                 }
 4598                 appIdSession->hsession->uri = attribute_data->httpRequestUri;
 4599                 appIdSession->hsession->uri_buflen = attribute_data->httpRequestUriLen;
 4600                 appIdSession->hsession->fieldOffset[REQ_URI_FID] = attribute_data->httpRequestUriOffset;
 4601                 appIdSession->hsession->fieldEndOffset[REQ_URI_FID] = attribute_data->httpRequestUriEndOffset;
 4602                 appIdSession->scan_flags |= SCAN_HTTP_URI_FLAG;
 4603                 attribute_data->httpRequestUri = NULL;
 4604                 if (app_id_debug_session_flag)
 4605                     _dpd.logMsg("AppIdDbg %s HTTP URI (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_URI_FID], appIdSession->hsession->fieldEndOffset[REQ_URI_FID], appIdSession->hsession->uri);
 4606             }
 4607         }
 4608         //========================================
 4609         // Begin common HTTP component field data
 4610         //========================================
 4611         if (attribute_data->httpRequestMethod)
 4612         {
 4613             if (app_id_debug_session_flag)
 4614                 _dpd.logMsg("AppIdDbg %s HTTP request method is %s\n", app_id_debug_session, attribute_data->httpRequestMethod);
 4615             if (!strcmp(attribute_data->httpRequestMethod, "CONNECT"))
 4616                 setAppIdFlag(appIdSession, APPID_SESSION_HTTP_CONNECT);
 4617         }
 4618         if (attribute_data->httpRequestVia)
 4619         {
 4620             if (appIdSession->hsession->via)
 4621             {
 4622                 free(appIdSession->hsession->via);
 4623                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4624                     appIdSession->hsession->chp_finished = 0;
 4625             }
 4626             appIdSession->hsession->via = attribute_data->httpRequestVia;
 4627             attribute_data->httpRequestVia = NULL;
 4628             appIdSession->scan_flags |= SCAN_HTTP_VIA_FLAG;
 4629         }
 4630         else if (attribute_data->httpResponseVia)
 4631         {
 4632             if (appIdSession->hsession->via)
 4633             {
 4634                 free(appIdSession->hsession->via);
 4635                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4636                     appIdSession->hsession->chp_finished = 0;
 4637             }
 4638             appIdSession->hsession->via = attribute_data->httpResponseVia;
 4639             attribute_data->httpResponseVia = NULL;
 4640             appIdSession->scan_flags |= SCAN_HTTP_VIA_FLAG;
 4641         }
 4642         if (attribute_data->httpRequestUserAgent)
 4643         {
 4644             if (appIdSession->hsession->useragent)
 4645             {
 4646                 free(appIdSession->hsession->useragent);
 4647                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4648                     appIdSession->hsession->chp_finished = 0;
 4649             }
 4650             appIdSession->hsession->useragent = attribute_data->httpRequestUserAgent;
 4651             appIdSession->hsession->useragent_buflen = attribute_data->httpRequestUserAgentLen;
 4652             attribute_data->httpRequestUserAgent = NULL;
 4653             appIdSession->hsession->fieldOffset[REQ_AGENT_FID] = attribute_data->httpRequestUserAgentOffset;
 4654             appIdSession->hsession->fieldEndOffset[REQ_AGENT_FID] = attribute_data->httpRequestUserAgentEndOffset;
 4655             if (app_id_debug_session_flag)
 4656                 _dpd.logMsg("AppIdDbg %s User-Agent (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_AGENT_FID], appIdSession->hsession->fieldEndOffset[REQ_AGENT_FID], appIdSession->hsession->useragent);
 4657             appIdSession->scan_flags |= SCAN_HTTP_USER_AGENT_FLAG;
 4658         }
 4659         // Check to see if third party discovered HTTP/2.
 4660         //  - once it supports it...
 4661         if (attribute_data->httpResponseVersion)
 4662         {
 4663             if (app_id_debug_session_flag)
 4664                 _dpd.logMsg("AppIdDbg %s HTTP response version is %s\n", app_id_debug_session, attribute_data->httpResponseVersion);
 4665             if (strncmp(attribute_data->httpResponseVersion, "HTTP/2", 6) == 0)
 4666             {
 4667                 if (app_id_debug_session_flag)
 4668                     _dpd.logMsg("AppIdDbg %s 3rd party detected and parsed HTTP/2\n", app_id_debug_session);
 4669                 appIdSession->is_http2 = true;
 4670             }
 4671             free(attribute_data->httpResponseVersion);
 4672             attribute_data->httpResponseVersion = NULL;
 4673         }
 4674         if (attribute_data->httpResponseCode)
 4675         {
 4676             if (app_id_debug_session_flag)
 4677                 _dpd.logMsg("AppIdDbg %s HTTP response code is %s\n", app_id_debug_session, attribute_data->httpResponseCode);
 4678             if (appIdSession->hsession->response_code)
 4679             {
 4680                 free(appIdSession->hsession->response_code);
 4681                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4682                     appIdSession->hsession->chp_finished = 0;
 4683             }
 4684             appIdSession->hsession->response_code = attribute_data->httpResponseCode;
 4685             appIdSession->hsession->response_code_buflen = attribute_data->httpResponseCodeLen;
 4686             attribute_data->httpResponseCode = NULL;
 4687         }
 4688         // Check to see if we've got an upgrade to HTTP/2 (if enabled).
 4689         //  - This covers the "without prior knowledge" case (i.e., the client
 4690         //    asks the server to upgrade to HTTP/2).
 4691         if (attribute_data->httpResponseUpgrade)
 4692         {
 4693             if (app_id_debug_session_flag)
 4694                 _dpd.logMsg("AppIdDbg %s HTTP response upgrade is %s\n", app_id_debug_session, attribute_data->httpResponseUpgrade);
 4695             if (appidStaticConfig->http2_detection_enabled)
 4696                 if (appIdSession->hsession->response_code && (strncmp(appIdSession->hsession->response_code, "101", 3) == 0))
 4697                     if (strncmp(attribute_data->httpResponseUpgrade, "h2c", 3) == 0)
 4698                     {
 4699                         if (app_id_debug_session_flag)
 4700                             _dpd.logMsg("AppIdDbg %s Got an upgrade to HTTP/2\n", app_id_debug_session);
 4701                         appIdSession->is_http2 = true;
 4702                     }
 4703             free(attribute_data->httpResponseUpgrade);
 4704             attribute_data->httpResponseUpgrade = NULL;
 4705         }
 4706         if (attribute_data->httpRequestReferer)
 4707         {
 4708             if (appIdSession->hsession->referer)
 4709             {
 4710                 free(appIdSession->hsession->referer);
 4711                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4712                     appIdSession->hsession->chp_finished = 0;
 4713             }
 4714             appIdSession->hsession->referer = attribute_data->httpRequestReferer;
 4715             appIdSession->hsession->referer_buflen = attribute_data->httpRequestRefererLen;
 4716             attribute_data->httpRequestReferer = NULL;
 4717             appIdSession->hsession->fieldOffset[REQ_REFERER_FID] = attribute_data->httpRequestRefererOffset;
 4718             appIdSession->hsession->fieldEndOffset[REQ_REFERER_FID] = attribute_data->httpRequestRefererEndOffset;
 4719             if (app_id_debug_session_flag)
 4720                 _dpd.logMsg("AppIdDbg %s Referer (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_REFERER_FID], appIdSession->hsession->fieldEndOffset[REQ_REFERER_FID], appIdSession->hsession->referer);
 4721         }
 4722         if (attribute_data->httpRequestCookie)
 4723         {
 4724             if (appIdSession->hsession->cookie)
 4725             {
 4726                 free(appIdSession->hsession->cookie);
 4727                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4728                     appIdSession->hsession->chp_finished = 0;
 4729             }
 4730             appIdSession->hsession->cookie = attribute_data->httpRequestCookie;
 4731             appIdSession->hsession->cookie_buflen = attribute_data->httpRequestCookieLen;
 4732             attribute_data->httpRequestCookie = NULL;
 4733             appIdSession->hsession->fieldOffset[REQ_COOKIE_FID] = attribute_data->httpRequestCookieOffset;
 4734             appIdSession->hsession->fieldEndOffset[REQ_COOKIE_FID] = attribute_data->httpRequestCookieEndOffset;
 4735             if (app_id_debug_session_flag)
 4736                 _dpd.logMsg("AppIdDbg %s Cookie (%u-%u) is %s\n", app_id_debug_session, appIdSession->hsession->fieldOffset[REQ_COOKIE_FID], appIdSession->hsession->fieldEndOffset[REQ_COOKIE_FID], appIdSession->hsession->cookie);
 4737         }
 4738         if (attribute_data->httpResponseContent)
 4739         {
 4740             if (appIdSession->hsession->content_type)
 4741             {
 4742                 free(appIdSession->hsession->content_type);
 4743                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4744                     appIdSession->hsession->chp_finished = 0;
 4745             }
 4746             appIdSession->hsession->content_type = attribute_data->httpResponseContent;
 4747             appIdSession->hsession->content_type_buflen = attribute_data->httpResponseContentLen;
 4748             attribute_data->httpResponseContent = NULL;
 4749             appIdSession->scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
 4750         }
 4751         if (ptype_scan_counts[LOCATION_PT] && attribute_data->httpResponseLocation)
 4752         {
 4753             if (appIdSession->hsession->location)
 4754             {
 4755                 free(appIdSession->hsession->location);
 4756                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4757                     appIdSession->hsession->chp_finished = 0;
 4758             }
 4759             appIdSession->hsession->location = attribute_data->httpResponseLocation;
 4760             appIdSession->hsession->location_buflen = attribute_data->httpResponseLocationLen;
 4761             attribute_data->httpResponseLocation = NULL;
 4762         }
 4763         if (attribute_data->httpRequestBody)
 4764         {
 4765             if (app_id_debug_session_flag)
 4766                 _dpd.logMsg("AppIdDbg %s got a request body %s\n", app_id_debug_session, attribute_data->httpRequestBody);
 4767             if (appIdSession->hsession->req_body)
 4768             {
 4769                 free(appIdSession->hsession->req_body);
 4770                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4771                     appIdSession->hsession->chp_finished = 0;
 4772             }
 4773             appIdSession->hsession->req_body = attribute_data->httpRequestBody;
 4774             appIdSession->hsession->req_body_buflen = attribute_data->httpRequestBodyLen;
 4775             attribute_data->httpRequestBody = NULL;
 4776         }
 4777         if (ptype_scan_counts[BODY_PT] && attribute_data->httpResponseBody)
 4778         {
 4779             if (appIdSession->hsession->body)
 4780             {
 4781                 free(appIdSession->hsession->body);
 4782                 if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
 4783                     appIdSession->hsession->chp_finished = 0;
 4784             }
 4785             appIdSession->hsession->body = attribute_data->httpResponseBody;
 4786             appIdSession->hsession->body_buflen = attribute_data->httpResponseBodyLen;
 4787             attribute_data->httpResponseBody = NULL;
 4788         }
 4789         if (attribute_data->numXffFields)
 4790         {
 4791             pickHttpXffAddress(p, appIdSession, attribute_data);
 4792         }
 4793         if (!appIdSession->hsession->chp_finished || appIdSession->hsession->chp_hold_flow)
 4794         {
 4795             setAppIdFlag(appIdSession, APPID_SESSION_CHP_INSPECTING);
 4796             if (thirdparty_appid_module)
 4797                 thirdparty_appid_module->session_attr_set(appIdSession->tpsession, TP_ATTR_CONTINUE_MONITORING);
 4798         }
 4799         if (attribute_data->httpResponseServer)
 4800         {
 4801             if (appIdSession->hsession->server)
 4802                 free(appIdSession->hsession->server);
 4803             appIdSession->hsession->server = attribute_data->httpResponseServer;
 4804             attribute_data->httpResponseServer = NULL;
 4805             appIdSession->scan_flags |= SCAN_HTTP_VENDOR_FLAG;
 4806         }
 4807         if (attribute_data->httpRequestXWorkingWith)
 4808         {
 4809             if