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