00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2016-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018
00019 // appid_inspector.cc author davis mcpherson <davmcphe@cisco.com>
00020 // Created on: May 10, 2016
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025
00026 #include "appid_inspector.h"
00027
00028 #include <openssl/crypto.h>
00029
00030 #include "appid_stats.h"
00031 #include "appid_session.h"
00032 #include "appid_discovery.h"
00033 #include "app_forecast.h"
00034 #include "host_port_app_cache.h"
00035 #include "lua_detector_module.h"
00036 #include "appid_http_event_handler.h"
00037 #include "thirdparty_appid_utils.h"
00038 #include "client_plugins/client_discovery.h"
00039 #include "service_plugins/service_discovery.h"
00040 #include "service_plugins/service_ssl.h"
00041 #include "detector_plugins/detector_dns.h"
00042 #include "detector_plugins/http_url_patterns.h"
00043 #include "detector_plugins/detector_sip.h"
00044 #include "detector_plugins/detector_pattern.h"
00045 #include "log/messages.h"
00046 #include "log/packet_tracer.h"
00047 #include "main/snort_config.h"
00048 #include "managers/inspector_manager.h"
00049 #include "managers/module_manager.h"
00050 #include "protocols/packet.h"
00051 #include "profiler/profiler.h"
00052 #include "target_based/snort_protocols.h"
00053
00054 #include "main/snort_debug.h"
00055
00056 static THREAD_LOCAL AppIdStatistics* appid_stats_manager = nullptr;
00057
00058 // FIXIT-L - appid cleans up openssl now as it is the primary (only) user... eventually this
00059 // should probably be done outside of appid
00060 static void openssl_cleanup()
00061 {
00062 CRYPTO_cleanup_all_ex_data();
00063 }
00064
00065 static void add_appid_to_packet_trace(Flow* flow)
00066 {
00067 AppIdSession* session = appid_api.get_appid_session(flow);
00068 if (session)
00069 {
00070 AppId service_id, client_id, payload_id, misc_id;
00071 const char *service_app_name, *client_app_name, *payload_app_name, *misc_name;
00072 session->get_application_ids(service_id, client_id, payload_id, misc_id);
00073 service_app_name = appid_api.get_application_name(service_id);
00074 client_app_name = appid_api.get_application_name(client_id);
00075 payload_app_name = appid_api.get_application_name(payload_id);
00076 misc_name = appid_api.get_application_name(misc_id);
00077
00078 PacketTracer::log("AppID: service: %s(%d), client: %s(%d), payload: %s(%d), misc: %s(%d)\n",
00079 (service_app_name ? service_app_name : ""), service_id,
00080 (client_app_name ? client_app_name : ""), client_id,
00081 (payload_app_name ? payload_app_name : ""), payload_id,
00082 (misc_name ? misc_name : ""), misc_id);
00083 }
00084 }
00085
00086 AppIdInspector::AppIdInspector(AppIdModule& mod)
00087 {
00088 config = mod.get_data();
00089 }
00090
00091 AppIdInspector::~AppIdInspector()
00092 {
00093 delete active_config;
00094 delete config;
00095 }
00096
00097 AppIdInspector* AppIdInspector::get_inspector()
00098 {
00099 return (AppIdInspector*)InspectorManager::get_inspector(MOD_NAME);
00100 }
00101
00102 AppIdConfig* AppIdInspector::get_appid_config()
00103 {
00104 return active_config;
00105 }
00106
00107 AppIdStatistics* AppIdInspector::get_stats_manager()
00108 {
00109 return appid_stats_manager;
00110 }
00111
00112 int16_t AppIdInspector::add_appid_protocol_reference(const char* protocol)
00113 {
00114 static std::mutex apr_mutex;
00115
00116 apr_mutex.lock();
00117 int16_t id = snort_conf->proto_ref->add(protocol);
00118 apr_mutex.unlock();
00119 return id;
00120 }
00121
00122 bool AppIdInspector::configure(SnortConfig*)
00123 {
00124 assert(!active_config);
00125
00126 active_config = new AppIdConfig( ( AppIdModuleConfig* )config);
00127
00128 get_data_bus().subscribe(HTTP_REQUEST_HEADER_EVENT_KEY, new HttpEventHandler(
00129 HttpEventHandler::REQUEST_EVENT));
00130 get_data_bus().subscribe(HTTP_RESPONSE_HEADER_EVENT_KEY, new HttpEventHandler(
00131 HttpEventHandler::RESPONSE_EVENT));
00132
00133 my_seh = SipEventHandler::create();
00134 my_seh->subscribe();
00135
00136 active_config->init_appid();
00137 return true;
00138
00139 // FIXIT-M some of this stuff may be needed in some fashion...
00140 #ifdef REMOVED_WHILE_NOT_IN_USE
00141 _dpd.registerGeAppId(getOpenAppId);
00142 _dpd.registerSslAppIdLookup(sslAppGroupIdLookup);
00143 #endif
00144 }
00145
00146 void AppIdInspector::show(SnortConfig*)
00147 {
00148 LogMessage("AppId Configuration\n");
00149
00150 LogMessage(" Detector Path: %s\n", config->app_detector_dir);
00151 LogMessage(" appStats Logging: %s\n", config->stats_logging_enabled ? "enabled" :
00152 "disabled");
00153 LogMessage(" appStats Period: %lu secs\n", config->app_stats_period);
00154 LogMessage(" appStats Rollover Size: %lu bytes\n",
00155 config->app_stats_rollover_size);
00156 LogMessage(" appStats Rollover time: %lu secs\n",
00157 config->app_stats_rollover_time);
00158 LogMessage("\n");
00159 }
00160
00161 void AppIdInspector::tinit()
00162 {
00163 appid_stats_manager = AppIdStatistics::initialize_manager(*config);
00164 HostPortCache::initialize();
00165 AppIdServiceState::initialize();
00166 init_appid_forecast();
00167 HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance();
00168 AppIdDiscovery::initialize_plugins();
00169 init_length_app_cache();
00170 LuaDetectorManager::initialize(*active_config);
00171 PatternServiceDetector::finalize_service_port_patterns();
00172 PatternClientDetector::finalize_client_port_patterns();
00173 AppIdDiscovery::finalize_plugins();
00174 http_matchers->finalize();
00175 SipUdpClientDetector::finalize_sip_ua();
00176 ssl_detector_process_patterns();
00177 dns_host_detector_process_patterns();
00178 }
00179
00180 void AppIdInspector::tterm()
00181 {
00182 delete appid_stats_manager;
00183 HostPortCache::terminate();
00184 clean_appid_forecast();
00185 service_dns_host_clean();
00186 service_ssl_clean();
00187 free_length_app_cache();
00188
00189 AppIdServiceState::clean();
00190 LuaDetectorManager::terminate();
00191 AppIdDiscovery::release_plugins();
00192 delete HttpPatternMatchers::get_instance();
00193 }
00194
00195 void AppIdInspector::eval(Packet* p)
00196 {
00197 Profile profile(appidPerfStats);
00198
00199
00200 new_invoked_inspector(1, p, 0);
00201
00202
00203 AppIdPegCounts::inc_disco_peg(AppIdPegCounts::DiscoveryPegs::PACKETS);
00204 if (p->flow)
00205 {
00206 AppIdDiscovery::do_application_discovery(p);
00207 if (PacketTracer::get_enable())
00208 add_appid_to_packet_trace(p->flow);
00209 }
00210 else
00211 AppIdPegCounts::inc_disco_peg(AppIdPegCounts::DiscoveryPegs::IGNORED_PACKETS);
00212 }
00213
00214 //-------------------------------------------------------------------------
00215 // api stuff
00216 //-------------------------------------------------------------------------
00217
00218 static Module* mod_ctor()
00219 {
00220 return new AppIdModule;
00221 }
00222
00223 static void mod_dtor(Module* m)
00224 {
00225 delete m;
00226 }
00227
00228 static void appid_inspector_pinit()
00229 {
00230 AppIdSession::init();
00231 }
00232
00233 static void appid_inspector_pterm()
00234 {
00235 openssl_cleanup();
00236 }
00237
00238 static void appid_inspector_tinit()
00239 {
00240 AppIdPegCounts::init_pegs();
00241 }
00242
00243 static void appid_inspector_tterm()
00244 {
00245 AppIdPegCounts::cleanup_pegs();
00246 }
00247
00248 static Inspector* appid_inspector_ctor(Module* m)
00249 {
00250 assert(m);
00251 return new AppIdInspector((AppIdModule&)*m);
00252 }
00253
00254 static void appid_inspector_dtor(Inspector* p)
00255 {
00256 delete p;
00257 }
00258
00259 const InspectApi appid_inspector_api =
00260 {
00261 {
00262 PT_INSPECTOR,
00263 sizeof(InspectApi),
00264 INSAPI_VERSION,
00265 0,
00266 API_RESERVED,
00267 API_OPTIONS,
00268 MOD_NAME,
00269 MOD_HELP,
00270 mod_ctor,
00271 mod_dtor
00272 },
00273 IT_NETWORK,
00274 (uint16_t)PktType::ANY_IP,
00275 nullptr, // buffers
00276 nullptr, // service
00277 appid_inspector_pinit,
00278 appid_inspector_pterm,
00279 appid_inspector_tinit,
00280 appid_inspector_tterm,
00281 appid_inspector_ctor,
00282 appid_inspector_dtor,
00283 nullptr, // ssn
00284 nullptr // reset
00285 };
00286
00287 extern const BaseApi* ips_appid;
00288
00289 #ifdef BUILDING_SO
00290 SO_PUBLIC const BaseApi* snort_plugins[] =
00291 #else
00292 const BaseApi* nin_appid[] =
00293 #endif
00294 {
00295 &appid_inspector_api.base,
00296 ips_appid,
00297 nullptr
00298 };
00299
00300 // @returns 1 if some appid is found, 0 otherwise.
00301 //int sslAppGroupIdLookup(void* ssnptr, const char* serverName, const char* commonName,
00302 // AppId* service_id, AppId* client_id, AppId* payload_id)
00303 int sslAppGroupIdLookup(void*, const char*, const char*, AppId*, AppId*, AppId*)
00304 {
00305 // FIXIT-M determine need and proper location for this code when support for ssl is implemented
00306 // also once this is done the call to get the appid config should change to use the
00307 // config assigned to the flow being processed
00308 #ifdef REMOVED_WHILE_NOT_IN_USE
00309 AppIdSession* asd;
00310 *service_id = *client_id = *payload_id = APP_ID_NONE;
00311
00312 if (commonName)
00313 {
00314 ssl_scan_cname((const uint8_t*)commonName, strlen(commonName), client_id, payload_app_id,
00315 &AppIdInspector::get_inspector()->get_appid_config()->serviceSslConfig);
00316 }
00317 if (serverName)
00318 {
00319 ssl_scan_hostname((const uint8_t*)serverName, strlen(serverName), client_id,
00320 payload_app_id,
00321 &AppIdInspector::get_inspector()->get_appid_config()->serviceSslConfig);
00322 }
00323
00324 if (ssnptr && (asd = appid_api.get_appid_session(ssnptr)))
00325 {
00326 *service_id = pick_service_app_id(asd);
00327 if (*client_id == APP_ID_NONE)
00328 {
00329 *client_id = pick_client_app_id(asd);
00330 }
00331 if (*payload_id == APP_ID_NONE)
00332 {
00333 *payload_id = pick_payload_app_id(asd);
00334 }
00335 }
00336 if (*service_id != APP_ID_NONE ||
00337 *client_id != APP_ID_NONE ||
00338 *payload_id != APP_ID_NONE)
00339 {
00340 return 1;
00341 }
00342 #endif
00343
00344 return 0;
00345 }
00346
00347 AppId getOpenAppId(Flow* flow)
00348 {
00349 assert(flow);
00350 AppIdSession* asd = appid_api.get_appid_session(flow);
00351 return asd->payload.get_id();
00352 }
END OF CODE