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