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