return false;
AppidChangeBits change_bits;
- HostPatternMatchers& host_matchers = asd->get_odp_ctxt().get_host_matchers();
if (!asd->tsession)
asd->tsession = new TlsSession();
- else if (sni_mismatch)
+
+ if (sni_mismatch)
{
asd->tsession->process_sni_mismatch();
- }
-
-
- if (sni_mismatch)
asd->scan_flags |= SCAN_SPOOFED_SNI_FLAG;
+ }
if (org_unit)
{
asd->tsession->set_tls_org_unit(org_unit, strlen(org_unit));
- if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
- {
- host_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit),
- client_id, payload_id);
- if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
- asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_ORG_UNIT);
- }
+ asd->scan_flags |= SCAN_SSL_ORG_UNIT_FLAG;
}
- if (server_name and !sni_mismatch)
+ if (server_name)
{
- asd->tsession->set_tls_host(server_name, strlen(server_name), change_bits);
- host_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
- client_id, payload_id);
- if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
- asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_HOST);
+ asd->tsession->set_tls_sni(server_name, strlen(server_name));
+ if (!sni_mismatch)
+ asd->scan_flags |= SCAN_SSL_HOST_FLAG;
}
if (first_alt_name)
{
- asd->tsession->set_tls_first_alt_name(first_alt_name, strlen(first_alt_name), change_bits);
- if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
- {
- host_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
- client_id, payload_id);
- if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
- asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_FIRST_SAN);
- }
+ asd->tsession->set_tls_first_alt_name(first_alt_name, strlen(first_alt_name));
+ asd->scan_flags |= SCAN_SSL_ALT_NAME;
}
if (common_name)
{
- asd->tsession->set_tls_cname(common_name, strlen(common_name), change_bits);
- if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
- {
- host_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name),
- client_id, payload_id);
- if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
- asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_CNAME);
- }
+ asd->tsession->set_tls_cname(common_name, strlen(common_name));
+ asd->scan_flags |= SCAN_SSL_CERTIFICATE_FLAG;
+ asd->tsession->set_tls_handshake_done();
}
asd->scan_flags |= SCAN_CERTVIZ_ENABLED_FLAG;
- service_id = asd->get_api().get_service_app_id();
-
- if (asd->use_eve_client_app_id())
- client_id = asd->get_eve_client_app_id();
- else if (client_id == APP_ID_NONE)
- client_id = asd->get_api().get_client_app_id();
- else
- asd->set_client_id(client_id);
-
- if (payload_id == APP_ID_NONE)
- payload_id = asd->get_api().get_payload_app_id();
- else
- asd->set_payload_id(payload_id);
-
+ asd->examine_ssl_metadata(change_bits, true);
+ service_id = asd->pick_service_app_id();
+ client_id = asd->pick_ss_client_app_id();
+ payload_id = asd->pick_ss_payload_app_id();
+
asd->set_ss_application_ids(client_id, payload_id, change_bits);
- asd->set_tls_host(change_bits);
Packet* p = DetectionEngine::get_current_packet();
assert(p);
asd.set_session_flags(APPID_SESSION_ADDITIONAL_PACKET);
}
+ if (asd.tsession)
+ asd.examine_ssl_metadata(change_bits, true);
+
service_id = asd.pick_service_app_id();
// Length-based service detection if no service is found yet
asd.set_ss_application_ids(service_id, client_id, payload_id, misc_id,
asd.pick_ss_referred_payload_app_id(), change_bits);
- asd.set_tls_host(change_bits);
- if (asd.tsession and asd.tsession->is_tls_host_unpublished())
- {
- change_bits.set(APPID_TLSHOST_BIT);
- asd.tsession->set_tls_host_unpublished(false);
- }
if (asd.is_client_info_unpublished())
{
#define SCAN_CERTVIZ_ENABLED_FLAG (1<<10)
#define SCAN_SPOOFED_SNI_FLAG (1<<11)
#define SCAN_SSL_VERSION_FLAG (1<<12)
+#define SCAN_SSL_ORG_UNIT_FLAG (1<<13)
+#define SCAN_SSL_ALT_NAME (1<<14)
enum FirstPktAppIdDiscovered
{
if (!server_name.empty())
{
- AppId tmp_client_id = APP_ID_NONE;
- AppId tmp_payload_id = APP_ID_NONE;
-
+ AppidChangeBits change_bits;
if (!asd->tsession)
asd->tsession = new TlsSession();
- asd->tsession->set_tls_host(server_name.c_str(), server_name.length());
- asd->set_tls_host();
-
- odp_ctxt.get_host_matchers().scan_hostname(reinterpret_cast<const uint8_t*>(server_name.c_str()),
- server_name.length(), tmp_client_id, tmp_payload_id);
- asd->set_payload_id(tmp_payload_id);
+ asd->tsession->set_tls_sni(server_name.c_str(), server_name.length());
+ if (is_quic)
+ asd->tsession->set_tls_handshake_done();
+ asd->scan_flags |= SCAN_SSL_HOST_FLAG;
+ asd->examine_ssl_metadata(change_bits, true);
}
std::string debug_str;
if (!asd)
asd = create_appid_session(*flow, key, *inspector);
- asd->set_tls_host(appHA->tls_host);
+ asd->consume_ha_tls_host(appHA->tls_host);
asd->set_consumed_ha_data(true);
}
}
-void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
+void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits, bool partial_inspect)
{
+ assert(tsession);
AppId client_id = 0;
AppId payload_id = 0;
- const char* tls_str = tsession->get_tls_org_unit();
+ const char* tls_str = nullptr;
- if (scan_flags & SCAN_CERTVIZ_ENABLED_FLAG)
+ if (!partial_inspect and !tsession->get_tls_handshake_done())
+ {
+ return;
+ }
+
+ if (tsession->is_tls_data_finished())
+ {
+ if (tsession->is_tls_host_published() == false)
+ {
+ change_bits.set(APPID_TLSHOST_BIT);
+ }
return;
+ }
- if (tls_str)
+
+ bool match_found = false;
+
+ if ((scan_flags & SCAN_SSL_HOST_FLAG) and !(scan_flags & SCAN_SPOOFED_SNI_FLAG) and (tls_str = tsession->get_tls_sni()))
{
size_t size = strlen(tls_str);
- if (odp_ctxt.get_host_matchers().scan_cname((const uint8_t*)tls_str, size,
+ if (odp_ctxt.get_host_matchers().scan_hostname((const uint8_t*)tls_str, size,
client_id, payload_id))
{
- set_client_appid_data(client_id, change_bits);
+ if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
+ set_client_appid_data(client_id, change_bits);
set_payload_appid_data(payload_id);
+ match_found = true;
+ if (api.get_tls_host() and (strcmp(api.get_tls_host(), tls_str) != 0))
+ tsession->set_tls_host_published(false);
+ tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_SNI);
}
- tsession->set_tls_org_unit(nullptr, 0);
+ scan_flags &= ~SCAN_SSL_HOST_FLAG;
}
- if ((scan_flags & SCAN_SSL_HOST_FLAG) and (tls_str = tsession->get_tls_host()))
+ if (!match_found and (scan_flags & SCAN_SSL_CERTIFICATE_FLAG) and (tls_str = tsession->get_tls_cname()))
{
size_t size = strlen(tls_str);
- if (odp_ctxt.get_host_matchers().scan_hostname((const uint8_t*)tls_str, size,
+ if (odp_ctxt.get_host_matchers().scan_cname((const uint8_t*)tls_str, size,
client_id, payload_id))
{
if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
set_client_appid_data(client_id, change_bits);
set_payload_appid_data(payload_id);
+ match_found = true;
+ if (api.get_tls_host() and (strcmp(api.get_tls_host(), tls_str) != 0))
+ tsession->set_tls_host_published(false);
+ tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_CNAME);
}
- scan_flags &= ~SCAN_SSL_HOST_FLAG;
+ else if (odp_ctxt.get_host_matchers().scan_hostname((const uint8_t*)tls_str, size,
+ client_id, payload_id))
+ {
+ if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
+ set_client_appid_data(client_id, change_bits);
+ set_payload_appid_data(payload_id);
+ match_found = true;
+ if (api.get_tls_host() and (strcmp(api.get_tls_host(), tls_str) != 0))
+ tsession->set_tls_host_published(false);
+ tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_CNAME);
+ }
+ scan_flags &= ~SCAN_SSL_CERTIFICATE_FLAG;
}
- if ((scan_flags & SCAN_SSL_CERTIFICATE_FLAG) and (tls_str = tsession->get_tls_cname()))
+
+ if (!match_found and (scan_flags & SCAN_SSL_ORG_UNIT_FLAG) and (tls_str = tsession->get_tls_org_unit()) )
{
size_t size = strlen(tls_str);
if (odp_ctxt.get_host_matchers().scan_cname((const uint8_t*)tls_str, size,
if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
set_client_appid_data(client_id, change_bits);
set_payload_appid_data(payload_id);
+ match_found = true;
+ if (api.get_tls_host() and (strcmp(api.get_tls_host(), tls_str) != 0))
+ tsession->set_tls_host_published(false);
+ tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_ORG_UNIT);
}
- scan_flags &= ~SCAN_SSL_CERTIFICATE_FLAG;
}
- if (tsession->get_tls_handshake_done() and
- api.payload.get_id() == APP_ID_NONE)
+ if (!match_found and (scan_flags & SCAN_SSL_ALT_NAME) and (tls_str = tsession->get_tls_first_alt_name()))
{
- APPID_LOG(CURRENT_PACKET, TRACE_DEBUG_LEVEL, "End of SSL/TLS handshake detected with no payloadAppId, "
- "so setting to unknown\n");
- api.payload.set_id(APP_ID_UNKNOWN);
+ size_t size = strlen(tls_str);
+ if (odp_ctxt.get_host_matchers().scan_hostname((const uint8_t*)tls_str, size,
+ client_id, payload_id))
+ {
+ if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
+ set_client_appid_data(client_id, change_bits);
+ set_payload_appid_data(payload_id);
+ if (api.get_tls_host() and (strcmp(api.get_tls_host(), tls_str) != 0))
+ tsession->set_tls_host_published(false);
+ tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_FIRST_SAN);
+ }
+ scan_flags &= ~SCAN_SSL_HOST_FLAG;
+ }
+
+ if (!tsession->is_tls_host_published())
+ {
+ if (tsession->get_tls_host())
+ {
+ api.set_tls_host(tsession->get_tls_host());
+ api.set_tls_sni(tsession->get_tls_sni());
+ change_bits.set(APPID_TLSHOST_BIT);
+ }
+ }
+ else if (tsession->is_tls_host_mismatched() and
+ (api.get_tls_host() and (strcmp(api.get_tls_host(), tsession->get_tls_host()) != 0)))
+ {
+ api.set_tls_host(tsession->get_tls_host());
+ api.set_tls_sni(tsession->get_tls_sni());
+ change_bits.set(APPID_TLSHOST_BIT);
}
}
else if (change_bits.none())
return;
+ if (tsession and change_bits.test(APPID_TLSHOST_BIT))
+ {
+ tsession->set_tls_host_published(true);
+ }
+
AppidEvent app_event(change_bits, is_httpx, httpx_stream_index, api, p);
DataBus::publish(AppIdInspector::get_pub_id(), AppIdEventIds::ANY_CHANGE, app_event, p.flow);
std::string str;
enum MatchedTlsType
{
MATCHED_TLS_NONE = 0,
- MATCHED_TLS_HOST,
+ MATCHED_TLS_SNI,
MATCHED_TLS_FIRST_SAN,
MATCHED_TLS_CNAME,
MATCHED_TLS_ORG_UNIT,
~TlsSession()
{
- if (tls_host)
- snort_free(tls_host);
+ if (tls_sni)
+ snort_free(tls_sni);
if (tls_first_alt_name)
snort_free(tls_first_alt_name);
if (tls_cname)
snort_free(tls_cname);
if (tls_org_unit)
snort_free(tls_org_unit);
- if (tls_host_mismatch)
- snort_free(tls_host_mismatch);
}
const char* get_tls_host() const
{
switch (matched_tls_type)
{
- case MATCHED_TLS_HOST:
- return tls_host;
+ case MATCHED_TLS_SNI:
+ return tls_sni;
case MATCHED_TLS_FIRST_SAN:
return tls_first_alt_name;
case MATCHED_TLS_CNAME:
return tls_cname;
+ case MATCHED_TLS_ORG_UNIT:
default:
- if (tls_host)
- return tls_host;
- else if (tls_first_alt_name)
- return tls_first_alt_name;
+ if (tls_sni and !tls_host_mismatch)
+ return tls_sni;
else if (tls_cname)
return tls_cname;
+ else if (tls_first_alt_name)
+ return tls_first_alt_name;
+
+ return nullptr;
}
- return nullptr;
}
const char* get_tls_sni() const
{
- return tls_host_mismatch ? tls_host_mismatch : tls_host;
+ return tls_sni;
}
void process_sni_mismatch()
{
- if(tls_host)
- {
- if(tls_host_mismatch)
- snort_free(tls_host_mismatch);
- tls_host_mismatch = tls_host;
- tls_host = nullptr;
- }
+ tls_host_mismatch = true;
}
+ bool is_tls_host_mismatched() const { return tls_host_mismatch; }
+
const char* get_tls_first_alt_name() const { return tls_first_alt_name; }
const char* get_tls_cname() const { return tls_cname; }
uint16_t get_tls_version() const { return tls_version; }
- // Duplicate only if len > 0, otherwise simply set (i.e., own the argument)
- void set_tls_host(const char* new_tls_host, uint32_t len, bool published=false)
+ void set_tls_sni(const char* new_tls_sni, uint32_t len)
{
- if (tls_host)
- snort_free(tls_host);
- if (!new_tls_host or *new_tls_host == '\0')
+ if (tls_sni)
{
- tls_host = nullptr;
- return;
+ snort_free(tls_sni);
+ }
+ if (new_tls_sni)
+ {
+ tls_sni = len ? snort::snort_strndup(new_tls_sni, len) :
+ const_cast<char*>(new_tls_sni);
+ }
+ else
+ {
+ tls_sni = nullptr;
}
- tls_host = len? snort::snort_strndup(new_tls_host,len) : const_cast<char*>(new_tls_host);
-
- if (!published)
- tls_host_unpublished = true;
- }
-
- void set_tls_host(const char* new_tls_host, uint32_t len, AppidChangeBits& change_bits)
- {
- set_tls_host(new_tls_host, len, true);
- if (new_tls_host and *new_tls_host != '\0')
- change_bits.set(APPID_TLSHOST_BIT);
}
- void set_tls_first_alt_name(const char* new_tls_first_alt_name, uint32_t len, AppidChangeBits& change_bits)
+ void set_tls_first_alt_name(const char* new_tls_first_alt_name, uint32_t len)
{
if (tls_first_alt_name)
snort_free(tls_first_alt_name);
}
tls_first_alt_name = len? snort::snort_strndup(new_tls_first_alt_name, len) :
const_cast<char*>(new_tls_first_alt_name);
- if (!tls_host)
- change_bits.set(APPID_TLSHOST_BIT);
}
- void set_tls_cname(const char* new_tls_cname, uint32_t len, AppidChangeBits& change_bits)
+ void set_tls_cname(const char* new_tls_cname, uint32_t len)
{
if (tls_cname)
snort_free(tls_cname);
}
tls_cname = len? snort::snort_strndup(new_tls_cname,len) :
const_cast<char*>(new_tls_cname);
- if (tls_host == nullptr)
- change_bits.set(APPID_TLSHOST_BIT);
}
void set_tls_org_unit(const char* new_tls_org_unit, uint32_t len)
void set_tls_handshake_done() { tls_handshake_done = true; }
- void set_matched_tls_type(MatchedTlsType type)
+ MatchedTlsType get_matched_tls_type() const
+ {
+ return matched_tls_type;
+ }
+
+ void set_matched_tls_type(MatchedTlsType type, bool is_tls_data_finished = true)
{
matched_tls_type = type;
+ tls_data_finished = is_tls_data_finished;
}
- void set_tls_host_unpublished(bool val) { tls_host_unpublished = val; }
+ void set_tls_host_published(bool val) { tls_host_published = val; }
- bool is_tls_host_unpublished() const { return tls_host_unpublished; }
+ bool is_tls_host_published() const { return tls_host_published; }
void set_tls_version(const char* value, uint32_t length, AppidChangeBits& change_bits)
{
}
}
+ bool is_tls_data_finished() const { return tls_data_finished; }
+
private:
- char* tls_host = nullptr;
- char* tls_host_mismatch = nullptr;
+ char* tls_sni = nullptr;
char* tls_first_alt_name = nullptr;
char* tls_cname = nullptr;
char* tls_org_unit = nullptr;
bool tls_handshake_done = false;
- bool tls_host_unpublished = false;
+ bool tls_host_published = false;
+ bool tls_host_mismatch = false;
+ bool tls_data_finished = false;
uint16_t tls_version = 0;
MatchedTlsType matched_tls_type = MATCHED_TLS_NONE;
};
void set_ss_application_ids_payload(AppId payload, AppidChangeBits& change_bits);
void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits);
- void examine_ssl_metadata(AppidChangeBits& change_bits);
+ void examine_ssl_metadata(AppidChangeBits& change_bits, bool partial_inspect = false);
void set_client_appid_data(AppId, AppidChangeBits& change_bits, char* version = nullptr);
void set_client_appid_data(AppId, char* version = nullptr, bool published=false);
void set_service_appid_data(AppId, AppidChangeBits& change_bits, char* version = nullptr);
api.service.set_service_port(port);
}
- void set_tls_host(const AppidChangeBits& change_bits)
- {
- if (tsession and change_bits[APPID_TLSHOST_BIT])
- {
- api.set_tls_host(tsession->get_tls_host());
- api.set_tls_sni(tsession->get_tls_sni());
- }
- }
-
- void set_tls_host(const char* tls_host)
- {
- api.set_tls_host(tls_host);
- }
-
- void set_tls_host()
- {
- if (tsession and tsession->is_tls_host_unpublished())
- {
- api.set_tls_host(tsession->get_tls_host());
- api.set_tls_sni(tsession->get_tls_sni());
- }
- }
-
void set_netbios_name(AppidChangeBits& change_bits, const char *name)
{
api.set_netbios_name(change_bits, name);
api.set_netbios_domain(change_bits, domain);
}
+ void consume_ha_tls_host(const char* tls_host)
+ {
+ api.set_tls_host(tls_host);
+ }
+
OdpContext& get_odp_ctxt() const
{
return odp_ctxt;
}
else if (asd.get_service_id() == APP_ID_RTMP)
asd.examine_rtmp_metadata(change_bits);
- else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) and asd.tsession)
- asd.examine_ssl_metadata(change_bits);
}
return is_discovery_done;
}
args.asd.set_session_flags(APPID_SESSION_SSL_SESSION);
+ if (!args.asd.tsession)
+ args.asd.tsession = new TlsSession();
if (ss->client_hello.host_name || ss->server_cert.common_name || ss->server_cert.org_unit)
{
- if (!args.asd.tsession)
- args.asd.tsession = new TlsSession();
-
/* TLS Host */
if (ss->client_hello.host_name)
{
- args.asd.tsession->set_tls_host(ss->client_hello.host_name, 0, args.change_bits);
+ args.asd.tsession->set_tls_sni(ss->client_hello.host_name, 0);
args.asd.scan_flags |= SCAN_SSL_HOST_FLAG;
}
/* TLS Common Name */
if (ss->server_cert.common_name)
{
- args.asd.tsession->set_tls_cname(ss->server_cert.common_name, 0, args.change_bits);
+ args.asd.tsession->set_tls_cname(ss->server_cert.common_name, 0);
args.asd.scan_flags |= SCAN_SSL_CERTIFICATE_FLAG;
- args.asd.scan_flags |= SCAN_SSL_HOST_FLAG;
}
/* TLS Org Unit */
if (ss->server_cert.org_unit)
+ {
args.asd.tsession->set_tls_org_unit(ss->server_cert.org_unit, 0);
+ args.asd.scan_flags |= SCAN_SSL_ORG_UNIT_FLAG;
+ }
ss->client_hello.host_name = ss->server_cert.common_name = ss->server_cert.org_unit = nullptr;
- args.asd.tsession->set_tls_handshake_done();
}
+ args.asd.tsession->set_tls_handshake_done();
return add_service(args.change_bits, args.asd, args.pkt, args.dir,
getSslServiceAppId(args.pkt->ptrs.sp));
}
THREAD_LOCAL bool TimeProfilerStats::enabled = false;
#define ShadowTraffic_Type_Domain_Fronting 0x00000010
+bool mock_inspector_exist = true;
+
namespace snort
{
class Inspector* InspectorManager::get_inspector(const char*, bool, const SnortConfig*)
-{ return &dummy_appid_inspector; }
+{ return mock_inspector_exist ? &dummy_appid_inspector : nullptr; }
Packet::Packet(bool) { }
Packet::~Packet() = default;
DataBus::publish(0, AppIdEventIds::ANY_CHANGE, app_event, p.flow);
}
+void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits, bool partial_inspect)
+{
+ if (tsession == nullptr)
+ return;
+
+ set_service_id(APPID_UT_ID, get_odp_ctxt());
+ api.client.set_id(APPID_UT_ID);
+ api.payload.set_id(APPID_UT_ID);
+}
+
bool HostPatternMatchers::scan_hostname(const uint8_t* server_name, size_t, AppId& client_id, AppId& payload_id)
{
if (((const char*)server_name) == APPID_UT_TLS_HOST)
AppIdHttpSession* AppIdSession::get_http_session(uint32_t) const { return nullptr; }
Flow* flow = nullptr;
+Flow* flow_no_session = nullptr;
AppIdSession* mock_session = nullptr;
TEST_GROUP(appid_api)
}
};
+TEST_GROUP(appid_api_no_session)
+{
+ void setup()
+ {
+ mock_init_appid_pegs();
+ flow_no_session = new Flow;
+ }
+
+ void teardown()
+ {
+ mock_cleanup_appid_pegs();
+ delete flow_no_session;
+ }
+};
+
TEST(appid_api, get_application_name)
{
AppIdConfig config;
STRCMP_EQUAL(app_name, test_app_name);
}
+TEST(appid_api, get_appid_detector_directory_inspector_exist)
+{
+ auto res = appid_api.get_appid_detector_directory();
+ STRCMP_EQUAL("test_dir", res);
+}
+
+TEST(appid_api, get_appid_detector_directory_inspector_does_not_exist)
+{
+ mock_inspector_exist = false;
+ auto res = appid_api.get_appid_detector_directory();
+ STRCMP_EQUAL("", res);
+ mock_inspector_exist = true;
+}
+
TEST(appid_api, get_application_id)
{
AppIdConfig config;
TEST(appid_api, ssl_app_group_id_lookup)
{
- mock().expectNCalls(7, "publish");
+ mock().expectNCalls(1, "publish");
AppId service, client, payload = APP_ID_NONE;
bool val = false;
AppidChangeBits change_bits;
- mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID,
- APPID_UT_ID, APPID_UT_ID, change_bits);
- val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, nullptr, nullptr,
- false, service, client, payload);
+
+ mock_session->set_ss_application_ids(0,0,0,0,0, change_bits);
+ mock_session->tsession->set_tls_sni(nullptr, 0);
+ mock_session->tsession->set_tls_cname(nullptr, 0);
+ mock_session->tsession->set_tls_first_alt_name(nullptr, 0);
+ mock_session->tsession->set_tls_org_unit(nullptr, 0);
+
+ val = appid_api.ssl_app_group_id_lookup(flow, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
+ (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_ORG_UNIT, false, service, client, payload);
+
CHECK_TRUE(val);
CHECK_EQUAL(service, APPID_UT_ID);
CHECK_EQUAL(client, APPID_UT_ID);
CHECK_EQUAL(payload, APPID_UT_ID);
- STRCMP_EQUAL("Published change_bits == 00000000000000000000000", test_log);
-
- // Server name based detection
- service = APP_ID_NONE;
- client = APP_ID_NONE;
- payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(flow, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
- (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST, false, service, client, payload);
- CHECK_TRUE(val);
- CHECK_EQUAL(client, APPID_UT_ID + 1);
- CHECK_EQUAL(payload, APPID_UT_ID + 1);
- STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
+ STRCMP_EQUAL(mock_session->tsession->get_tls_sni(), APPID_UT_TLS_HOST);
STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST);
STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL(mock_session->tsession->get_tls_sni(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL("Published change_bits == 00000000000000100011000", test_log);
-
- // Common name based detection
- mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits);
- mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits);
- mock_session->tsession->set_tls_org_unit("Cisco", 5);
- STRCMP_EQUAL(mock_session->tsession->get_tls_host(), "www.cisco.com");
- STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), "www.cisco.com");
- STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco");
- val = appid_api.ssl_app_group_id_lookup(flow, (const char*)"www.google.com",
- nullptr, (const char*)APPID_UT_TLS_HOST, nullptr, false, service, client, payload);
- CHECK_TRUE(val);
- CHECK_EQUAL(client, APPID_UT_ID + 2);
- CHECK_EQUAL(payload, APPID_UT_ID + 2);
- STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco");
- STRCMP_EQUAL("Published change_bits == 00000000000000100011000", test_log);
-
- // First alt name based detection
- change_bits.reset();
- mock_session->tsession->set_tls_host("", 0, change_bits);
- val = appid_api.ssl_app_group_id_lookup(flow, nullptr, (const char*)APPID_UT_TLS_HOST,
- nullptr, nullptr, false, service, client, payload);
- CHECK_TRUE(val);
- CHECK_EQUAL(client, APPID_UT_ID + 1);
- CHECK_EQUAL(payload, APPID_UT_ID + 1);
- STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL("Published change_bits == 00000000000000100011000", test_log);
-
- // Org unit based detection
- string host = "";
- change_bits.reset();
- mock_session->tsession->set_tls_host("", 0, change_bits);
- val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr,
- nullptr, (const char*)APPID_UT_ORG_UNIT, false, service, client, payload);
- CHECK_TRUE(val);
- CHECK_EQUAL(client, APPID_UT_ID + 3);
- CHECK_EQUAL(payload, APPID_UT_ID + 3);
STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), APPID_UT_ORG_UNIT);
- STRCMP_EQUAL("Published change_bits == 00000000000000000011000", test_log);
+ mock().checkExpectations();
+}
+
+TEST(appid_api, ssl_app_group_id_lookup_sni_mismatch)
+{
+ mock().expectNCalls(1, "publish");
+ AppId service, client, payload = APP_ID_NONE;
+ bool val = false;
+
+ AppidChangeBits change_bits;
+
+ mock_session->set_ss_application_ids(0,0,0,0,0, change_bits);
+ mock_session->tsession->set_tls_sni(nullptr, 0);
+ mock_session->tsession->set_tls_cname(nullptr, 0);
+ mock_session->tsession->set_tls_first_alt_name(nullptr, 0);
+ mock_session->tsession->set_tls_org_unit(nullptr, 0);
- // Override client id found by SSL pattern matcher with the client id provided by
- // Encrypted Visibility Engine if available
- service = APP_ID_NONE;
- client = APP_ID_NONE;
- payload = APP_ID_NONE;
- change_bits.reset();
- mock_session->tsession->set_tls_host("", 0, change_bits);
- mock_session->set_client_id(APP_ID_NONE);
- mock_session->set_eve_client_app_id(APPID_UT_ID + 100);
val = appid_api.ssl_app_group_id_lookup(flow, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
- (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST, false, service, client, payload);
+ (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_ORG_UNIT, true, service, client, payload);
+
CHECK_TRUE(val);
- CHECK_EQUAL(client, APPID_UT_ID + 100);
- CHECK_EQUAL(payload, APPID_UT_ID + 1);
- STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
+ CHECK_TRUE(mock_session->tsession->is_tls_host_mismatched());
+ CHECK_EQUAL(service, APPID_UT_ID);
+ CHECK_EQUAL(client, APPID_UT_ID);
+ CHECK_EQUAL(payload, APPID_UT_ID);
+ STRCMP_EQUAL(mock_session->tsession->get_tls_sni(), APPID_UT_TLS_HOST);
STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST);
STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
- STRCMP_EQUAL("Published change_bits == 00000000000000100011000", test_log);
-
- //check for sni mismatch being stored in sni field
- change_bits.reset();
- mock_session->tsession->set_tls_host("mismatchedsni.com", 17, change_bits);
- service = APP_ID_NONE;
- client = APP_ID_NONE;
- payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(flow, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
- nullptr, nullptr, true, service, client, payload);
- CHECK_TRUE(val);
- STRCMP_EQUAL(APPID_UT_TLS_HOST, mock_session->tsession->get_tls_host());
- STRCMP_EQUAL("mismatchedsni.com", mock_session->tsession->get_tls_sni());
-
+ STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), APPID_UT_ORG_UNIT);
mock().checkExpectations();
+}
- // When appid session is not existing
- // 1. Match based on server name
- Flow* f = new Flow;
- // This call just sets mock_flow_data pointer to nullptr, so mocks work correctly for the test.
- flow->free_flow_data(1);
- service = APP_ID_NONE;
- client = APP_ID_NONE;
- payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(f, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
+TEST(appid_api_no_session, ssl_app_group_id_lookup)
+{
+ AppId service, client, payload = APP_ID_NONE;
+ bool val = false;
+
+ AppidChangeBits change_bits;
+
+ flow_no_session->free_flow_data(1);
+ val = appid_api.ssl_app_group_id_lookup(flow_no_session, (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST,
(const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST, false, service, client, payload);
CHECK_TRUE(val);
CHECK_EQUAL(client, APPID_UT_ID + 1);
// 2. First alt name match
client = APP_ID_NONE;
payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(f, nullptr, (const char*)APPID_UT_TLS_HOST,
- (const char*)APPID_UT_TLS_HOST, (const char*)APPID_UT_TLS_HOST, false, service, client, payload);
+ val = appid_api.ssl_app_group_id_lookup(flow_no_session, nullptr, (const char*)APPID_UT_TLS_HOST,
+ nullptr, (const char*)APPID_UT_TLS_HOST, false, service, client, payload);
CHECK_TRUE(val);
CHECK_EQUAL(client, APPID_UT_ID + 1);
CHECK_EQUAL(payload, APPID_UT_ID + 1);
// 3. CN match
client = APP_ID_NONE;
payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(f, nullptr, nullptr, (const char*)APPID_UT_TLS_HOST,
+ val = appid_api.ssl_app_group_id_lookup(flow_no_session, nullptr, nullptr, (const char*)APPID_UT_TLS_HOST,
(const char*)APPID_UT_TLS_HOST, false, service, client, payload);
CHECK_TRUE(val);
CHECK_EQUAL(client, APPID_UT_ID + 2);
// 4. Org unit match
client = APP_ID_NONE;
payload = APP_ID_NONE;
- val = appid_api.ssl_app_group_id_lookup(f, nullptr, nullptr, nullptr, (const char*)APPID_UT_TLS_HOST,
+ val = appid_api.ssl_app_group_id_lookup(flow_no_session, nullptr, nullptr, nullptr, (const char*)APPID_UT_TLS_HOST,
false, service, client, payload);
CHECK_TRUE(val);
CHECK_EQUAL(client, APPID_UT_ID + 2);
CHECK_EQUAL(payload, APPID_UT_ID + 2);
-
- delete f;
}
TEST(appid_api, is_inspection_needed)
void AppIdSession::check_app_detection_restart(AppidChangeBits&, ThirdPartyAppIdContext*) {}
void AppIdSession::set_client_appid_data(AppId, AppidChangeBits&, char*) {}
void AppIdSession::examine_rtmp_metadata(AppidChangeBits&) {}
-void AppIdSession::examine_ssl_metadata(AppidChangeBits&) {}
void AppIdSession::update_encrypted_app_id(AppId) {}
bool AppIdSession::is_tp_processing_done() const {return false;}
AppId AppIdSession::pick_ss_payload_app_id(AppId) const { return get_payload_id(); }
bool AppIdSession::need_to_delete_tp_conn(ThirdPartyAppIdContext*) const { return true; }
void AppIdSession::process_shadow_traffic_appids() {}
+void AppIdSession::examine_ssl_metadata(AppidChangeBits&,bool) {}
AppIdSession* AppIdSession::allocate_session(const Packet*, IpProtocol,
AppidSessionDirection, AppIdInspector&, OdpContext&)
delete asd;
}
-TEST(appid_discovery_tests, change_bits_for_tls_host)
-{
- // Testing set_tls_host
- AppidChangeBits change_bits;
- char* host = snort_strdup(APPID_UT_TLS_HOST);
- TlsSession tls;
- tls.set_tls_host(host, 0, change_bits);
-
- // Detect changes in tls_host
- CHECK_EQUAL(change_bits.test(APPID_TLSHOST_BIT), true);
-}
-
TEST(appid_discovery_tests, change_bits_for_non_http_appid)
{
// Testing FTP appid
return;
}
+void AppIdSession::examine_ssl_metadata(AppidChangeBits&,bool) {}
+
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection,
AppId, AppidChangeBits&) { }
void AppIdModule::reset_stats() { }
AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
Flow* flow = new Flow;
event_handler.handle(event, flow);
- CHECK(session->get_payload_id() == APPID_UT_ID + 1);
+ STRCMP_EQUAL(session->tsession->get_tls_sni(),"www.google.com");
delete flow;
}
PegCount* AppIdModule::get_counts() const { return nullptr; }
snort::ProfileStats* AppIdModule::get_profile(
unsigned, const char*&, const char*& ) const { return nullptr; }
-void AppIdModule::set_trace(const Trace*) const { }
-const TraceOption* AppIdModule::get_trace_options() const { return nullptr; }
+void AppIdModule::set_trace(const snort::Trace*) const { }
+const snort::TraceOption* AppIdModule::get_trace_options() const { return nullptr; }
AppIdConfig appid_config;
AppIdInspector::AppIdInspector(AppIdModule&) : config(&appid_config), ctxt(appid_config)
-{ }
+{ appid_config.app_detector_dir = "test_dir"; }
AppIdInspector::~AppIdInspector() = default;
void AppIdInspector::eval(snort::Packet*) { }
bool AppIdInspector::configure(snort::SnortConfig*) { return true; }
-void AppIdInspector::show(const SnortConfig*) const { }
+void AppIdInspector::show(const snort::SnortConfig*) const { }
void AppIdInspector::tinit() { }
void AppIdInspector::tterm() { }
void AppIdInspector::tear_down(snort::SnortConfig*) { }
api.set_application_ids_service(service_id, change_bits, *flow);
}
+void AppIdSession::examine_ssl_metadata(AppidChangeBits& bits, bool)
+{
+ api.set_tls_host(tsession->get_tls_sni());
+}
+
TEST_GROUP(appid_session_api)
{
void setup() override
TEST(appid_session_api, get_tls_host)
{
AppidChangeBits change_bits;
- change_bits.set(APPID_TLSHOST_BIT);
- mock_session->tsession->set_tls_host(nullptr, 0, change_bits);
- mock_session->set_tls_host(change_bits);
- const char* val = mock_session->get_api().get_tls_host();
- STRCMP_EQUAL(val, nullptr);
char* host = snort_strdup(APPID_UT_TLS_HOST);
- mock_session->tsession->set_tls_host(host, 0, change_bits);
- mock_session->set_tls_host(change_bits);
- val = mock_session->get_api().get_tls_host();
+ mock_session->tsession->set_tls_sni(host, 0);
+ mock_session->examine_ssl_metadata(change_bits, true);
+ auto val = mock_session->get_api().get_tls_host();
STRCMP_EQUAL(val, APPID_UT_TLS_HOST);
+ mock_session->tsession->set_tls_sni(nullptr, 0);
}
TEST(appid_session_api, get_tls_version)
mock_session->service_disco_state = APPID_DISCO_STATE_STATEFUL;
mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
char* host = snort_strdup(APPID_UT_TLS_HOST);
- mock_session->tsession->set_tls_host(host, 0, change_bits);
- change_bits.set(APPID_TLSHOST_BIT);
- mock_session->set_tls_host(change_bits);
+ mock_session->tsession->set_tls_sni(host, 0);
+ mock_session->examine_ssl_metadata(change_bits, true);
val = mock_session->get_api().is_http_inspection_done();
CHECK_TRUE(val);
mock_session->service_disco_state = APPID_DISCO_STATE_FINISHED;
reinspect_ssl_appid = check_ssl_appid_for_reinspect(tmpAppId, asd.get_odp_ctxt());
- if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
- asd.tsession->get_tls_host() == nullptr and
+ if (asd.tsession->get_tls_version() == 0 and
+ (field = attribute_data.tls_version(false)) != nullptr)
+ {
+ asd.tsession->set_tls_version(field->c_str(), field->size(), change_bits);
+ if (reinspect_ssl_appid)
+ {
+ asd.scan_flags |= SCAN_SSL_VERSION_FLAG;
+ }
+ }
+
+ if (asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG)
+ return;
+
+ if ( asd.tsession->get_tls_sni() == nullptr and
(field = attribute_data.tls_host(false)) != nullptr)
{
- asd.tsession->set_tls_host(field->c_str(), field->size(), change_bits);
+ asd.tsession->set_tls_sni(field->c_str(), field->size());
if (reinspect_ssl_appid)
asd.scan_flags |= SCAN_SSL_HOST_FLAG;
}
- if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
- asd.tsession->get_tls_cname() == nullptr and
+ if ( asd.tsession->get_tls_cname() == nullptr and
(field = attribute_data.tls_cname()) != nullptr)
{
- asd.tsession->set_tls_cname(field->c_str(), field->size(), change_bits);
+ asd.tsession->set_tls_cname(field->c_str(), field->size());
if (reinspect_ssl_appid)
asd.scan_flags |= SCAN_SSL_CERTIFICATE_FLAG;
+
+ asd.tsession->set_tls_handshake_done();
}
if (reinspect_ssl_appid)
{
- if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
- asd.tsession->get_tls_org_unit() == nullptr and
+ if ( asd.tsession->get_tls_org_unit() == nullptr and
(field = attribute_data.tls_org_unit()) != nullptr)
{
asd.tsession->set_tls_org_unit(field->c_str(), field->size());
- }
- }
-
- if (asd.tsession->get_tls_version() == 0 and
- (field = attribute_data.tls_version(false)) != nullptr)
- {
- asd.tsession->set_tls_version(field->c_str(), field->size(), change_bits);
- if (reinspect_ssl_appid)
- {
- asd.scan_flags |= SCAN_SSL_VERSION_FLAG;
+ asd.tsession->set_tls_handshake_done();
+ asd.scan_flags |= SCAN_SSL_ORG_UNIT_FLAG;
}
}
}
if ( !asd.tsession )
asd.tsession = new TlsSession();
- if ( !asd.tsession->get_tls_host() and (field=attribute_data.quic_sni()) != nullptr )
+ if ( !asd.tsession->get_tls_sni() and (field=attribute_data.quic_sni()) != nullptr )
{
APPID_LOG(CURRENT_PACKET, TRACE_DEBUG_LEVEL, "Flow is QUIC\n");
- asd.tsession->set_tls_host(field->c_str(), field->size(), change_bits);
+ asd.tsession->set_tls_sni(field->c_str(), field->size());
+ asd.tsession->set_tls_handshake_done();
+ asd.scan_flags |= SCAN_SSL_HOST_FLAG;
if ( asd.get_service_id() <= APP_ID_NONE )
asd.set_service_appid_data(APP_ID_QUIC, change_bits);
}
}
else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession)
{
- asd.examine_ssl_metadata(change_bits);
uint16_t serverPort;
AppId portAppId;
serverPort = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.dp : p->ptrs.sp;