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
22 #ifndef _APPID_H_
23 #define _APPID_H_
24
25 #include <stdint.h>
26 #include <attribute.h>
27
28 #include <netinet/in.h>
29 #include "profiler.h"
30 #include "commonAppMatcher.h"
31 #include "client_app_api.h"
32 #include "service_api.h"
33 #include "flow.h"
34 #include "common_util.h"
35 #include "sip_common.h"
36 #include "appInfoTable.h"
37 #include "thirdparty_appid_utils.h"
38 #include "sfghash.h"
39
40 #define PP_APP_ID 1
41
42 #define MIN_SFTP_PACKET_COUNT 30
43 #define MAX_SFTP_PACKET_COUNT 55
44
45 /*#define APPID_FULL_CLEANUP 1 */
46
47 typedef enum
48 {
49 APPID_DEBUG_HOST_MONITOR0,
50 APPID_DEBUG_HOST_MONITOR1,
51 APPID_DEBUG_HOST_MONITOR2,
52 APPID_DEBUG_HOST_MONITOR3,
53 APPID_DEBUG_HOST_MONITOR4,
54 APPID_DEBUG_HOST_MONITOR5,
55 APPID_DEBUG_HOST_NOT_MONITORED,
56 } AppIdDebugHostMonitorType;
57
58 typedef struct
59 {
60 struct in6_addr initiatorIp;
61 int family;
62 tAppIdData* session;
63 uint16_t initiatorPort;
64 APPID_SESSION_DIRECTION direction;
65 uint8_t protocol;
66 int monitorType;
67 } AppIdDebugHostInfo_t;
68
69
70 extern uint8_t appIdPriorityArray[SF_APPID_MAX+1];
71 extern AppIdDebugHostInfo_t AppIdDebugHostInfo;
72
73 struct AppIdData * getAppIdData(void* lwssn);
74
75 void fwAppIdInit(void);
76 void fwAppIdFini(tAppIdConfig *pConfig);
77 void fwAppIdSearch(SFSnortPacket *p);
78 void httpHeaderCallback (SFSnortPacket *p, HttpParsedHeaders *const headers);
79 void SipSessionSnortCallback (void *ssnptr, ServiceEventType eventType, void *eventData);
80
81 void readRnaAppMappingTable(const char *path, tAppIdConfig *pConfig);
82 tAppId appGetAppFromServiceId(uint32_t serviceId, tAppIdConfig *pConfig);
83 tAppId appGetAppFromClientId(uint32_t clientId, tAppIdConfig *pConfig);
84 tAppId appGetAppFromPayloadId(uint32_t payloadId, tAppIdConfig *pConfig);
85 void appSharedDataDelete(tAppIdData * sharedData);
86 void AppIdAddUser(tAppIdData *flowp, const char *username, tAppId appId, int success);
87 void AppIdAddDnsQueryInfo(tAppIdData *flow,
88 uint16_t id,
89 const uint8_t *host, uint8_t host_len, uint16_t host_offset,
90 uint16_t record_type, uint16_t options_offset);
91 void AppIdAddDnsResponseInfo(tAppIdData *flow,
92 uint16_t id,
93 const uint8_t *host, uint8_t host_len, uint16_t host_offset,
94 uint8_t response_type, uint32_t ttl);
95 void AppIdResetDnsInfo(tAppIdData *flow);
96
97 void AppIdAddPayload(tAppIdData *flow, tAppId payload_id);
98 void AppIdAddMultiPayload(tAppIdData *flow, tAppId payload_id);
99 tAppIdData* appSharedDataAlloc(uint8_t proto, const struct in6_addr *ip, uint16_t initiator_port);
100 tAppId getOpenAppId(void *ssnptr);
101
102 void appSetServiceDetectorCallback(RNAServiceCallbackFCN fcn, tAppId appId, struct _Detector *userdata, tAppIdConfig *pConfig);
103 void appSetClientDetectorCallback(RNAClientAppCallbackFCN fcn, tAppId appId, struct _Detector *userdata, tAppIdConfig *pConfig);
104
105 void appSetServiceValidator(RNAServiceValidationFCN fcn, tAppId appId, unsigned extractsInfo, tAppIdConfig *pConfig);
106 void appSetLuaServiceValidator(RNAServiceValidationFCN fcn, tAppId appId, unsigned extractsInfo, struct _Detector *dat);
107 void appSetClientValidator(RNAClientAppFCN fcn, tAppId appId, unsigned extractsInfo, tAppIdConfig *pConfig);
108 void appSetLuaClientValidator(RNAClientAppFCN fcn, tAppId appId, unsigned extractsInfo, struct _Detector *data);
109 int sslAppGroupIdLookup(void *ssnptr, const char * serverName, const char * commonName, tAppId *serviceAppId, tAppId *clientAppId, tAppId *payloadAppId);
110
111 tAppId getAppId(void *ssnptr);
112 void CheckDetectorCallback(const SFSnortPacket *p, tAppIdData *session, APPID_SESSION_DIRECTION direction, tAppId appId, const tAppIdConfig *pConfig);
113 void setTlsHost(void *ssnptr, const char *serverName, const char *commonName,
114 const char *orgName, const char *subjectAltName, bool isSniMismatch,
115 tAppId *serviceAppId, tAppId *clientAppId, tAppId *payloadAppId);
116
117 #ifdef FW_TRACKER_DEBUG
118 void logAppIdInfo(SFSnortPacket *p, char *message, tAppId id);
119 #endif
120 int AppIdDebug(uint16_t type, const uint8_t *data, uint32_t length, void **new_context,
121 char* statusBuf, int statusBuf_len);
122
123 extern char app_id_debug_session[FW_DEBUG_SESSION_ID_SIZE];
124 extern bool app_id_debug_session_flag;
125
126 #ifdef PERF_PROFILING
127 extern PreprocStats httpPerfStats;
128 extern PreprocStats clientMatchPerfStats;
129 extern PreprocStats serviceMatchPerfStats;
130 extern PreprocStats luaDetectorsPerfStats;
131 extern PreprocStats luaCiscoPerfStats;
132 extern PreprocStats luaCustomPerfStats;
133 extern PreprocStats tpPerfStats;
134 extern PreprocStats tpLibPerfStats;
135 #endif
136
137 extern unsigned dhcp_fp_table_size;
138 extern unsigned long app_id_ongoing_session;
139 extern unsigned long app_id_total_alloc;
140 extern unsigned long app_id_raw_packet_count;
141 extern unsigned long app_id_processed_packet_count;
142 extern unsigned long app_id_ignored_packet_count;
143 extern unsigned long app_id_session_heap_alloc_count;
144 extern unsigned long app_id_session_freelist_alloc_count;
145 extern unsigned long app_id_flow_data_free_list_count;
146 extern unsigned long app_id_data_free_list_count;
147 extern unsigned long app_id_tmp_free_list_count;
148
149 extern int app_id_debug;
150 extern unsigned isIPv4HostMonitored(uint32_t ip4, int32_t zone);
151 extern void checkSandboxDetection(tAppId appId);
initializePriorityArray()152 static inline void initializePriorityArray()
153 {
154 int i;
155 for (i=0; i < SF_APPID_MAX; i++)
156 appIdPriorityArray[i] = 2;
157 }
158
setAppPriority(tAppId app_id,uint8_t bit_val)159 static inline void setAppPriority (tAppId app_id, uint8_t bit_val)
160 {
161 if (app_id < SF_APPID_MAX && bit_val <= APPID_MAX_PRIORITY )
162 appIdPriorityArray[app_id] = bit_val;
163 }
164
getAppPriority(tAppId app_id)165 static inline int getAppPriority (tAppId app_id)
166 {
167 if (app_id > APP_ID_NONE && app_id < SF_APPID_MAX)
168 return appIdPriorityArray[app_id] ;
169 else
170 return -1;
171 }
172
ThirdPartyAppIDFoundProto(tAppId proto,tAppId * proto_list)173 static inline int ThirdPartyAppIDFoundProto(tAppId proto, tAppId* proto_list)
174 {
175 unsigned int proto_cnt = 0;
176 while (proto_list[proto_cnt] != APP_ID_NONE)
177 if (proto_list[proto_cnt++] == proto)
178 return 1; // found
179 return 0; // not found
180 }
TPIsAppIdDone(void * tpSession)181 static inline int TPIsAppIdDone(void *tpSession)
182 {
183 if (thirdparty_appid_module)
184 {
185 unsigned state;
186
187 if (tpSession)
188 state = thirdparty_appid_module->session_state_get(tpSession);
189 else
190 state = TP_STATE_INIT;
191 return (state == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED || state == TP_STATE_HA);
192 }
193 return true;
194 }
195
TPIsAppIdAvailable(void * tpSession)196 static inline int TPIsAppIdAvailable(void * tpSession)
197 {
198 if (thirdparty_appid_module)
199 {
200 unsigned state;
201
202 if (tpSession)
203 state = thirdparty_appid_module->session_state_get(tpSession);
204 else
205 state = TP_STATE_INIT;
206 return (state == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED || state == TP_STATE_MONITORING);
207 }
208 return true;
209 }
210
isTPProcessingDone(tAppIdData * flow)211 static inline int isTPProcessingDone(tAppIdData *flow)
212 {
213 if (thirdparty_appid_module &&
214 !getAppIdFlag(flow, APPID_SESSION_NO_TPI) &&
215 (!TPIsAppIdDone(flow->tpsession) ||
216 getAppIdFlag(flow, APPID_SESSION_APP_REINSPECT | APPID_SESSION_APP_REINSPECT_SSL)))
217 return 0;
218 else
219 return 1;
220 }
isAppDetectionDone(tAppIdData * flow)221 static inline tAppId isAppDetectionDone(tAppIdData *flow)
222 {
223 return getAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
224 }
225
pickServiceAppId(tAppIdData * flow)226 static inline tAppId pickServiceAppId(tAppIdData *flow)
227 {
228 tAppId rval;
229
230 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
231 return APP_ID_NONE;
232
233 if (getAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED))
234 {
235 bool deferred = appInfoEntryFlagGet(flow->serviceAppId, APPINFO_FLAG_DEFER, appIdActiveConfigGet()) || appInfoEntryFlagGet(flow->tpAppId, APPINFO_FLAG_DEFER, appIdActiveConfigGet());
236
237 if (flow->serviceAppId > APP_ID_NONE && !deferred)
238 return flow->serviceAppId;
239 if (TPIsAppIdAvailable(flow->tpsession))
240 {
241 if (flow->tpAppId > APP_ID_NONE)
242 return flow->tpAppId;
243 else if (deferred)
244 return flow->serviceAppId;
245 else
246 rval = APP_ID_UNKNOWN_UI;
247 }
248 else
249 rval = flow->tpAppId;
250 }
251 else if (flow->tpAppId > APP_ID_NONE)
252 return flow->tpAppId;
253 else
254 rval = APP_ID_NONE;
255
256 if (flow->clientServiceAppId > APP_ID_NONE)
257 return flow->clientServiceAppId;
258
259 if (flow->portServiceAppId > APP_ID_NONE)
260 return flow->portServiceAppId;
261
262 return rval;
263 }
264
pickOnlyServiceAppId(tAppIdData * flow)265 static inline tAppId pickOnlyServiceAppId(tAppIdData *flow)
266 {
267 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
268 return APP_ID_NONE;
269
270 bool deferred = appInfoEntryFlagGet(flow->serviceAppId, APPINFO_FLAG_DEFER, appIdActiveConfigGet()) || appInfoEntryFlagGet(flow->tpAppId, APPINFO_FLAG_DEFER, appIdActiveConfigGet());
271
272 if (flow->serviceAppId > APP_ID_NONE && !deferred)
273 return flow->serviceAppId;
274
275 if (TPIsAppIdAvailable(flow->tpsession) && flow->tpAppId > APP_ID_NONE)
276 return flow->tpAppId;
277 else if (deferred)
278 return flow->serviceAppId;
279
280 if (flow->serviceAppId < APP_ID_NONE)
281 return APP_ID_UNKNOWN_UI;
282
283 return APP_ID_NONE;
284 }
285
pickMiscAppId(tAppIdData * flow)286 static inline tAppId pickMiscAppId(tAppIdData *flow)
287 {
288 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
289 return APP_ID_NONE;
290 if (flow->miscAppId > APP_ID_NONE)
291 return flow->miscAppId;
292 return APP_ID_NONE;
293 }
294
pickClientAppId(tAppIdData * flow)295 static inline tAppId pickClientAppId(tAppIdData *flow)
296 {
297 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
298 return APP_ID_NONE;
299 if (flow->clientAppId > APP_ID_NONE)
300 return flow->clientAppId;
301 return APP_ID_NONE;
302 }
303
isSvcHttpType(tAppId app_id)304 static inline bool isSvcHttpType(tAppId app_id)
305 {
306 switch(app_id)
307 {
308 case APP_ID_HTTP:
309 case APP_ID_HTTPS:
310 case APP_ID_FTPS:
311 case APP_ID_IMAPS:
312 case APP_ID_IRCS:
313 case APP_ID_LDAPS:
314 case APP_ID_NNTPS:
315 case APP_ID_POP3S:
316 case APP_ID_SMTPS:
317 case APP_ID_SSHELL:
318 case APP_ID_SSL:
319 return true;
320 }
321 return false;
322 }
323
pickPayloadId(tAppIdData * flow)324 static inline tAppId pickPayloadId(tAppIdData *flow)
325 {
326 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
327 return APP_ID_NONE;
328
329 // if we have a deferred payload, just use it.
330 // we are not worried about the APP_ID_UNKNOWN case here
331 if (appInfoEntryFlagGet(flow->tpPayloadAppId, APPINFO_FLAG_DEFER_PAYLOAD, appIdActiveConfigGet()))
332 return flow->tpPayloadAppId;
333 if (flow->payloadAppId > APP_ID_NONE)
334 return flow->payloadAppId;
335 if (flow->tpPayloadAppId > APP_ID_NONE)
336 return flow->tpPayloadAppId;
337 /* APP_ID_UNKNOWN is valid only for HTTP type services */
338 if (flow->payloadAppId == APP_ID_UNKNOWN &&
339 isSvcHttpType(flow->serviceAppId))
340 return APP_ID_UNKNOWN;
341 return APP_ID_NONE;
342 }
343
pickMultiPayloadList(tAppIdData * flow)344 static inline SFGHASH* pickMultiPayloadList(tAppIdData *flow)
345 {
346 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
347 return NULL;
348 if (flow->multiPayloadList)
349 return flow->multiPayloadList;
350 return NULL;
351 }
pickReferredPayloadId(tAppIdData * flow)352 static inline tAppId pickReferredPayloadId(tAppIdData *flow)
353 {
354 if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
355 return APP_ID_NONE;
356 if (flow->referredPayloadAppId > APP_ID_NONE)
357 return flow->referredPayloadAppId;
358 return APP_ID_NONE;
359 }
fwPickServiceAppId(tAppIdData * session)360 static inline tAppId fwPickServiceAppId(tAppIdData *session)
361 {
362 tAppId appId;
363 appId = pickServiceAppId(session);
364 if (appId == APP_ID_NONE || appId== APP_ID_UNKNOWN_UI)
365 appId = session->encrypted.serviceAppId;
366 return appId;
367 }
368
fwPickMiscAppId(tAppIdData * session)369 static inline tAppId fwPickMiscAppId(tAppIdData *session)
370 {
371 tAppId appId;
372 appId = pickMiscAppId(session);
373 if (appId == APP_ID_NONE)
374 appId = session->encrypted.miscAppId;
375 return appId;
376 }
377
fwPickClientAppId(tAppIdData * session)378 static inline tAppId fwPickClientAppId(tAppIdData *session)
379 {
380 tAppId appId;
381 appId = pickClientAppId(session);
382 return appId;
383 }
384
fwPickPayloadAppId(tAppIdData * session)385 static inline tAppId fwPickPayloadAppId(tAppIdData *session)
386 {
387 tAppId appId;
388 appId = pickPayloadId(session);
389 if (appId == APP_ID_NONE ||
390 (appId == APP_ID_SPDY && session && session->hsession && session->hsession->url == NULL && session->encrypted.payloadAppId>APP_ID_NONE))
391 appId = session->encrypted.payloadAppId;
392 return appId;
393 }
394
fwPickReferredPayloadAppId(tAppIdData * session)395 static inline tAppId fwPickReferredPayloadAppId(tAppIdData *session)
396 {
397 tAppId appId;
398 appId = pickReferredPayloadId(session);
399 if (appId == APP_ID_NONE)
400 appId = session->encrypted.referredAppId;
401 return appId;
402 }
403
fwPickMultiPayloadList(tAppIdData * session)404 static inline SFGHASH* fwPickMultiPayloadList(tAppIdData *session)
405 {
406 SFGHASH* multiPayloadList = NULL;
407 multiPayloadList = pickMultiPayloadList(session);
408 return multiPayloadList;
409 }
410
appSharedGetData(const SFSnortPacket * p)411 static inline tAppIdData* appSharedGetData(const SFSnortPacket *p)
412 {
413 return _dpd.sessionAPI->get_application_data(p->stream_session, PP_APP_ID);
414 }
415
isFwSessionSslDecrypted(tAppIdData * session)416 static inline unsigned int isFwSessionSslDecrypted(tAppIdData *session)
417 {
418 return getAppIdFlag(session, APPID_SESSION_DECRYPTED);
419 }
testSSLAppIdForReinspect(tAppId app_id)420 static inline int testSSLAppIdForReinspect (tAppId app_id)
421 {
422 if (app_id <= SF_APPID_MAX && (app_id == APP_ID_SSL || appInfoEntryFlagGet(app_id, APPINFO_FLAG_SSL_INSPECT, appIdActiveConfigGet())))
423 return 1;
424 else
425 return 0;
426 }
427 #endif
428