"Fossies" - the Fresh Open Source Software Archive 
Member "snort-2.9.17/src/dynamic-preprocessors/appid/appInfoTable.c" (16 Oct 2020, 37417 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "appInfoTable.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.9.16.1_vs_2.9.17.
1 /*
2 ** Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 2005-2013 Sourcefire, Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation. You may not use, modify or
8 ** distribute this program under any other version of the GNU General
9 ** Public License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include <syslog.h>
32 #include <limits.h>
33 #include "appId.h"
34 #include "appInfoTable.h"
35 #include "Unified2_common.h"
36
37 #define APP_MAPPING_FILE "appMapping.data"
38 #define APP_CONFIG_FILE "appid.conf"
39 #define USR_CONFIG_FILE "userappid.conf"
40
41 #define MAX_TABLE_LINE_LEN 1024
42 // Generic delimiter for conf file
43 #define CONF_SEPARATORS "\t\n\r"
44 // Delimiter for appid.conf and userappid.conf file
45 #define CONF_SEPARATORS_USR_APPID " \t\n\r"
46 #define MIN_MAX_TP_FLOW_DEPTH 1
47 #define MAX_MAX_TP_FLOW_DEPTH 1000000
48 #define MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL 1
49 #define MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL 1000000
50 #define MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE 1
51 #define MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE 1000000
52 #define MIN_MAX_BYTES_BEFORE_SERVICE_FAIL 4096
53 #define MIN_MAX_PACKET_BEFORE_SERVICE_FAIL 5
54 #define MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES 15
55 struct DynamicArray
56 {
57 void **table;
58 size_t indexStart;
59 size_t indexCurrent;
60 size_t usedCount;
61 size_t allocatedCount;
62 size_t stepSize;
63 };
64 typedef struct DynamicArray tDynamicArray;
65
66 static inline struct DynamicArray* dynamicArrayCreate(unsigned indexStart)
67 {
68 struct DynamicArray *array;
69
70 if ((array = calloc(1, sizeof(*array))))
71 {
72 array->stepSize = 1;
73 array->indexStart = indexStart;
74 }
75 return array;
76 }
77
78 static inline void dynamicArrayDestroy(struct DynamicArray *array)
79 {
80 unsigned i;
81 AppInfoTableEntry *entry;
82
83 if (!array)
84 return;
85 for (i = 0; i < array->usedCount; i++)
86 {
87 entry = array->table[i];
88 free(entry->appName);
89 free(entry);
90 }
91
92 free(array->table);
93 free(array);
94 }
95
96 static inline void dynamicArraySetIndex(struct DynamicArray *array, unsigned index, void* data)
97 {
98 if (index >= array->indexStart && index < (array->indexStart + array->usedCount))
99 array->table[index - array->indexStart] = data;
100 }
101 static inline void* dynamicArrayGetIndex(struct DynamicArray *array, unsigned index)
102 {
103 if (index >= array->indexStart && index < (array->indexStart + array->usedCount))
104 return array->table[index - array->indexStart];
105 return NULL;
106 }
107 static inline bool dynamicArrayCreateIndex(struct DynamicArray *array, unsigned *index)
108 {
109 if (array->usedCount == array->allocatedCount)
110 {
111 void** tmp = realloc(array->table, (array->allocatedCount + array->stepSize)*sizeof(*tmp));
112 if (!tmp)
113 {
114 return false;
115 }
116 array->table = tmp;
117 array->allocatedCount += array->stepSize;
118 }
119 *index = array->indexStart + (array->usedCount++);
120 return true;
121 }
122
123 static inline void* dynamicArrayGetFirst(struct DynamicArray *array)
124 {
125 AppInfoTableEntry *entry;
126 for (array->indexCurrent = 0; array->indexCurrent < array->usedCount; array->indexCurrent++)
127 {
128 if ((entry = array->table[array->indexCurrent]))
129 return entry;
130 }
131 return NULL;
132 }
133 static inline void* dynamicArrayGetNext(struct DynamicArray *array)
134 {
135 AppInfoTableEntry *entry;
136 for (array->indexCurrent++; array->indexCurrent < array->usedCount; array->indexCurrent++)
137 {
138 if ((entry = array->table[array->indexCurrent]))
139 return entry;
140 }
141 return NULL;
142 }
143 // End of Dynamic array
144 SFGHASH* appNameHashInit()
145 {
146 SFGHASH *appNameHash;
147 appNameHash = sfghash_new(65, 0, 0 /* alloc copies of lowercased keys */, NULL);
148 if (!appNameHash)
149 {
150 _dpd.fatalMsg("AppNameHash: Failed to Initialize\n");
151 }
152 return appNameHash;
153 }
154 void appNameHashFini(SFGHASH *appNameHash)
155 {
156 if (appNameHash)
157 {
158 sfghash_delete(appNameHash);
159 }
160 }
161
162 static inline char *strdupToLower(const char *source)
163 {
164 int index;
165 char *dest = malloc(strlen(source)+1);
166
167 if (dest)
168 {
169 for(index = 0;; index++)
170 {
171 if (source[index])
172 {
173 dest[index] = tolower(source[index]);
174 continue;
175 }
176 else
177 {
178 dest[index] = '\0';
179 break;
180 }
181 }
182 }
183 else
184 _dpd.errMsg("strdupToLower: Failed to allocate memory for destination\n");
185
186 return dest;
187 }
188
189 void appNameHashAdd(SFGHASH *appNameHash, const char *appName, void *data)
190 {
191 char *searchName;
192 int errCode;
193
194 if (!appName || !appNameHash)
195 return;
196
197 searchName = strdupToLower(appName);
198 if (!searchName)
199 return;
200
201 if (SFGHASH_OK == (errCode = sfghash_add(appNameHash, searchName, data)))
202 {
203 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "App name added for %s\n", appName););
204 }
205 else if (SFGHASH_INTABLE == errCode)
206 {
207 /* Note that, although this entry is not placed in the hash table,
208 being a duplicate, it remains in the list of allocated entries
209 for cleanup by appInfoTableFini() */
210
211 // Rediscover the existing, hashed entry for the purpose of a complete error message.
212 AppInfoTableEntry* tableEntry = (AppInfoTableEntry*)sfghash_find(appNameHash, searchName);
213
214 if (tableEntry)
215 {
216 _dpd.errMsg("App name, \"%s\", is a duplicate of \"%s\" and has been ignored.\n",
217 appName, tableEntry->appName );
218 }
219 else
220 {
221 _dpd.errMsg("App name, \"%s\", has been ignored. Hash key \"%s\" is not unique.\n",
222 appName, searchName );
223 }
224 }
225 free(searchName);
226 }
227
228 void* appNameHashFind(SFGHASH *appNameHash, const char *appName)
229 {
230 void *data;
231 char *searchName;
232
233 if (!appName || !appNameHash)
234 return NULL;
235
236 searchName = strdupToLower(appName);
237 if (!searchName)
238 return NULL;
239
240 data = sfghash_find(appNameHash, searchName);
241
242 free(searchName);
243
244 return data;
245 }
246 // End of appName hash
247
248 static void appIdConfLoad (tAppidStaticConfig* appidSC, const char *path);
249
250 static unsigned int getAppIdStaticIndex(tAppId appid)
251 {
252 if (appid > 0 && appid < SF_APPID_BUILDIN_MAX)
253 return appid;
254 if (appid >= SF_APPID_CSD_MIN && appid < SF_APPID_CSD_MIN+(SF_APPID_MAX-SF_APPID_BUILDIN_MAX))
255 return (SF_APPID_BUILDIN_MAX + appid - SF_APPID_CSD_MIN);
256 return 0;
257 }
258
259 AppInfoTableEntry* appInfoEntryGet(tAppId appId, const tAppIdConfig *pConfig)
260 {
261 tAppId tmp;
262 if ((tmp = getAppIdStaticIndex(appId)))
263 return pConfig->AppInfoTable[tmp];
264 return dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
265 }
266
267 AppInfoTableEntry* appInfoEntryCreate(const char *appName, tAppIdConfig *pConfig)
268 {
269 tAppId appId;
270 AppInfoTableEntry *entry;
271
272 if (!appName || strlen(appName) >= MAX_EVENT_APPNAME_LEN)
273 {
274 _dpd.errMsg("Appname invalid\n", appName);
275 return NULL;
276 }
277
278 entry = appNameHashFind(pConfig->AppNameHash, appName);
279 if (!entry)
280 {
281 if (!dynamicArrayCreateIndex(pConfig->AppInfoTableDyn, (uint32_t *)&appId))
282 {
283 return NULL;
284 }
285
286 if ((entry = calloc(1, sizeof(*entry))))
287 {
288 entry->appId = appId;
289 entry->serviceId = entry->appId;
290 entry->clientId = entry->appId;
291 entry->payloadId = entry->appId;
292 entry->appName = strdup(appName);
293 if (!entry->appName)
294 {
295 _dpd.errMsg("failed to allocate appName");
296 free(entry);
297 return NULL;
298 }
299
300 dynamicArraySetIndex(pConfig->AppInfoTableDyn, appId, entry);
301 if (pConfig->AppNameHash != NULL)
302 appNameHashAdd(pConfig->AppNameHash, appName, entry);
303 }
304 else
305 {
306 _dpd.errMsg("calloc failure\n");
307 }
308 }
309 return entry;
310 }
311
312 void appInfoTableInit(tAppidStaticConfig* appidSC, tAppIdConfig* pConfig)
313 {
314 FILE *tableFile;
315 const char *token;
316 char buf[MAX_TABLE_LINE_LEN];
317 AppInfoTableEntry *entry;
318 tAppId appId;
319 uint32_t clientId, serviceId, payloadId;
320 char filepath[PATH_MAX];
321 char *appName=NULL;
322 char *snortName=NULL;
323
324 pConfig->AppInfoTableDyn = dynamicArrayCreate(SF_APPID_DYNAMIC_MIN);
325
326 snprintf(filepath, sizeof(filepath), "%s/odp/%s", appidSC->app_id_detector_path, APP_MAPPING_FILE);
327
328 tableFile = fopen(filepath, "r");
329 if (tableFile == NULL)
330 {
331 _dpd.errMsg("Could not open RnaAppMapping Table file: %s\n", filepath);
332 return;
333 }
334
335 DEBUG_WRAP(DebugMessage(DEBUG_APPID, " AppInfo read from %s\n", filepath););
336
337 while (fgets(buf, sizeof(buf), tableFile))
338 {
339 token = strtok(buf, CONF_SEPARATORS );
340 if (!token)
341 {
342 _dpd.errMsg("Could not read id for Rna Id\n");
343 continue;
344 }
345
346 appId = strtol(token, NULL, 10);
347
348 token = strtok(NULL, CONF_SEPARATORS );
349 if (!token)
350 {
351 _dpd.errMsg("Could not read appName. Line %s\n", buf);
352 continue;
353 }
354
355 appName = strdup(token);
356 if (!appName)
357 {
358 _dpd.errMsg("Could not allocate space for appName\n");
359 continue;
360 }
361
362 token = strtok(NULL, CONF_SEPARATORS );
363 if (!token)
364 {
365 _dpd.errMsg("Could not read service id for Rna Id\n");
366 free(appName);
367 continue;
368 }
369
370 serviceId = strtol(token, NULL, 10);
371
372 token = strtok(NULL, CONF_SEPARATORS );
373 if (!token)
374 {
375 _dpd.errMsg("Could not read client id for Rna Id\n");
376 free(appName);
377 continue;
378 }
379
380 clientId = strtol(token, NULL, 10);
381
382 token = strtok(NULL, CONF_SEPARATORS );
383 if (!token)
384 {
385 _dpd.errMsg("Could not read payload id for Rna Id\n");
386 free(appName);
387 continue;
388 }
389
390 payloadId = strtol(token, NULL, 10);
391
392 /* snort service key, if it exists */
393 token = strtok(NULL, CONF_SEPARATORS );
394 if (token)
395 {
396 snortName = strdup(token);
397 if (!snortName)
398 {
399 _dpd.errMsg("malloc failure\n");
400 free(appName);
401 continue;
402 }
403 }
404
405
406 entry = calloc(1, sizeof(*entry));
407 if (!entry)
408 {
409 _dpd.errMsg("AppInfoTable: Memory allocation failure\n");
410 free(appName);
411 free(snortName);
412 continue;
413 }
414
415 entry->next = pConfig->AppInfoList;
416 pConfig->AppInfoList = entry;
417
418 if (snortName)
419 {
420 #ifdef TARGET_BASED
421 entry->snortId = _dpd.addProtocolReference(snortName);
422 free(snortName);
423 snortName = NULL;
424 #endif
425 }
426
427 entry->appName = appName;
428
429 entry->appId = appId;
430 entry->serviceId = serviceId;
431 entry->clientId = clientId;
432 entry->payloadId = payloadId;
433 entry->priority = APP_PRIORITY_DEFAULT;
434
435 if ((appId = getAppIdStaticIndex(entry->appId)))
436 pConfig->AppInfoTable[appId] = entry;
437 if ((appId = getAppIdStaticIndex(entry->serviceId)))
438 pConfig->AppInfoTableByService[appId] = entry;
439 if ((appId = getAppIdStaticIndex(entry->clientId)))
440 pConfig->AppInfoTableByClient[appId] = entry;
441 if ((appId = getAppIdStaticIndex(entry->payloadId)))
442 pConfig->AppInfoTableByPayload[appId] = entry;
443
444 if (!pConfig->AppNameHash)
445 {
446 pConfig->AppNameHash = appNameHashInit();
447 }
448 appNameHashAdd(pConfig->AppNameHash, appName, entry);
449 }
450 fclose(tableFile);
451
452 /* Configuration defaults. */
453 appidSC->rtmp_max_packets = 15;
454 appidSC->mdns_user_reporting = 1;
455 appidSC->dns_host_reporting = 1;
456 appidSC->max_tp_flow_depth = 5;
457 appidSC->http2_detection_enabled = 0;
458 appidSC->host_port_app_cache_lookup_interval = 10;
459 appidSC->host_port_app_cache_lookup_range = 100000;
460 appidSC->is_host_port_app_cache_runtime = 1;
461 appidSC->check_host_port_app_cache = 0;
462 appidSC->check_host_cache_unknown_ssl = 0;
463 appidSC->recheck_for_unknown_appid = 0;
464 appidSC->send_state_sharing_updates = 1;
465 appidSC->allow_port_wildcard_host_cache = 0;
466 appidSC->recheck_for_portservice_appid = 0;
467 appidSC->max_packet_before_service_fail = MIN_MAX_PACKET_BEFORE_SERVICE_FAIL;
468 appidSC->max_bytes_before_service_fail = MIN_MAX_BYTES_BEFORE_SERVICE_FAIL;
469 appidSC->max_packet_service_fail_ignore_bytes = MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES;
470 appidSC->http_tunnel_detect = HTTP_TUNNEL_DETECT_RESTART;
471 snprintf(filepath, sizeof(filepath), "%s/odp/%s", appidSC->app_id_detector_path, APP_CONFIG_FILE);
472 appIdConfLoad (appidSC, filepath);
473 snprintf(filepath, sizeof(filepath), "%s/../%s", appidSC->app_id_detector_path, USR_CONFIG_FILE);
474 appIdConfLoad (appidSC, filepath);
475 }
476
477 void appInfoTableFini(tAppIdConfig *pConfig)
478 {
479 AppInfoTableEntry *entry;
480
481 while ((entry = pConfig->AppInfoList))
482 {
483 pConfig->AppInfoList = entry->next;
484 if (entry->appName)
485 free(entry->appName);
486 free(entry);
487 }
488
489 dynamicArrayDestroy(pConfig->AppInfoTableDyn);
490 pConfig->AppInfoTableDyn = NULL;
491
492 appNameHashFini(pConfig->AppNameHash);
493 }
494
495 void appInfoTableDump(tAppIdConfig *pConfig)
496 {
497 AppInfoTableEntry *entry;
498 tAppId appId;
499
500 _dpd.errMsg("Cisco provided detectors:\n");
501 for (appId = 1; appId < SF_APPID_MAX; appId++)
502 {
503 entry = pConfig->AppInfoTable[appId];
504 if (entry)
505 _dpd.errMsg("%s\t%d\t%s\n", entry->appName, entry->appId, (entry->flags & APPINFO_FLAG_ACTIVE)? "active":"inactive");
506 }
507 _dpd.errMsg("User provided detectors:\n");
508 for (entry = dynamicArrayGetFirst(pConfig->AppInfoTableDyn); entry; entry = dynamicArrayGetNext(pConfig->AppInfoTableDyn))
509 {
510 _dpd.errMsg("%s\t%d\t%s\n", entry->appName, entry->appId, (entry->flags & APPINFO_FLAG_ACTIVE)? "active":"inactive");
511 }
512 }
513 tAppId appGetAppFromServiceId(uint32_t appId, tAppIdConfig *pConfig)
514 {
515 AppInfoTableEntry *entry;
516 tAppId tmp;
517
518 if ((tmp = getAppIdStaticIndex(appId)))
519 entry = pConfig->AppInfoTableByService[tmp];
520 else
521 entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
522
523 return entry ? entry->appId : APP_ID_NONE;
524 }
525
526 tAppId appGetAppFromClientId(uint32_t appId, tAppIdConfig *pConfig)
527 {
528 AppInfoTableEntry *entry;
529 tAppId tmp;
530
531 if ((tmp = getAppIdStaticIndex(appId)))
532 entry = pConfig->AppInfoTableByClient[tmp];
533 else
534 entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
535
536 return entry ? entry->appId : APP_ID_NONE;
537 }
538 tAppId appGetAppFromPayloadId(uint32_t appId, tAppIdConfig *pConfig)
539 {
540 AppInfoTableEntry *entry;
541 tAppId tmp;
542
543 if ((tmp = getAppIdStaticIndex(appId)))
544 entry = pConfig->AppInfoTableByPayload[tmp];
545 else
546 entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
547
548 return entry ? entry->appId : APP_ID_NONE;
549 }
550 const char * appGetAppName(int32_t appId)
551 {
552 AppInfoTableEntry *entry;
553 tAppIdConfig *pConfig = appIdActiveConfigGet();
554 tAppId tmp;
555
556 if ((tmp = getAppIdStaticIndex(appId)))
557 entry = pConfig->AppInfoTable[tmp];
558 else
559 entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
560
561 return entry ? entry->appName : NULL;
562 }
563
564 int32_t appGetAppId(const char *appName)
565 {
566 AppInfoTableEntry *entry;
567 tAppIdConfig *pConfig = appIdActiveConfigGet();
568
569 entry = appNameHashFind(pConfig->AppNameHash, appName);
570 return entry?entry->appId:0;
571 }
572
573 void appInfoSetActive(tAppId appId, bool active)
574 {
575 AppInfoTableEntry *entry = NULL;
576 tAppIdConfig *pConfig = appIdActiveConfigGet();
577 tAppId tmp;
578
579 if (appId == APP_ID_NONE)
580 return;
581
582 if ((tmp = getAppIdStaticIndex(appId)))
583 entry = pConfig->AppInfoTable[tmp];
584 else
585 entry = dynamicArrayGetIndex(pConfig->AppInfoTableDyn, appId);
586
587 if (entry)
588 {
589 if (active)
590 entry->flags |= APPINFO_FLAG_ACTIVE;
591 else
592 entry->flags &= ~APPINFO_FLAG_ACTIVE;
593 }
594 else
595 {
596 _dpd.errMsg("AppInfo: AppId %d is UNKNOWN\n", appId);
597 }
598 }
599
600
601 static void appIdConfLoad (tAppidStaticConfig* appidSC, const char *path)
602 {
603 FILE *config_file;
604 char *token;
605 char buf[1024];
606 char referred_app_list[4096];
607 int referred_app_index;
608 char *conf_type;
609 char *conf_key;
610 char *conf_val;
611 unsigned line = 0;
612 tAppIdConfig *pConfig = appIdNewConfigGet();
613 int max_tp_flow_depth;
614 int host_port_app_cache_lookup_interval;
615 int host_port_app_cache_lookup_range;
616
617 config_file = fopen(path, "r");
618 if (config_file == NULL)
619 {
620 return;
621 }
622 else
623 {
624 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "Loading configuration file %s\n", path););
625 }
626
627 while (fgets(buf, sizeof(buf), config_file) != NULL)
628 {
629 line++;
630 token = strtok(buf, CONF_SEPARATORS_USR_APPID);
631 if (token == NULL)
632 {
633 _dpd.errMsg("Could not read configuration at line %s:%u\n", path, line);
634 continue;
635 }
636 conf_type = token;
637
638 token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
639 if (token == NULL)
640 {
641 _dpd.errMsg("Could not read configuration value at line %s:%u\n", path, line);
642 continue;
643 }
644 conf_key = token;
645
646 token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
647 if (token == NULL)
648 {
649 _dpd.errMsg("Could not read configuration value at line %s:%u\n", path, line);
650 continue;
651 }
652 conf_val = token;
653
654 /* APPID configurations are for anything else - currently we only have ssl_reinspect */
655 if (!(strcasecmp(conf_type, "appid")))
656 {
657 if (!(strcasecmp(conf_key, "max_tp_flow_depth")))
658 {
659 max_tp_flow_depth = atoi(conf_val);
660 if (max_tp_flow_depth < MIN_MAX_TP_FLOW_DEPTH || max_tp_flow_depth > MAX_MAX_TP_FLOW_DEPTH)
661 {
662 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_tp_flow_depth %d, must be between %d and %d\n.", max_tp_flow_depth, MIN_MAX_TP_FLOW_DEPTH, MAX_MAX_TP_FLOW_DEPTH););
663 }
664 else
665 {
666 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: setting max thirdparty inspection flow depth to %d packets.\n", max_tp_flow_depth););
667 appidSC->max_tp_flow_depth = max_tp_flow_depth;
668 }
669 }
670 else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_interval")))
671 {
672 host_port_app_cache_lookup_interval = atoi(conf_val);
673 if (host_port_app_cache_lookup_interval < MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL || host_port_app_cache_lookup_interval > MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL)
674 {
675 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid host_port_app_cache_lookup_interval %d, must be between %d and %d\n.",
676 host_port_app_cache_lookup_interval, MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL, MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL););
677 }
678 else
679 {
680 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed every %d packet(s).\n", host_port_app_cache_lookup_interval););
681 appidSC->host_port_app_cache_lookup_interval = host_port_app_cache_lookup_interval;
682 }
683 }
684 else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_range")))
685 {
686 host_port_app_cache_lookup_range = atoi(conf_val);
687 if (host_port_app_cache_lookup_range < MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE || host_port_app_cache_lookup_range > MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE)
688 {
689 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid host_port_app_cache_lookup_range %d, must be between %d and %d\n.",
690 host_port_app_cache_lookup_range, MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE, MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE););
691 }
692 else
693 {
694 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed till maximum of %d packet(s) per session.\n", host_port_app_cache_lookup_range););
695 appidSC->host_port_app_cache_lookup_range = host_port_app_cache_lookup_range;
696 }
697 }
698 else if (!(strcasecmp(conf_key, "is_host_port_app_cache_runtime")))
699 {
700 if (!(strcasecmp(conf_val, "disabled")))
701 {
702 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache not configured for runtime modification.\n"););
703 appidSC->is_host_port_app_cache_runtime = 0;
704 }
705 }
706 else if (!(strcasecmp(conf_key, "check_host_port_app_cache")))
707 {
708 if (!(strcasecmp(conf_val, "enabled")))
709 {
710 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed for every flow.\n"););
711 appidSC->check_host_port_app_cache = 1;
712 }
713 }
714 else if (!(strcasecmp(conf_key, "check_host_cache_unknown_ssl")))
715 {
716 if (!(strcasecmp(conf_val, "enabled")))
717 {
718 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: hostPortCache lookup performed for SSL flows not having either of server name or certificate.\n"););
719 appidSC->check_host_cache_unknown_ssl = 1;
720 }
721 }
722 else if (!(strcasecmp(conf_key, "recheck_for_unknown_appid")))
723 {
724 if (!(strcasecmp(conf_val, "enabled")))
725 {
726 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: Flows with unknown AppID's will not be ignored.\n"););
727 appidSC->recheck_for_unknown_appid = 1;
728 }
729 }
730 else if (!(strcasecmp(conf_key, "recheck_for_portservice_appid")))
731 {
732 if (!(strcasecmp(conf_val, "enabled")))
733 {
734 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: Checking hostPortCache for flows with only port service AppID.\n"););
735 appidSC->recheck_for_portservice_appid = 1;
736 }
737 }
738 else if (!(strcasecmp(conf_key, "tp_allow_probes")))
739 {
740 if (!(strcasecmp(conf_val, "enabled")))
741 {
742 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: TCP probes will be analyzed by NAVL.\n"););
743 appidSC->tp_allow_probes = 1;
744 }
745 }
746 else if (!(strcasecmp(conf_key, "tp_client_app")))
747 {
748 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: if thirdparty reports app %d, we will use it as a client.\n", atoi(conf_val)););
749 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_TP_CLIENT, pConfig);
750 }
751 else if (!(strcasecmp(conf_key, "ssl_reinspect")))
752 {
753 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of SSL apps that get more granular inspection.\n", atoi(conf_val)););
754 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_SSL_INSPECT, pConfig);
755 }
756 else if (!(strcasecmp(conf_key, "disable_safe_search")))
757 {
758 if (!(strcasecmp(conf_val, "disabled")))
759 {
760 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: disabling safe search enforcement.\n"););
761 appidSC->disable_safe_search = 1;
762 }
763 }
764 else if (!(strcasecmp(conf_key, "ssl_squelch")))
765 {
766 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of SSL apps that may open a second SSL connection.\n", atoi(conf_val)););
767 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_SSL_SQUELCH, pConfig);
768 }
769 else if (!(strcasecmp(conf_key, "defer_to_thirdparty")))
770 {
771 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of apps where we should take thirdparty ID over the NDE's.\n", atoi(conf_val)););
772 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_DEFER, pConfig);
773 }
774 else if (!(strcasecmp(conf_key, "defer_payload_to_thirdparty")))
775 {
776 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding app %d to list of apps where we should take thirdparty payload ID over the NDE's.\n", atoi(conf_val)););
777 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
778 }
779 else if (!(strcasecmp(conf_key, "chp_userid")))
780 {
781 if (!(strcasecmp(conf_val, "disabled")))
782 {
783 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP UserID collection disabled.\n"););
784 appidSC->chp_userid_disabled = 1;
785 continue;
786 }
787 }
788 else if (!(strcasecmp(conf_key, "chp_body_collection")))
789 {
790 if (!(strcasecmp(conf_val, "disabled")))
791 {
792 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP Body header reading disabled.\n"););
793 appidSC->chp_body_collection_disabled = 1;
794 continue;
795 }
796 }
797 else if (!(strcasecmp(conf_key, "chp_fflow")))
798 {
799 if (!(strcasecmp(conf_val, "disabled")))
800 {
801 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP future flow creation disabled.\n"););
802 appidSC->chp_fflow_disabled = 1;
803 continue;
804 }
805 }
806 else if (!(strcasecmp(conf_key, "ftp_userid")))
807 {
808 if (!(strcasecmp(conf_val, "disabled")))
809 {
810 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: FTP userID disabled.\n"););
811 appidSC->ftp_userid_disabled = 1;
812 continue;
813 }
814 }
815 else if (!(strcasecmp(conf_key, "max_bytes_before_service_fail")))
816 {
817 uint64_t max_bytes_before_service_fail = atoi(conf_val);
818 if (max_bytes_before_service_fail < MIN_MAX_BYTES_BEFORE_SERVICE_FAIL)
819 {
820 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_bytes_before_service_fail %"PRIu64" must be greater than %u\n.", max_bytes_before_service_fail, MIN_MAX_BYTES_BEFORE_SERVICE_FAIL ););
821 }
822 else
823 appidSC->max_bytes_before_service_fail = max_bytes_before_service_fail;
824 }
825 else if (!(strcasecmp(conf_key, "max_packet_before_service_fail")))
826 {
827 uint16_t max_packet_before_service_fail = atoi(conf_val);
828 if (max_packet_before_service_fail < MIN_MAX_PACKET_BEFORE_SERVICE_FAIL)
829 {
830 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_packet_before_service_fail %"PRIu16", must be greater than %u \n.", max_packet_before_service_fail, MIN_MAX_PACKET_BEFORE_SRV_FAIL););
831 }
832 else
833 appidSC->max_packet_before_service_fail = max_packet_before_service_fail;
834 }
835 else if (!(strcasecmp(conf_key, "max_packet_service_fail_ignore_bytes")))
836 {
837 uint16_t max_packet_service_fail_ignore_bytes = atoi(conf_val);
838 if (max_packet_service_fail_ignore_bytes < MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES)
839 {
840 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: invalid max_packet_service_fail_ignore_bytes %"PRIu16", must be greater than %u\n.", max_packet_service_fail_ignore_bytes, MIN_MAX_PACKET_BEFORE_SERVICE_FAIL_IGNORE_BYTES););
841 }
842 else
843 appidSC->max_packet_service_fail_ignore_bytes= max_packet_service_fail_ignore_bytes;
844 }
845 else if (!(strcasecmp(conf_key, "http_tunnel_detect")))
846 {
847 if (!(strcasecmp(conf_val, "restart_and_reset")))
848 {
849 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: HTTP tunnel detect set to restart and reset.\n"););
850 appidSC->http_tunnel_detect = HTTP_TUNNEL_DETECT_RESTART_AND_RESET;
851 continue;
852 }
853 }
854 /* App Priority bit set*/
855 else if (!(strcasecmp(conf_key, "app_priority")))
856 {
857 int temp_appid;
858 temp_appid = strtol(conf_val, NULL, 10 );
859 token = strtok(NULL, CONF_SEPARATORS_USR_APPID);
860 if (token == NULL)
861 {
862 _dpd.errMsg("Could not read app_priority at line %u\n", line);
863 continue;
864 }
865 conf_val = token;
866 uint8_t temp_val;
867 temp_val = strtol(conf_val, NULL, 10 );
868 appInfoEntryPrioritySet (temp_appid, temp_val, pConfig);
869 DEBUG_WRAP(DebugMessage(DEBUG_APPID,"AppId: %d Setting priority bit %d .\n", temp_appid, temp_val););
870 }
871 else if (!(strcasecmp(conf_key, "referred_appId")))
872 {
873
874 if (!(strcasecmp(conf_val, "disabled")))
875 {
876 appidSC->referred_appId_disabled = 1;
877 continue;
878 }
879
880 else if (!appidSC->referred_appId_disabled)
881 {
882 referred_app_index=0;
883 referred_app_index += sprintf(referred_app_list, "%d ", atoi(conf_val));
884 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_REFERRED, pConfig);
885
886 while ((token = strtok(NULL, CONF_SEPARATORS_USR_APPID)) != NULL)
887 {
888 referred_app_index += sprintf(referred_app_list+referred_app_index, "%d ", atoi(token));
889 appInfoEntryFlagSet(atoi(token), APPINFO_FLAG_REFERRED, pConfig);
890 }
891 DEBUG_WRAP(DebugMessage(DEBUG_APPID, "AppId: adding appIds to list of referred web apps: %s\n", referred_app_list););
892 }
893 }
894 else if (!(strcasecmp(conf_key, "rtmp_max_packets")))
895 {
896 appidSC->rtmp_max_packets = atoi(conf_val);
897 }
898 else if (!(strcasecmp(conf_key, "mdns_user_report")))
899 {
900 appidSC->mdns_user_reporting = atoi(conf_val);
901 }
902 else if (!(strcasecmp(conf_key, "dns_host_report")))
903 {
904 appidSC->dns_host_reporting = atoi(conf_val);
905 }
906 else if (!(strcasecmp(conf_key, "chp_body_max_bytes")))
907 {
908 appidSC->chp_body_collection_max = atoi(conf_val);
909 }
910 else if (!(strcasecmp(conf_key, "ignore_thirdparty_appid")))
911 {
912 _dpd.logMsg("AppId: adding app %d to list of ignore thirdparty apps.\n", atoi(conf_val));
913 appInfoEntryFlagSet(atoi(conf_val), APPINFO_FLAG_IGNORE, pConfig);
914 }
915 else if (!(strcasecmp(conf_key, "http2_detection")))
916 {
917 // This option will control our own HTTP/2 detection. We can
918 // still be told externally, though, that it's HTTP/2 (either
919 // from HTTP Inspect or 3rd Party). This is intended to be
920 // used to ask AppID to detect unencrypted HTTP/2 on non-std
921 // ports.
922 if (!(strcasecmp(conf_val, "disabled")))
923 {
924 _dpd.logMsg("AppId: disabling internal HTTP/2 detection.\n");
925 appidSC->http2_detection_enabled = 0;
926 }
927 else if (!(strcasecmp(conf_val, "enabled")))
928 {
929 _dpd.logMsg("AppId: enabling internal HTTP/2 detection.\n");
930 appidSC->http2_detection_enabled = 1;
931 }
932 else
933 {
934 _dpd.logMsg("AppId: ignoring invalid option for http2_detection: %s\n", conf_val);
935 }
936 }
937 else if (!(strcasecmp(conf_key, "send_state_sharing_updates")))
938 {
939 if (!(strcasecmp(conf_val, "disabled")))
940 {
941 _dpd.logMsg("AppId: Disabling state sharing updates.\n");
942 appidSC->send_state_sharing_updates = 0;
943 }
944 }
945 else if (!(strcasecmp(conf_key, "allow_port_wildcard_host_cache")))
946 {
947 if (!(strcasecmp(conf_val, "enabled")))
948 {
949 _dpd.logMsg("AppId: Enabling wild card for port numbers in hostPortAppCache.\n");
950 appidSC->allow_port_wildcard_host_cache = 1;
951 }
952 }
953 else if (!(strcasecmp(conf_key, "bittorrent_aggressiveness")))
954 {
955 int aggressiveness = atoi(conf_val);
956 _dpd.logMsg("AppId: bittorrent_aggressiveness %d\n", aggressiveness);
957 if (aggressiveness >= 50)
958 {
959 appidSC->recheck_for_unknown_appid = 1;
960 appidSC->recheck_for_portservice_appid = 1;
961 appidSC->host_port_app_cache_lookup_interval = 5;
962 appidSC->max_tp_flow_depth = 25;
963 appInfoEntryFlagSet(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER, pConfig);
964 appInfoEntryFlagSet(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
965 }
966 if (aggressiveness >= 80)
967 {
968 appidSC->allow_port_wildcard_host_cache = 1;
969 }
970 }
971 else if (!(strcasecmp(conf_key, "ultrasurf_aggressiveness")))
972 {
973 int aggressiveness = atoi(conf_val);
974 _dpd.logMsg("AppId: ultrasurf_aggressiveness %d\n", aggressiveness);
975 if (aggressiveness >= 50)
976 {
977 appidSC->check_host_cache_unknown_ssl = 1;
978 appidSC->max_tp_flow_depth = 25;
979 appInfoEntryFlagSet(APP_ID_ULTRASURF, APPINFO_FLAG_DEFER, pConfig);
980 appInfoEntryFlagSet(APP_ID_ULTRASURF, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
981 }
982 if (aggressiveness >= 80)
983 {
984 appidSC->recheck_for_unknown_appid = 1;
985 appidSC->allow_port_wildcard_host_cache = 1;
986 }
987 }
988 else if (!(strcasecmp(conf_key, "psiphon_aggressiveness")))
989 {
990 int aggressiveness = atoi(conf_val);
991 _dpd.logMsg("AppId: psiphon_aggressiveness %d\n", aggressiveness);
992 if (aggressiveness >= 50)
993 {
994 appidSC->check_host_cache_unknown_ssl = 1;
995 appidSC->max_tp_flow_depth = 25;
996 appInfoEntryFlagSet(APP_ID_PSIPHON, APPINFO_FLAG_DEFER, pConfig);
997 appInfoEntryFlagSet(APP_ID_PSIPHON, APPINFO_FLAG_DEFER_PAYLOAD, pConfig);
998 }
999 if (aggressiveness >= 80)
1000 {
1001 appidSC->recheck_for_unknown_appid = 1;
1002 appidSC->allow_port_wildcard_host_cache = 1;
1003 }
1004 }
1005 else if (!(strcasecmp(conf_key, "multipayload_max_packets")))
1006 {
1007 appidSC->multipayload_max_packets = atoi(conf_val);
1008 _dpd.logMsg("AppId: Multipayload feature will scan up to %d packets.\n",
1009 appidSC->multipayload_max_packets);
1010 }
1011 }
1012 }
1013 fclose(config_file);
1014 }
1015