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 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.
9 //
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.
14 //
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 //--------------------------------------------------------------------------
19 
20 // app_info_table.h author Sourcefire Inc.
21 
22 #ifndef APP_INFO_TABLE_H
23 #define APP_INFO_TABLE_H
24 
25 #include <unordered_map>
26 #include <vector>
27 
28 #include "application_ids.h"
29 
30 #include "flow/flow.h"
31 #include "framework/counts.h"
32 #include "main/thread.h"
33 #include "target_based/snort_protocols.h"
34 #include "utils/util.h"
35 
36 #define APP_PRIORITY_DEFAULT 2
37 #define SF_APPID_MAX            40000
38 #define SF_APPID_BUILDIN_MAX    30000
39 #define SF_APPID_CSD_MIN        1000000
40 #define SF_APPID_DYNAMIC_MIN    2000000
41 
42 class AppIdConfig;
43 class ClientDetector;
44 class OdpContext;
45 class ServiceDetector;
46 
47 enum AppInfoFlags
48 {
49     APPINFO_FLAG_SERVICE_ADDITIONAL   = (1<<0),
50     APPINFO_FLAG_SERVICE_UDP_REVERSED = (1<<1),
51     APPINFO_FLAG_CLIENT_ADDITIONAL    = (1<<2),
52     APPINFO_FLAG_CLIENT_USER          = (1<<3),
53     APPINFO_FLAG_ACTIVE               = (1<<4),
54     APPINFO_FLAG_SSL_INSPECT          = (1<<5),
55     APPINFO_FLAG_REFERRED             = (1<<6),
56     APPINFO_FLAG_DEFER                = (1<<7),
57 
58     APPINFO_FLAG_IGNORE               = (1<<8),
59     APPINFO_FLAG_PERSISTENT           = (1<<9),
60     APPINFO_FLAG_TP_CLIENT            = (1<<10),
61     APPINFO_FLAG_DEFER_PAYLOAD        = (1<<11),
62     APPINFO_FLAG_CLIENT_DETECTOR_CALLBACK = (1<<12),
63     APPINFO_FLAG_SERVICE_DETECTOR_CALLBACK = (1<<13)
64 };
65 
66 class AppInfoTableEntry
67 {
68 public:
69     AppInfoTableEntry(AppId id, char* name);
70     AppInfoTableEntry(AppId id, char* name, AppId sid, AppId cid, AppId pid);
71     ~AppInfoTableEntry();
72 
73     AppId appId;
74     uint32_t serviceId;
75     uint32_t clientId;
76     uint32_t payloadId;
77     SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID;
78     uint32_t flags = 0;
79     uint32_t priority = APP_PRIORITY_DEFAULT;
80     ClientDetector* client_detector = nullptr;
81     ServiceDetector* service_detector = nullptr;
82     char* app_name = nullptr;
83     char* app_name_key = nullptr;
84 };
85 
86 typedef std::unordered_map<AppId, AppInfoTableEntry*> AppInfoTable;
87 typedef std::unordered_map<std::string, AppInfoTableEntry*> AppInfoNameTable;
88 
89 class AppInfoManager
90 {
91 public:
92     AppInfoTableEntry* get_app_info_entry(AppId);
93     AppInfoTableEntry* add_dynamic_app_entry(const char* app_name);
94     AppId get_appid_by_service_id(uint32_t);
95     AppId get_appid_by_client_id(uint32_t);
96     AppId get_appid_by_payload_id(uint32_t);
97     void set_app_info_active(AppId);
98     const char* get_app_name(AppId);
99     const char* get_app_name_key(AppId);
100     static char * strdup_to_lower(const char *app_name);
101     int32_t get_appid_by_name(const char* app_name);
102     bool configured();
103 
set_app_info_flags(AppId appId,unsigned flags)104     void set_app_info_flags(AppId appId, unsigned flags)
105     {
106         AppInfoTableEntry* entry = get_app_info_entry(appId);
107         if ( entry )
108             entry->flags |= flags;
109     }
110 
clear_app_info_flags(AppId appId,unsigned flags)111     void clear_app_info_flags(AppId appId, unsigned flags)
112     {
113         AppInfoTableEntry* entry = get_app_info_entry(appId);
114         if ( entry )
115             entry->flags &= (~flags);
116     }
117 
get_app_info_flags(AppId app_id,unsigned flags)118     unsigned get_app_info_flags(AppId app_id, unsigned flags)
119     {
120         AppInfoTableEntry* entry = get_app_info_entry(app_id);
121         return entry ? entry->flags & flags : 0;
122     }
123 
set_app_info_priority(AppId appId,unsigned priority)124     void set_app_info_priority(AppId appId, unsigned priority)
125     {
126         AppInfoTableEntry* entry = get_app_info_entry(appId);
127         if ( entry )
128             entry->priority |= priority;
129     }
130 
get_priority(AppId app_id)131     unsigned get_priority(AppId app_id)
132     {
133         AppInfoTableEntry* entry = get_app_info_entry(app_id);
134         return entry ? entry->priority : 0;
135     }
136 
137     void init_appid_info_table(const AppIdConfig&, snort::SnortConfig*, OdpContext& odp_ctxt);
138     void cleanup_appid_info_table();
139     void dump_app_info_table();
140     SnortProtocolId add_appid_protocol_reference(const char* protocol, snort::SnortConfig*);
141     void dump_appid_configurations(const std::string&) const;
142 
143 private:
144     void load_odp_config(OdpContext&, const char* path);
145     AppInfoTableEntry* get_app_info_entry(AppId appId, const AppInfoTable&);
146     bool is_existing_entry(AppInfoTableEntry* entry);
147     AppInfoTableEntry* find_app_info_by_name(const char* app_name);
148     bool add_entry_to_app_info_name_table(const char* app_name, AppInfoTableEntry* entry);
149     AppId get_static_app_info_entry(AppId appid);
150 
151     AppInfoTable app_info_table;
152     AppInfoTable app_info_service_table;
153     AppInfoTable app_info_client_table;
154     AppInfoTable app_info_payload_table;
155     AppInfoNameTable app_info_name_table;
156     AppId next_custom_appid = SF_APPID_DYNAMIC_MIN;
157     AppInfoTable custom_app_info_table;
158 };
159 
160 #endif
161 
162