1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2024 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2005-2013 Sourcefire, Inc.
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation. You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //--------------------------------------------------------------------------
20 // app_info_table.cc author Sourcefire Inc.
26 #include "app_info_table.h"
33 #include "log/messages.h"
34 #include "log/unified2.h"
35 #include "main/snort_config.h"
36 #include "target_based/snort_protocols.h"
37 #include "utils/util_cstring.h"
39 #include "appid_api.h"
40 #include "appid_config.h"
41 #include "appid_debug.h"
42 #include "appid_inspector.h"
43 #include "appid_peg_counts.h"
45 using namespace snort
;
47 #define MAX_TABLE_LINE_LEN 1024
48 static const int MIN_MAX_TP_FLOW_DEPTH
= 1;
49 static const int MAX_MAX_TP_FLOW_DEPTH
= 1000000;
50 static const int MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
= 1;
51 static const int MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
= 1000000;
52 static const int MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE
= 1;
53 static const int MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE
= 1000000;
54 static const char* APP_CONFIG_FILE
= "appid.conf";
55 static const char* USR_CONFIG_FILE
= "userappid.conf";
56 const char* APP_MAPPING_FILE
= "appMapping.data";
58 AppInfoTableEntry::AppInfoTableEntry(AppId id
, char* name
)
59 : appId(id
), serviceId(id
), clientId(id
), payloadId(id
), app_name(name
)
61 app_name_key
= AppInfoManager::strdup_to_lower(name
);
64 AppInfoTableEntry::AppInfoTableEntry(AppId id
, char* name
, AppId sid
, AppId cid
, AppId pid
) :
65 appId(id
), serviceId(sid
), clientId(cid
), payloadId(pid
), app_name(name
)
67 app_name_key
= AppInfoManager::strdup_to_lower(name
);
70 AppInfoTableEntry::~AppInfoTableEntry()
75 snort_free(app_name_key
);
78 bool AppInfoManager::is_existing_entry(AppInfoTableEntry
* entry
)
80 AppInfoNameTable::iterator app
;
82 app
= app_info_name_table
.find(entry
->app_name_key
);
83 return app
!= app_info_name_table
.end();
86 AppInfoTableEntry
* AppInfoManager::find_app_info_by_name(const char* app_name
)
88 AppInfoTableEntry
* entry
= nullptr;
89 AppInfoNameTable::iterator app
;
90 const char* search_name
= AppInfoManager::strdup_to_lower(app_name
);
92 app
= app_info_name_table
.find(search_name
);
93 if (app
!= app_info_name_table
.end())
96 snort_free((void*)search_name
);
100 bool AppInfoManager::add_entry_to_app_info_name_table(const char* app_name
,
101 AppInfoTableEntry
* entry
)
105 if (!is_existing_entry(entry
))
106 app_info_name_table
[app_name
] = entry
;
109 appid_log(nullptr, TRACE_WARNING_LEVEL
, "App name, \"%s\" is a duplicate entry will be shared by "
110 "each detector.\n", app_name
);
116 AppId
AppInfoManager::get_static_app_info_entry(AppId appid
)
118 if (appid
> 0 && appid
< SF_APPID_BUILDIN_MAX
)
120 if ((appid
>= SF_APPID_CSD_MIN
) &&
121 appid
< (SF_APPID_CSD_MIN
+ (SF_APPID_MAX
- SF_APPID_BUILDIN_MAX
)))
122 return (SF_APPID_BUILDIN_MAX
+ appid
- SF_APPID_CSD_MIN
);
126 char* AppInfoManager::strdup_to_lower(const char* source
)
128 char* dest
= snort_strdup(source
);
133 *lcd
= tolower(*lcd
);
139 bool AppInfoManager::configured()
141 return !app_info_table
.empty();
144 AppInfoTableEntry
* AppInfoManager::get_app_info_entry(AppId appId
,
145 const AppInfoTable
& lookup_table
)
148 AppInfoTable::const_iterator app
;
149 AppInfoTableEntry
* entry
= nullptr;
151 if ((tmp
= get_static_app_info_entry(appId
)))
153 app
= lookup_table
.find(tmp
);
154 if (app
!= lookup_table
.end())
159 app
= custom_app_info_table
.find(appId
);
160 if (app
!= custom_app_info_table
.end())
166 AppInfoTableEntry
* AppInfoManager::get_app_info_entry(AppId appId
)
168 return get_app_info_entry(appId
, app_info_table
);
171 AppInfoTableEntry
* AppInfoManager::add_dynamic_app_entry(const char* app_name
)
173 if (!app_name
|| strlen(app_name
) >= MAX_EVENT_APPNAME_LEN
)
175 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Appname invalid or too long: %s\n", app_name
);
179 AppInfoTableEntry
* entry
= find_app_info_by_name(app_name
);
182 entry
= new AppInfoTableEntry(next_custom_appid
++, snort_strdup(app_name
));
183 custom_app_info_table
[entry
->appId
] = entry
;
185 if (!add_entry_to_app_info_name_table(entry
->app_name_key
, entry
))
194 void AppInfoManager::cleanup_appid_info_table()
196 for (const auto& kv
: app_info_table
)
198 app_info_table
.erase(app_info_table
.begin(), app_info_table
.end());
200 for (const auto& kv
: custom_app_info_table
)
203 custom_app_info_table
.erase(custom_app_info_table
.begin(), custom_app_info_table
.end());
204 app_info_name_table
.erase(app_info_name_table
.begin(), app_info_name_table
.end());
207 void AppInfoManager::dump_app_info_table()
209 appid_log(nullptr, TRACE_INFO_LEVEL
, "Cisco provided detectors:\n");
210 for (auto& kv
: app_info_table
)
211 appid_log(nullptr, TRACE_INFO_LEVEL
, "%s\t%d\t%s\n", kv
.second
->app_name
, kv
.second
->appId
,
212 (kv
.second
->flags
& APPINFO_FLAG_ACTIVE
) ? "active" : "inactive");
214 appid_log(nullptr, TRACE_INFO_LEVEL
, "User provided detectors:\n");
215 for (auto& kv
: custom_app_info_table
)
216 appid_log(nullptr, TRACE_INFO_LEVEL
, "%s\t%d\t%s\n", kv
.second
->app_name
, kv
.second
->appId
,
217 (kv
.second
->flags
& APPINFO_FLAG_ACTIVE
) ? "active" : "inactive");
220 AppId
AppInfoManager::get_appid_by_service_id(uint32_t id
)
222 AppInfoTableEntry
* entry
= get_app_info_entry(id
, app_info_service_table
);
223 return entry
? entry
->appId
: APP_ID_NONE
;
226 AppId
AppInfoManager::get_appid_by_client_id(uint32_t id
)
228 AppInfoTableEntry
* entry
= get_app_info_entry(id
, app_info_client_table
);
229 return entry
? entry
->appId
: APP_ID_NONE
;
232 AppId
AppInfoManager::get_appid_by_payload_id(uint32_t id
)
234 AppInfoTableEntry
* entry
= get_app_info_entry(id
, app_info_payload_table
);
235 return entry
? entry
->appId
: APP_ID_NONE
;
238 const char* AppInfoManager::get_app_name(int32_t id
)
240 AppInfoTableEntry
* entry
= get_app_info_entry(id
);
241 return entry
? entry
->app_name
: nullptr;
244 const char* AppInfoManager::get_app_name_key(int32_t id
)
246 AppInfoTableEntry
* entry
= get_app_info_entry(id
);
247 return entry
? entry
->app_name_key
: nullptr;
250 AppId
AppInfoManager::get_appid_by_name(const char* app_name
)
252 AppInfoTableEntry
* entry
= find_app_info_by_name(app_name
);
253 return entry
? entry
->appId
: APP_ID_NONE
;
256 void AppInfoManager::set_app_info_active(AppId appId
)
258 if (appId
== APP_ID_NONE
)
261 AppInfoTableEntry
* entry
= get_app_info_entry(appId
);
263 entry
->flags
|= APPINFO_FLAG_ACTIVE
;
265 ParseWarning(WARN_PLUGINS
, "appid: no entry in %s for %d", APP_MAPPING_FILE
, appId
);
268 void AppInfoManager::load_odp_config(OdpContext
& odp_ctxt
, const char* path
)
270 char buf
[MAX_TABLE_LINE_LEN
];
272 const char* CONF_SEPARATORS
= "\t\n\r ";
274 FILE* config_file
= fopen(path
, "r");
275 if (config_file
== nullptr)
278 while (fgets(buf
, sizeof(buf
), config_file
) != nullptr)
283 char* token
= strtok_r(buf
, CONF_SEPARATORS
, &context
);
284 if (token
== nullptr)
286 ParseWarning(WARN_CONF
, "appid: No 'conf_type' value at line %s:%u\n", path
, line
);
289 char* conf_type
= token
;
291 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
292 if (token
== nullptr)
294 ParseWarning(WARN_CONF
, "appid: No 'conf_key' value at line %s:%u\n", path
, line
);
297 char* conf_key
= token
;
299 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
300 if (token
== nullptr)
302 ParseWarning(WARN_CONF
, "appid: No 'conf_val' value at line %s:%u\n", path
, line
);
305 char* conf_val
= token
;
307 /* APPID configurations are for anything else - currently we only have ssl_reinspect */
308 if (!(strcasecmp(conf_type
, "appid")))
310 if (!(strcasecmp(conf_key
, "max_tp_flow_depth")))
312 int max_tp_flow_depth
= atoi(conf_val
);
313 if (max_tp_flow_depth
< MIN_MAX_TP_FLOW_DEPTH
314 || max_tp_flow_depth
> MAX_MAX_TP_FLOW_DEPTH
)
316 ParseWarning(WARN_CONF
,
317 "appid: invalid max_tp_flow_depth %d, must be between %d and %d\n.",
318 max_tp_flow_depth
, MIN_MAX_TP_FLOW_DEPTH
, MAX_MAX_TP_FLOW_DEPTH
);
322 odp_ctxt
.max_tp_flow_depth
= max_tp_flow_depth
;
325 else if (!(strcasecmp(conf_key
, "host_port_app_cache_lookup_interval")))
327 int host_port_app_cache_lookup_interval
= atoi(conf_val
);
328 if (host_port_app_cache_lookup_interval
<
329 MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
||
330 host_port_app_cache_lookup_interval
>
331 MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
)
333 ParseWarning(WARN_CONF
,
334 "appid: invalid host_port_app_cache_lookup_interval %d, "
335 "must be between %d and %d\n.",
336 host_port_app_cache_lookup_interval
,
337 MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
,
338 MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
);
342 odp_ctxt
.host_port_app_cache_lookup_interval
=
343 host_port_app_cache_lookup_interval
;
346 else if (!(strcasecmp(conf_key
, "host_port_app_cache_lookup_range")))
348 int host_port_app_cache_lookup_range
= atoi(conf_val
);
349 if (host_port_app_cache_lookup_range
< MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE
350 || host_port_app_cache_lookup_range
> MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE
)
352 ParseWarning(WARN_CONF
,
353 "appid: invalid host_port_app_cache_lookup_range %d, "
354 "must be between %d and %d\n.", host_port_app_cache_lookup_range
,
355 MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE
,
356 MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE
);
360 odp_ctxt
.host_port_app_cache_lookup_range
= host_port_app_cache_lookup_range
;
363 else if (!(strcasecmp(conf_key
, "is_host_port_app_cache_runtime")))
365 if (!(strcasecmp(conf_val
, "enabled")))
367 odp_ctxt
.is_host_port_app_cache_runtime
= true;
370 else if (!(strcasecmp(conf_key
, "check_host_port_app_cache")))
372 if (!(strcasecmp(conf_val
, "enabled")))
374 odp_ctxt
.check_host_port_app_cache
= true;
377 else if (!(strcasecmp(conf_key
, "check_host_cache_unknown_ssl")))
379 if (!(strcasecmp(conf_val
, "enabled")))
381 odp_ctxt
.check_host_cache_unknown_ssl
= true;
384 else if (!(strcasecmp(conf_key
, "allow_port_wildcard_host_cache")))
386 if (!(strcasecmp(conf_val
, "enabled")))
388 odp_ctxt
.allow_port_wildcard_host_cache
= true;
391 else if (!(strcasecmp(conf_key
, "recheck_for_portservice_appid")))
393 if (!(strcasecmp(conf_val
, "enabled")))
395 odp_ctxt
.recheck_for_portservice_appid
= true;
398 else if (!(strcasecmp(conf_key
, "bittorrent_aggressiveness")))
400 int aggressiveness
= atoi(conf_val
);
401 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: bittorrent_aggressiveness %d\n", aggressiveness
);
402 if (aggressiveness
>= 50)
404 odp_ctxt
.host_port_app_cache_lookup_interval
= 5;
405 odp_ctxt
.recheck_for_portservice_appid
= true;
406 set_app_info_flags(APP_ID_BITTORRENT
, APPINFO_FLAG_DEFER
);
407 set_app_info_flags(APP_ID_BITTORRENT
, APPINFO_FLAG_DEFER_PAYLOAD
);
408 odp_ctxt
.max_tp_flow_depth
= 25;
409 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: host_port_app_cache_lookup_interval %d\n",
410 odp_ctxt
.host_port_app_cache_lookup_interval
);
411 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: recheck_for_portservice_appid enabled\n");
412 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_to_thirdparty %d\n", APP_ID_BITTORRENT
);
413 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_payload_to_thirdparty %d\n", APP_ID_BITTORRENT
);
414 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: max_tp_flow_depth %d\n", odp_ctxt
.max_tp_flow_depth
);
416 if (aggressiveness
>= 80)
418 odp_ctxt
.allow_port_wildcard_host_cache
= true;
419 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: allow_port_wildcard_host_cache enabled\n");
422 else if (!(strcasecmp(conf_key
, "ultrasurf_aggressiveness")))
424 int aggressiveness
= atoi(conf_val
);
425 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: ultrasurf_aggressiveness %d\n", aggressiveness
);
426 if (aggressiveness
>= 50)
428 odp_ctxt
.check_host_cache_unknown_ssl
= true;
429 set_app_info_flags(APP_ID_ULTRASURF
, APPINFO_FLAG_DEFER
);
430 set_app_info_flags(APP_ID_ULTRASURF
, APPINFO_FLAG_DEFER_PAYLOAD
);
431 odp_ctxt
.max_tp_flow_depth
= 25;
432 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: check_host_cache_unknown_ssl enabled\n");
433 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_to_thirdparty %d\n", APP_ID_ULTRASURF
);
434 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_payload_to_thirdparty %d\n", APP_ID_ULTRASURF
);
435 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: max_tp_flow_depth %d\n", odp_ctxt
.max_tp_flow_depth
);
437 if (aggressiveness
>= 80)
439 odp_ctxt
.allow_port_wildcard_host_cache
= true;
440 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: allow_port_wildcard_host_cache enabled\n");
443 else if (!(strcasecmp(conf_key
, "psiphon_aggressiveness")))
445 int aggressiveness
= atoi(conf_val
);
446 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: psiphon_aggressiveness %d\n", aggressiveness
);
447 if (aggressiveness
>= 50)
449 odp_ctxt
.check_host_cache_unknown_ssl
= true;
450 set_app_info_flags(APP_ID_PSIPHON
, APPINFO_FLAG_DEFER
);
451 set_app_info_flags(APP_ID_PSIPHON
, APPINFO_FLAG_DEFER_PAYLOAD
);
452 odp_ctxt
.max_tp_flow_depth
= 25;
453 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: check_host_cache_unknown_ssl enabled\n");
454 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_to_thirdparty %d\n", APP_ID_PSIPHON
);
455 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: defer_payload_to_thirdparty %d\n", APP_ID_PSIPHON
);
456 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: max_tp_flow_depth %d\n", odp_ctxt
.max_tp_flow_depth
);
458 if (aggressiveness
>= 80)
460 odp_ctxt
.allow_port_wildcard_host_cache
= true;
461 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: allow_port_wildcard_host_cache enabled\n");
464 else if (!(strcasecmp(conf_key
, "tp_allow_probes")))
466 if (!(strcasecmp(conf_val
, "enabled")))
468 odp_ctxt
.tp_allow_probes
= true;
471 else if (!(strcasecmp(conf_key
, "tp_client_app")))
473 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_TP_CLIENT
);
475 else if (!(strcasecmp(conf_key
, "ssl_reinspect")))
477 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_SSL_INSPECT
);
479 else if (!(strcasecmp(conf_key
, "defer_to_thirdparty")))
481 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_DEFER
);
483 else if (!(strcasecmp(conf_key
, "defer_payload_to_thirdparty")))
485 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_DEFER_PAYLOAD
);
487 else if (!(strcasecmp(conf_key
, "chp_userid")))
489 if (!(strcasecmp(conf_val
, "disabled")))
491 odp_ctxt
.chp_userid_disabled
= true;
495 else if (!(strcasecmp(conf_key
, "chp_body_collection")))
497 if (!(strcasecmp(conf_val
, "disabled")))
499 odp_ctxt
.chp_body_collection_disabled
= true;
503 else if (!(strcasecmp(conf_key
, "ftp_userid")))
505 if (!(strcasecmp(conf_val
, "disabled")))
507 odp_ctxt
.ftp_userid_disabled
= true;
511 else if (!(strcasecmp(conf_key
, "max_bytes_before_service_fail")))
513 uint64_t max_bytes_before_service_fail
= atoi(conf_val
);
514 if (max_bytes_before_service_fail
< MIN_MAX_BYTES_BEFORE_SERVICE_FAIL
)
516 appid_log(nullptr, TRACE_WARNING_LEVEL
, "appid: invalid max_bytes_before_service_fail "
517 "%" PRIu64
" must be greater than %u.\n", max_bytes_before_service_fail
,
518 MIN_MAX_BYTES_BEFORE_SERVICE_FAIL
);
522 odp_ctxt
.max_bytes_before_service_fail
= max_bytes_before_service_fail
;
525 else if (!(strcasecmp(conf_key
, "max_packet_before_service_fail")))
527 uint16_t max_packet_before_service_fail
= atoi(conf_val
);
528 if (max_packet_before_service_fail
< MIN_MAX_PKTS_BEFORE_SERVICE_FAIL
)
530 appid_log(nullptr, TRACE_WARNING_LEVEL
, "appid: invalid max_packet_before_service_fail "
531 "%" PRIu16
", must be greater than %u.\n", max_packet_before_service_fail
,
532 MIN_MAX_PKTS_BEFORE_SERVICE_FAIL
);
536 odp_ctxt
.max_packet_before_service_fail
= max_packet_before_service_fail
;
539 else if (!(strcasecmp(conf_key
, "max_packet_service_fail_ignore_bytes")))
541 uint16_t max_packet_service_fail_ignore_bytes
= atoi(conf_val
);
542 if (max_packet_service_fail_ignore_bytes
<
543 MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES
)
545 appid_log(nullptr, TRACE_WARNING_LEVEL
, "appid: invalid max_packet_service_fail_ignore_bytes"
546 "%" PRIu16
", must be greater than %u.\n",
547 max_packet_service_fail_ignore_bytes
,
548 MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES
);
552 odp_ctxt
.max_packet_service_fail_ignore_bytes
=
553 max_packet_service_fail_ignore_bytes
;
556 /* App Priority bit set*/
557 else if (!(strcasecmp(conf_key
, "app_priority")))
560 temp_appid
= strtol(conf_val
, nullptr, 10);
561 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
562 if (token
== nullptr)
564 ParseWarning(WARN_CONF
, "appid: Could not read app_priority at line %u\n", line
);
569 temp_val
= strtol(conf_val
, nullptr, 10);
570 set_app_info_priority (temp_appid
, temp_val
);
572 else if (!(strcasecmp(conf_key
, "referred_appId")))
574 if (!(strcasecmp(conf_val
, "disabled")))
576 odp_ctxt
.referred_appId_disabled
= true;
579 else if (!odp_ctxt
.referred_appId_disabled
)
581 char referred_app_list
[4096];
582 int referred_app_index
= safe_snprintf(referred_app_list
, 4096, "%d ",
584 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_REFERRED
);
586 while ((token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
)) != nullptr)
588 AppId id
= atoi(token
);
589 referred_app_index
+= safe_snprintf(referred_app_list
+ referred_app_index
,
590 sizeof(referred_app_list
) - referred_app_index
, "%d ", id
);
591 set_app_info_flags(id
, APPINFO_FLAG_REFERRED
);
595 else if (!(strcasecmp(conf_key
, "rtmp_max_packets")))
597 odp_ctxt
.rtmp_max_packets
= atoi(conf_val
);
599 else if (!(strcasecmp(conf_key
, "mdns_user_report")))
601 odp_ctxt
.mdns_user_reporting
= atoi(conf_val
) ? true : false;
603 else if (!(strcasecmp(conf_key
, "dns_host_report")))
605 odp_ctxt
.dns_host_reporting
= atoi(conf_val
) ? true : false;
607 else if (!(strcasecmp(conf_key
, "chp_body_max_bytes")))
609 odp_ctxt
.chp_body_collection_max
= atoi(conf_val
);
611 else if (!(strcasecmp(conf_key
, "ignore_thirdparty_appid")))
613 set_app_info_flags(atoi(conf_val
), APPINFO_FLAG_IGNORE
);
615 else if (!(strcasecmp(conf_key
, "eve_http_client")))
617 odp_ctxt
.eve_http_client
= atoi(conf_val
) ? true : false;
620 ParseWarning(WARN_CONF
, "appid: unsupported configuration: %s\n", conf_key
);
627 void AppInfoManager::dump_appid_configurations(const std::string
& file_path
) const
629 std::ifstream
conf_file(file_path
);
630 if (!conf_file
.is_open())
633 appid_log(nullptr, TRACE_INFO_LEVEL
, "AppId: Configuration file %s\n", file_path
.c_str());
635 while (getline(conf_file
, line
))
636 appid_log(nullptr, TRACE_INFO_LEVEL
, "%s\n", line
.c_str());
641 SnortProtocolId
AppInfoManager::add_appid_protocol_reference(const char* protocol
,
644 SnortProtocolId snort_protocol_id
= sc
->proto_ref
->add(protocol
);
645 return snort_protocol_id
;
648 void AppInfoManager::init_appid_info_table(const AppIdConfig
& config
,
649 SnortConfig
* sc
, OdpContext
& odp_ctxt
)
651 if (!config
.app_detector_dir
)
653 return; // no lua detectors, no rule support, already warned
656 char filepath
[PATH_MAX
];
657 snprintf(filepath
, sizeof(filepath
), "%s/odp/%s", config
.app_detector_dir
,
660 FILE* tableFile
= fopen(filepath
, "r");
664 ParseError("appid: could not open %s", filepath
);
668 char buf
[MAX_TABLE_LINE_LEN
];
669 const char* CONF_SEPARATORS
= "\t\n\r";
670 while (fgets(buf
, sizeof(buf
), tableFile
))
673 uint32_t client_id
, service_id
, payload_id
;
677 const char* token
= strtok_r(buf
, CONF_SEPARATORS
, &context
);
680 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Could not read id for AppId\n");
683 app_id
= strtol(token
, nullptr, 10);
685 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
688 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Could not read app_name. Line %s\n", buf
);
691 app_name
= snort_strdup(token
);
693 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
696 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Could not read service id for AppId\n");
697 snort_free(app_name
);
700 service_id
= strtoul(token
, nullptr, 10);
702 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
705 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Could not read client id for AppId\n");
706 snort_free(app_name
);
709 client_id
= strtoul(token
, nullptr, 10);
711 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
714 appid_log(nullptr, TRACE_ERROR_LEVEL
, "Could not read payload id for AppId\n");
715 snort_free(app_name
);
718 payload_id
= strtoul(token
, nullptr, 10);
720 AppInfoTableEntry
* entry
= new AppInfoTableEntry(app_id
, app_name
, service_id
,
721 client_id
, payload_id
);
723 /* snort service key, if it exists */
724 token
= strtok_r(nullptr, CONF_SEPARATORS
, &context
);
726 // FIXIT-RC: Sometimes the token is "~". Should we ignore those?
728 entry
->snort_protocol_id
= add_appid_protocol_reference(token
, sc
);
730 if (!add_entry_to_app_info_name_table(entry
->app_name_key
, entry
))
734 if ((app_id
= get_static_app_info_entry(entry
->appId
)))
736 app_info_table
[app_id
] = entry
;
737 AppIdPegCounts::add_app_peg_info(entry
->app_name_key
, app_id
);
739 if ((app_id
= get_static_app_info_entry(entry
->serviceId
)))
740 app_info_service_table
[app_id
] = entry
;
741 if ((app_id
= get_static_app_info_entry(entry
->clientId
)))
742 app_info_client_table
[app_id
] = entry
;
743 if ((app_id
= get_static_app_info_entry(entry
->payloadId
)))
744 app_info_payload_table
[app_id
] = entry
;
749 snprintf(filepath
, sizeof(filepath
), "%s/odp/%s", config
.app_detector_dir
,
751 load_odp_config(odp_ctxt
, filepath
);
752 snprintf(filepath
, sizeof(filepath
), "%s/custom/%s", config
.app_detector_dir
,
754 if (access (filepath
, F_OK
))
755 snprintf(filepath
, sizeof(filepath
), "%s/../%s", config
.app_detector_dir
,
757 load_odp_config(odp_ctxt
, filepath
);