#include "appid_http_session.h"
#include "appid_inspector.h"
#include "appid_session.h"
+#include "detector_plugins/detector_imap.h"
+#include "detector_plugins/detector_kerberos.h"
#include "detector_plugins/detector_pattern.h"
+#include "detector_plugins/detector_pop3.h"
+#include "detector_plugins/detector_smtp.h"
#include "host_port_app_cache.h"
#include "main/snort_config.h"
#include "log/messages.h"
{
odp_ctxt->get_client_disco_mgr().initialize(inspector);
odp_ctxt->get_service_disco_mgr().initialize(inspector);
+ odp_ctxt->set_client_and_service_detectors();
+
odp_thread_local_ctxt->initialize(sc, *this, true);
odp_ctxt->initialize(inspector);
alpn_matchers.reload_patterns();
}
+void OdpContext::set_client_and_service_detectors()
+{
+ Pop3ServiceDetector* s_pop = (Pop3ServiceDetector*) service_disco_mgr.get_service_detector("pop3");
+ Pop3ClientDetector* c_pop = (Pop3ClientDetector*) client_disco_mgr.get_client_detector("pop3");
+ if (!s_pop or !c_pop)
+ {
+ ErrorMessage("appid: failed to initialize pop3 detector\n");
+ return;
+ }
+ s_pop->set_client_detector(c_pop);
+ c_pop->set_service_detector(s_pop);
+
+ KerberosServiceDetector* s_krb = (KerberosServiceDetector*) service_disco_mgr.get_service_detector("kerberos");
+ KerberosClientDetector* c_krb = (KerberosClientDetector*) client_disco_mgr.get_client_detector("kerberos");
+ if (!s_krb or !c_krb)
+ {
+ ErrorMessage("appid: failed to initialize kerberos detector\n");
+ return;
+ }
+ s_krb->set_client_detector(c_krb);
+ c_krb->set_service_detector(s_krb);
+
+ SmtpServiceDetector* s_smtp = (SmtpServiceDetector*) service_disco_mgr.get_service_detector("smtp");
+ SmtpClientDetector* c_smtp = (SmtpClientDetector*) client_disco_mgr.get_client_detector("SMTP");
+ if (!s_smtp or !c_smtp)
+ {
+ ErrorMessage("appid: failed to initialize smtp detector\n");
+ return;
+ }
+ s_smtp->set_client_detector(c_smtp);
+
+ ImapServiceDetector* s_imap = (ImapServiceDetector*) service_disco_mgr.get_service_detector("IMAP");
+ ImapClientDetector* c_imap = (ImapClientDetector*) client_disco_mgr.get_client_detector("IMAP");
+ if (!s_imap or !c_imap)
+ {
+ ErrorMessage("appid: failed to initialize imap detector\n");
+ return;
+ }
+ s_imap->set_client_detector(c_imap);
+}
+
+SipServiceDetector* OdpContext::get_sip_service_detector()
+{
+ SipServiceDetector* s_sip = (SipServiceDetector*) service_disco_mgr.get_service_detector("sip");
+ if (!s_sip)
+ ErrorMessage("appid: failed to initialize sip service detector\n");
+ return s_sip;
+}
+
+SipUdpClientDetector* OdpContext::get_sip_client_detector()
+{
+ SipUdpClientDetector* c_sip = (SipUdpClientDetector*) client_disco_mgr.get_client_detector("SIP");
+ if (!c_sip)
+ ErrorMessage("appid: failed to initialize sip client detector\n");
+ return c_sip;
+}
+
void OdpContext::add_port_service_id(IpProtocol proto, uint16_t port, AppId appid)
{
if (proto == IpProtocol::TCP)
class AppIdInspector;
class PatternClientDetector;
class PatternServiceDetector;
+class SipUdpClientDetector;
+class SipServiceDetector;
class AppIdConfig
{
void add_protocol_service_id(IpProtocol, AppId);
AppId get_port_service_id(IpProtocol, uint16_t);
AppId get_protocol_service_id(IpProtocol);
+ void set_client_and_service_detectors();
+ SipUdpClientDetector* get_sip_client_detector();
+ SipServiceDetector* get_sip_service_detector();
private:
AppInfoManager app_info_mgr;
OdpContext& odp_ctxt = ctxt.get_odp_ctxt();
odp_ctxt.get_client_disco_mgr().initialize(*inspector);
odp_ctxt.get_service_disco_mgr().initialize(*inspector);
+ odp_ctxt.set_client_and_service_detectors();
+
odp_thread_local_ctxt->initialize(SnortConfig::get_conf(), ctxt, true, true);
odp_ctxt.initialize(*inspector);
return tcp_pattern_count + udp_pattern_count;
}
+ClientDetector* ClientDiscovery::get_client_detector(const std::string& name) const
+{
+ auto det = tcp_detectors.find(name);
+ if (det != tcp_detectors.end())
+ return (ClientDetector*) det->second;
+
+ return nullptr;
+}
+
/*
* Callback function for string search
*
unsigned get_pattern_count();
bool do_client_discovery(AppIdSession&, snort::Packet*,
AppidSessionDirection direction, AppidChangeBits& change_bits);
+ ClientDetector* get_client_detector(const std::string&) const;
private:
void exec_client_detectors(AppIdSession&, snort::Packet*,
int need_continue;
};
-static ImapClientDetector* imap_client_detector;
-
static int isImapTagChar(uint8_t tag)
{
/* Per RFC 3501
ImapClientDetector::ImapClientDetector(ClientDiscovery* cdm)
{
- imap_client_detector = this;
handler = cdm;
name = "IMAP";
proto = IpProtocol::TCP;
int ImapServiceDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!imap_client_detector)
+ return APPID_NOMATCH;
+
ImapDetectorData* dd;
ImapServiceData* id;
ImapServiceDetector(ServiceDiscovery*);
int validate(AppIdDiscoveryArgs&) override;
+ void set_client_detector(ImapClientDetector* c)
+ {
+ imap_client_detector = c;
+ }
+
+private:
+ ImapClientDetector* imap_client_detector = nullptr;
};
#endif
#define TGS_REP_MSG_TYPE 0x0d
#define ERROR_MSG_TYPE 0x1e
-static KerberosClientDetector* krb_client_detector;
-static KerberosServiceDetector* krb_service_detector;
-
-static int krb_walk_server_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
+int KerberosServiceDetector::krb_walk_server_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
AppIdSession& asd, Packet* pkt, const AppidSessionDirection dir,
const char* reqCname, AppidChangeBits& change_bits)
{
/*end of server response message */
if (krbs->flags & KRB_FLAG_SERVICE_DETECTED)
if (!asd.is_service_detected() && pkt)
- krb_service_detector->add_service(change_bits, asd, pkt, dir, APP_ID_KERBEROS,
- nullptr, krbs->ver, nullptr);
+ this->add_service(change_bits, asd, pkt, dir, APP_ID_KERBEROS, nullptr, krbs->ver, nullptr);
if (krbs->flags & KRB_FLAG_AUTH_FAILED)
{
if (krb_client_detector->failed_login
&& ((krbs->flags & KRB_FLAG_USER_DETECTED) || reqCname))
{
- krb_service_detector->add_user(asd,
- (krbs->flags & KRB_FLAG_USER_DETECTED) ? krbs->cname : reqCname,
+ this->add_user(asd, (krbs->flags & KRB_FLAG_USER_DETECTED) ? krbs->cname : reqCname,
APP_ID_LDAP, false, change_bits);
}
}
else if (krbs->flags & KRB_FLAG_USER_DETECTED)
- krb_service_detector->add_user(asd, krbs->cname, APP_ID_LDAP, true, change_bits);
+ this->add_user(asd, krbs->cname, APP_ID_LDAP, true, change_bits);
krbs->flags = 0;
}
KerberosServiceDetector::KerberosServiceDetector(ServiceDiscovery* sd)
{
- krb_service_detector = this;
handler = sd;
name = "kerberos";
proto = IpProtocol::TCP;
int KerberosServiceDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!krb_client_detector)
+ return APPID_NOMATCH;
+
KerberosDetectorData* fd;
const uint8_t* s = args.data;
const uint8_t* end = (args.data + args.size);
KerberosClientDetector::KerberosClientDetector(ClientDiscovery* cdm)
{
- krb_client_detector = this;
handler = cdm;
name = "kerberos";
proto = IpProtocol::TCP;
krbs->tag = *s;
if (krbs->tag == 0xa4
&& (krbs->msg_type == AS_REQ_MSG_TYPE || krbs->msg_type == TGS_REQ_MSG_TYPE)
- && krb_client_detector->failed_login)
+ && this->failed_login)
{
krbs->next_state = KRB_STATE_REQBODY_SEQ;
}
int KerberosClientDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!krb_service_detector)
+ return APPID_NOMATCH;
+
const uint8_t* s = args.data;
const uint8_t* end = (args.data + args.size);
return APPID_SUCCESS;
}
}
- else if (krb_walk_server_packet(&fd->svr_state, s, end, args.asd, nullptr, args.dir,
+ else if (krb_service_detector->krb_walk_server_packet(&fd->svr_state, s, end, args.asd, nullptr, args.dir,
fd->clnt_state.cname, args.change_bits) == KRB_FAILED)
{
args.asd.clear_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
#ifndef DETECTOR_KERBEROS_H
#define DETECTOR_KERBEROS_H
+#include "protocols/packet.h"
#include "client_plugins/client_detector.h"
#include "service_plugins/service_detector.h"
+namespace snort
+{
+struct Packet;
+}
+
struct KRBState;
struct KerberosDetectorData;
+class KerberosServiceDetector;
class KerberosClientDetector : public ClientDetector
{
int validate(AppIdDiscoveryArgs&) override;
KerberosDetectorData* get_common_data(AppIdSession&);
+ void set_service_detector(KerberosServiceDetector* s)
+ {
+ krb_service_detector = s;
+ }
bool failed_login = false;
private:
int krb_walk_client_packet(KRBState*, const uint8_t*, const uint8_t*,
AppIdSession&, AppidChangeBits&);
+ KerberosServiceDetector* krb_service_detector = nullptr;
};
class KerberosServiceDetector : public ServiceDetector
KerberosServiceDetector(ServiceDiscovery*);
int validate(AppIdDiscoveryArgs&) override;
+ int krb_walk_server_packet(KRBState*, const uint8_t*, const uint8_t*, AppIdSession&, snort::Packet*,
+ const AppidSessionDirection, const char*, AppidChangeBits&);
+ void set_client_detector(KerberosClientDetector* c)
+ {
+ krb_client_detector = c;
+ }
+
+private:
+ KerberosClientDetector* krb_client_detector = nullptr;
};
#endif
int need_continue;
};
-static Pop3ClientDetector* pop3_client_detector;
-static Pop3ServiceDetector* pop3_service_detector;
-
static AppIdFlowContentPattern pop3_client_patterns[] =
{
{ USER, sizeof(USER)-1, 0, 1, 0 },
{ APP_ID_POP3S, APPINFO_FLAG_SERVICE_ADDITIONAL | APPINFO_FLAG_CLIENT_USER }
};
- pop3_client_detector = this;
handler->register_detector(name, this, proto);
}
return 1;
}
-static int pop3_server_validate(POP3DetectorData* dd, const uint8_t* data, uint16_t size,
+int Pop3ServiceDetector::pop3_server_validate(POP3DetectorData* dd, const uint8_t* data, uint16_t size,
AppIdSession& asd, int server, AppidChangeBits& change_bits)
{
ServicePOP3Data* pd = &dd->server;
{
if (pd->error)
{
- pop3_service_detector->add_user(asd, dd->client.username, APP_ID_POP3, false, change_bits);
+ this->add_user(asd, dd->client.username, APP_ID_POP3, false, change_bits);
snort_free(dd->client.username);
dd->client.username = nullptr;
}
{
if (dd->client.state == POP3_CLIENT_STATE_TRANS)
{
- pop3_service_detector->add_user(asd, dd->client.username, APP_ID_POP3, true, change_bits);
+ this->add_user(asd, dd->client.username, APP_ID_POP3, true, change_bits);
snort_free(dd->client.username);
dd->client.username = nullptr;
dd->need_continue = 0;
int Pop3ClientDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!pop3_service_detector)
+ return APPID_NOMATCH;
+
const uint8_t* s = args.data;
const uint8_t* end = (args.data + args.size);
unsigned length;
if (args.dir == APP_ID_FROM_RESPONDER)
{
- if (pop3_server_validate(dd, args.data, args.size, args.asd, 0, args.change_bits))
+ if (pop3_service_detector->pop3_server_validate(dd, args.data, args.size, args.asd, 0, args.change_bits))
args.asd.clear_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return APPID_INPROCESS;
}
{ POP3_PORT, IpProtocol::TCP, false }
};
- pop3_service_detector = this;
handler->register_detector(name, this, proto);
}
int Pop3ServiceDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!pop3_client_detector)
+ return APPID_NOMATCH;
+
POP3DetectorData* dd;
ServicePOP3Data* pd;
#include "service_plugins/service_detector.h"
struct POP3DetectorData;
+class Pop3ServiceDetector;
class Pop3ClientDetector : public ClientDetector
{
void do_custom_reload() override;
int validate(AppIdDiscoveryArgs&) override;
POP3DetectorData* get_common_data(AppIdSession&);
+ void set_service_detector(Pop3ServiceDetector* s)
+ {
+ pop3_service_detector = s;
+ }
private:
snort::SearchTool* cmd_matcher = nullptr;
unsigned longest_pattern = 0;
+ Pop3ServiceDetector* pop3_service_detector = nullptr;
};
class Pop3ServiceDetector : public ServiceDetector
Pop3ServiceDetector(ServiceDiscovery*);
int validate(AppIdDiscoveryArgs&) override;
+ void set_client_detector(Pop3ClientDetector* c)
+ {
+ pop3_client_detector = c;
+ }
+ int pop3_server_validate(POP3DetectorData*, const uint8_t*, uint16_t, AppIdSession&, int, AppidChangeBits&);
+
+private:
+ Pop3ClientDetector* pop3_client_detector = nullptr;
};
#endif
{ APP_ID_SIP, APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER },
};
- SipEventHandler::set_client(this);
handler->register_detector(name, this, proto);
}
{ SIP_PORT, IpProtocol::TCP, false }
};
- SipEventHandler::set_service(this);
handler->register_detector(name, this, proto);
}
return APPID_INPROCESS;
}
-SipUdpClientDetector* SipEventHandler::client = nullptr;
#endif
-SipServiceDetector* SipEventHandler::service = nullptr;
void SipEventHandler::handle(DataEvent& event, Flow* flow)
{
AppId client_id = APP_ID_SIP;
char* client_version = nullptr;
+ SipUdpClientDetector* client = pkt_thread_odp_ctxt->get_sip_client_detector();
+ if (!client)
+ return;
+
ClientSIPData* fd = (ClientSIPData*)client->data_get(asd);
if ( !fd )
{
void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd,
AppidChangeBits& change_bits)
{
+ SipServiceDetector* service = pkt_thread_odp_ctxt->get_sip_service_detector();
+ if (!service)
+ return;
+
ServiceSIPData* ss = (ServiceSIPData*)service->data_get(asd);
if ( !ss )
{
DataHandler(MOD_NAME), inspector(inspector)
{ }
- static void set_client(SipUdpClientDetector* cd) { SipEventHandler::client = cd; }
- static void set_service(SipServiceDetector* sd) { SipEventHandler::service = sd; }
-
void handle(snort::DataEvent&, snort::Flow*) override;
private:
void client_handler(SipEvent&, AppIdSession&, AppidChangeBits&);
void service_handler(SipEvent&, AppIdSession&, AppidChangeBits&);
- static SipUdpClientDetector* client;
- static SipServiceDetector* service;
AppIdInspector& inspector;
};
#endif
static const uint8_t APP_SMTP_MOZILLA[] = "Mozilla";
static const uint8_t APP_SMTP_THUNDERBIRD_SHORT[] = "Thunderbird/";
-static SmtpClientDetector* smtp_client_detector;
-
SmtpClientDetector::SmtpClientDetector(ClientDiscovery* cdm)
{
handler = cdm;
{ APP_ID_SMTPS, APPINFO_FLAG_CLIENT_ADDITIONAL }
};
- smtp_client_detector = this;
handler->register_detector(name, this, proto);
}
int SmtpServiceDetector::validate(AppIdDiscoveryArgs& args)
{
+ if (!smtp_client_detector)
+ return APPID_NOMATCH;
+
SMTPDetectorData* dd = smtp_client_detector->get_common_data(args.asd);
if ( !dd )
return APPID_ENOMEM;
SmtpServiceDetector(ServiceDiscovery*);
int validate(AppIdDiscoveryArgs&) override;
+ void set_client_detector(SmtpClientDetector* c)
+ {
+ smtp_client_detector = c;
+ }
+
+private:
+ SmtpClientDetector* smtp_client_detector = nullptr;
};
#endif
sip_matchers.finalize_patterns(*this);
}
+SipUdpClientDetector* OdpContext::get_sip_client_detector() { return &cd; }
+
void SipPatternMatchers::finalize_patterns(OdpContext&)
{
sip_ua_matcher = mlmpCreate();
bool SipEvent::is_dialog_established() const { return false; }
int SipPatternMatchers::get_client_from_ua(char const*, unsigned int, int&, char*&) { return 0; } // LCOV_EXCL_LINE
void SipEventHandler::service_handler(SipEvent&, AppIdSession&, AppidChangeBits&) { }
-SipUdpClientDetector* SipEventHandler::client = &cd;
void* AppIdDetector::data_get(AppIdSession&)
{
return tcp_pattern_count + udp_pattern_count;
}
+ServiceDetector* ServiceDiscovery::get_service_detector(const std::string& name) const
+{
+ auto det = tcp_detectors.find(name);
+ if (det != tcp_detectors.end())
+ return (ServiceDetector*) det->second;
+
+ return nullptr;
+}
+
int ServiceDiscovery::add_service_port(AppIdDetector* detector, const ServiceDetectorPort& pp)
{
ServiceDetector* service = static_cast<ServiceDetector*>(detector);
static void clear_ftp_service_state();
static void set_thread_local_ftp_service();
static void reset_thread_local_ftp_service();
+ ServiceDetector* get_service_detector(const std::string&) const;
+
private:
void get_next_service(const snort::Packet*, const AppidSessionDirection dir, AppIdSession&);
void get_port_based_services(IpProtocol, uint16_t port, AppIdSession&);