return sizeof(*appHA);
}
-bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name, const char* common_name,
- AppId& service_id, AppId& client_id, AppId& payload_id, const char* org_unit)
+bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
+ const char* first_alt_name, const char* common_name, const char* org_unit,
+ bool sni_mismatch, AppId& service_id, AppId& client_id, AppId& payload_id)
{
AppIdSession* asd = nullptr;
service_id = APP_ID_NONE;
AppidChangeBits change_bits;
SslPatternMatchers& ssl_matchers = asd->ctxt.get_odp_ctxt().get_ssl_matchers();
if (!asd->tsession)
- asd->tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
+ asd->tsession = new TlsSession();
+ else if (sni_mismatch)
+ asd->tsession->set_tls_host(nullptr, 0, change_bits);
- if (server_name)
+ if (sni_mismatch)
+ asd->scan_flags |= SCAN_SPOOFED_SNI_FLAG;
+
+ if (server_name and !sni_mismatch)
{
- ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name), client_id,
- payload_id);
asd->tsession->set_tls_host(server_name, strlen(server_name), change_bits);
- asd->scan_flags |= SCAN_SSL_HOST_FLAG;
- asd->scan_flags |= SCAN_DO_NOT_OVERRIDE_SERVER_NAME_FLAG;
+ ssl_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);
+ }
+
+ 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)
+ {
+ ssl_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);
+ }
}
if (common_name)
{
- ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id,
- payload_id);
asd->tsession->set_tls_cname(common_name, strlen(common_name), change_bits);
- asd->scan_flags |= SCAN_SSL_CERTIFICATE_FLAG;
- asd->scan_flags |= SCAN_DO_NOT_OVERRIDE_COMMON_NAME_FLAG;
+ if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
+ {
+ ssl_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);
+ }
}
if (org_unit)
{
- ssl_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit), client_id,
- payload_id);
- asd->tsession->set_tls_org_unit(org_unit, strlen(org_unit));
- asd->scan_flags |= SCAN_DO_NOT_OVERRIDE_ORG_NAME_FLAG;
+ asd->tsession->set_tls_org_unit(org_unit, strlen(org_unit));
+ if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
+ {
+ ssl_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_CERTVIZ_ENABLED_FLAG;
+
service_id = asd->get_application_ids_service();
AppId misc_id = asd->get_application_ids_misc();
{
SslPatternMatchers& ssl_matchers = inspector->get_ctxt().get_odp_ctxt().get_ssl_matchers();
- if (server_name)
+ if (server_name and !sni_mismatch)
ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
client_id, payload_id);
-
- if (common_name)
+ if (first_alt_name and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
+ ssl_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
+ client_id, payload_id);
+ if (common_name and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id,
payload_id);
-
- if (org_unit)
+ if (org_unit and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
ssl_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit), client_id,
payload_id);
-
}
}
uint32_t produce_ha_state(const Flow& flow, uint8_t* buf);
uint32_t consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t length, IpProtocol,
SfIp*, uint16_t initiatorPort);
- bool ssl_app_group_id_lookup(Flow* flow, const char*, const char*, AppId& service_id,
- AppId& client_id, AppId& payload_id, const char* org_unit = nullptr);
+ bool ssl_app_group_id_lookup(Flow* flow, const char*, const char*, const char*,
+ const char*, bool, AppId& service_id, AppId& client_id, AppId& payload_id);
AppIdSessionApi* create_appid_session_api(const Flow& flow);
void free_appid_session_api(AppIdSessionApi* api);
bool is_inspection_needed(const Inspector& g) const;
#define SCAN_HTTP_XWORKINGWITH_FLAG (1<<7)
#define SCAN_HTTP_CONTENT_TYPE_FLAG (1<<8)
#define SCAN_HTTP_URI_FLAG (1<<9)
-#define SCAN_DO_NOT_OVERRIDE_SERVER_NAME_FLAG (1<<10)
-#define SCAN_DO_NOT_OVERRIDE_COMMON_NAME_FLAG (1<<11)
-#define SCAN_DO_NOT_OVERRIDE_ORG_NAME_FLAG (1<<12)
+#define SCAN_CERTVIZ_ENABLED_FLAG (1<<10)
+#define SCAN_SPOOFED_SNI_FLAG (1<<11)
class AppIdPatternMatchNode
{
AppId payload_id = 0;
const char* tls_str = tsession->get_tls_host();
+ if (scan_flags & SCAN_CERTVIZ_ENABLED_FLAG)
+ return;
+
if ((scan_flags & SCAN_SSL_HOST_FLAG) and tls_str)
{
size_t size = strlen(tls_str);
init_bytes_without_reply > ctxt.get_odp_ctxt().max_bytes_before_service_fail));
}
-void AppIdSession::free_tls_session_data()
-{
- if (tsession)
- {
- tsession->free_data();
- snort_free(tsession);
- tsession = nullptr;
- }
-}
-
void AppIdSession::delete_session_data()
{
service.reset();
}
delete_all_http_sessions();
- free_tls_session_data();
+ if (tsession)
+ delete tsession;
delete dsession;
}
uint16_t initiator_port = 0;
};
-// FIXIT-L: make these const strings
-struct TlsSession
+enum MatchedTlsType
{
- char* get_tls_host() { return tls_host; }
+ MATCHED_TLS_NONE = 0,
+ MATCHED_TLS_HOST,
+ MATCHED_TLS_FIRST_SAN,
+ MATCHED_TLS_CNAME,
+ MATCHED_TLS_ORG_UNIT,
+};
+
+class TlsSession
+{
+public:
+ ~TlsSession()
+ {
+ if (tls_host)
+ snort_free(tls_host);
+ 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);
+ }
- char* get_tls_cname() { return tls_cname; }
+ const char* get_tls_host() const
+ {
+ switch (matched_tls_type)
+ {
+ case MATCHED_TLS_HOST:
+ return tls_host;
+ case MATCHED_TLS_FIRST_SAN:
+ return tls_first_alt_name;
+ case MATCHED_TLS_CNAME:
+ return tls_cname;
+ default:
+ if (tls_host)
+ return tls_host;
+ else if (tls_first_alt_name)
+ return tls_first_alt_name;
+ else if (tls_cname)
+ return tls_cname;
+ }
+ return nullptr;
+ }
- char* get_tls_org_unit() { return tls_org_unit; }
+ const char* get_tls_first_alt_name() const { return tls_first_alt_name; }
+
+ const char* get_tls_cname() const { return tls_cname; }
+
+ const char* get_tls_org_unit() const { return tls_org_unit; }
bool get_tls_handshake_done() { return tls_handshake_done; }
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)
+ {
+ if (tls_first_alt_name)
+ snort_free(tls_first_alt_name);
+ if (!new_tls_first_alt_name or *new_tls_first_alt_name == '\0')
+ {
+ tls_first_alt_name = nullptr;
+ return;
+ }
+ 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)
{
if (tls_cname)
void set_tls_handshake_done() { tls_handshake_done = true; }
- void free_data()
+ void set_matched_tls_type(MatchedTlsType type)
{
- if (tls_host)
- snort_free(tls_host);
- if (tls_cname)
- snort_free(tls_cname);
- if (tls_org_unit)
- snort_free(tls_org_unit);
- tls_host = tls_cname = tls_org_unit = nullptr;
- tls_handshake_done = false;
+ matched_tls_type = type;
}
private:
char* tls_host = nullptr;
+ char* tls_first_alt_name = nullptr;
char* tls_cname = nullptr;
char* tls_org_unit = nullptr;
bool tls_handshake_done = false;
+ MatchedTlsType matched_tls_type = MATCHED_TLS_NONE;
};
class AppIdSession : public snort::FlowData
void* remove_flow_data(unsigned id);
void free_flow_data_by_id(unsigned id);
void free_flow_data_by_mask(unsigned mask);
- void free_tls_session_data();
void free_flow_data();
AppId pick_service_app_id();
return asd->service_port;
}
-char* AppIdSessionApi::get_tls_host()
+const char* AppIdSessionApi::get_tls_host()
{
if (asd->tsession)
- {
- if (asd->tsession->get_tls_host())
- return asd->tsession->get_tls_host();
- else
- return asd->tsession->get_tls_cname();
- }
-
+ return asd->tsession->get_tls_host();
return nullptr;
}
SfIp* get_initiator_ip();
AppIdDnsSession* get_dns_session();
AppIdHttpSession* get_http_session(uint32_t stream_index = 0);
- char* get_tls_host();
+ const char* get_tls_host();
DHCPData* get_dhcp_fp_data();
void free_dhcp_fp_data(DHCPData*);
DHCPInfo* get_dhcp_info();
const uint8_t* str = data + offsetof(ServiceSSLV3ExtensionServerName, string_length) +
sizeof(ext->string_length);
- ss->host_name = (char*)snort_alloc(len + 1); //Plus nullptr term.
- memcpy(ss->host_name, str, len);
- ss->host_name[len] = '\0';
+ ss->host_name = snort_strndup((const char*)str, len);
ss->host_name_strlen = len;
return;
}
}
}
-static bool parse_certificates(ServiceSSLData* ss, AppIdDiscoveryArgs& args)
+static bool parse_certificates(ServiceSSLData* ss)
{
bool success = false;
if (ss->certs_data and ss->certs_len)
{
if ((cert_name = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0)))
{
- if (!(args.asd.scan_flags & SCAN_DO_NOT_OVERRIDE_COMMON_NAME_FLAG) and !common_name)
+ if (!common_name)
{
if ((start = strstr(cert_name, COMMON_NAME_STR)))
{
start = nullptr;
}
}
- if (!(args.asd.scan_flags & SCAN_DO_NOT_OVERRIDE_ORG_NAME_FLAG) and !org_name)
+ if (!org_name)
{
if ((start = strstr(cert_name, COMMON_NAME_STR)))
{
{
ss->state = SSL_STATE_CONNECTION;
- if (!(args.asd.scan_flags & SCAN_DO_NOT_OVERRIDE_SERVER_NAME_FLAG) and
+ if (!(args.asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
args.dir == APP_ID_FROM_INITIATOR)
{
parse_client_initiation(data, size, ss);
success:
if (ss->certs_data && ss->certs_len)
{
- if (!((args.asd.scan_flags & SCAN_DO_NOT_OVERRIDE_COMMON_NAME_FLAG) and
- (args.asd.scan_flags & SCAN_DO_NOT_OVERRIDE_ORG_NAME_FLAG)) and
- (!parse_certificates(ss, args)))
+ if (!(args.asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
+ (!parse_certificates(ss)))
{
goto fail;
}
if (ss->host_name || ss->common_name || ss->org_name)
{
if (!args.asd.tsession)
- args.asd.tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
+ args.asd.tsession = new TlsSession();
/* TLS Host */
if (ss->host_name)
DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
}
-bool SslPatternMatchers::scan_hostname(unsigned char const*, unsigned long, AppId& client_id, AppId& payload_id)
+bool SslPatternMatchers::scan_hostname(unsigned char const* server_name, unsigned long, AppId& client_id, AppId& payload_id)
{
- client_id = APPID_UT_ID + 1;
- payload_id = APPID_UT_ID + 1;
+ if (((const char*)server_name) == APPID_UT_TLS_HOST)
+ {
+ client_id = APPID_UT_ID + 1;
+ payload_id = APPID_UT_ID + 1;
+ }
+ else
+ {
+ client_id = 0;
+ payload_id = 0;
+ }
return true;
}
}
else
{
- client_id = APPID_UT_ID + 3;
- payload_id = APPID_UT_ID + 3;
+ client_id = 0;
+ payload_id = 0;
}
return true;
}
AppId service, client, payload = APP_ID_NONE;
bool val = false;
mock_session->common.flow_type = APPID_FLOW_TYPE_IGNORE;
- val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, service, client, payload);
+ val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, nullptr, nullptr,
+ false, service, client, payload);
CHECK_TRUE(!val);
CHECK_EQUAL(service, APP_ID_NONE);
CHECK_EQUAL(client, APP_ID_NONE);
CHECK_EQUAL(payload, APP_ID_NONE);
mock_session->common.flow_type = APPID_FLOW_TYPE_NORMAL;
- val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, service, client, payload);
+ val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, nullptr, nullptr,
+ false, service, client, payload);
CHECK_TRUE(val);
CHECK_EQUAL(service, APPID_UT_ID);
CHECK_EQUAL(client, APPID_UT_ID);
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, nullptr, service, client, payload);
+ 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_first_alt_name(), APPID_UT_TLS_HOST);
+ STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
STRCMP_EQUAL("Published change_bits == 000001000110", test_log);
AppidChangeBits change_bits;
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*)APPID_UT_TLS_HOST,
- (const char*)APPID_UT_TLS_HOST, service, client, payload);
+ 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("Published change_bits == 000001000110", test_log);
string host = "";
- val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()),
- (const char*)APPID_UT_TLS_HOST, service, client, payload, (const char*)("Google"));
+ val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
+ (const char*)APPID_UT_TLS_HOST, (const char*)"Google", 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_host(), nullptr);
+ 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(), "Google");
- STRCMP_EQUAL("Published change_bits == 000001000110", test_log);
+ STRCMP_EQUAL("Published change_bits == 000001000000", test_log);
mock().checkExpectations();
}
{
// Testing set_tls_host
AppidChangeBits change_bits;
- const char* host = "www.cisco.com";
+ char* host = snort_strdup(APPID_UT_TLS_HOST);
TlsSession tls;
tls.set_tls_host(host, 0, change_bits);
TEST(appid_session_api, get_tls_host)
{
AppidChangeBits change_bits;
- mock_session->tsession->set_tls_host(APPID_UT_TLS_HOST, 0, change_bits);
+ char* host = snort_strdup(APPID_UT_TLS_HOST);
+ mock_session->tsession->set_tls_host(host, 0, change_bits);
const char* val = appid_session_api->get_tls_host();
STRCMP_EQUAL(val, APPID_UT_TLS_HOST);
}
CHECK_FALSE(val);
mock_session->service_disco_state = APPID_DISCO_STATE_STATEFUL;
mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
- mock_session->tsession->set_tls_host(APPID_UT_TLS_HOST, 0, change_bits);
+ char* host = snort_strdup(APPID_UT_TLS_HOST);
+ mock_session->tsession->set_tls_host(host, 0, change_bits);
val = appid_session_api->is_http_inspection_done();
CHECK_TRUE(val);
mock_session->service_disco_state = APPID_DISCO_STATE_FINISHED;
asd.set_session_flags(APPID_SESSION_SSL_SESSION);
if (!asd.tsession)
- asd.tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
+ asd.tsession = new TlsSession();
if (!asd.client.get_id())
asd.set_client_appid_data(APP_ID_SSL_CLIENT, change_bits);
reinspect_ssl_appid = check_ssl_appid_for_reinspect(tmpAppId, asd.ctxt.get_odp_ctxt());
- if (!(asd.scan_flags & SCAN_DO_NOT_OVERRIDE_SERVER_NAME_FLAG) and
+ if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
asd.tsession->get_tls_host() == nullptr and
(field = attribute_data.tls_host(false)) != nullptr)
{
asd.scan_flags |= SCAN_SSL_HOST_FLAG;
}
- if (!(asd.scan_flags & SCAN_DO_NOT_OVERRIDE_COMMON_NAME_FLAG) and
+ if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
asd.tsession->get_tls_cname() == nullptr and
(field = attribute_data.tls_cname()) != nullptr)
{
if (reinspect_ssl_appid)
{
- if (!(asd.scan_flags & SCAN_DO_NOT_OVERRIDE_ORG_NAME_FLAG) and
+ if (!(asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and
asd.tsession->get_tls_org_unit() == nullptr and
(field = attribute_data.tls_org_unit()) != nullptr)
{
{
const string* field = 0;
if ( !asd.tsession )
- asd.tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
+ asd.tsession = new TlsSession();
if ( (field=attribute_data.quic_sni()) != nullptr )
{
}
else
{
- asd.set_tp_payload_app_id(*p, direction, tp_app_id, change_bits);
+ if (!(asd.scan_flags & SCAN_SPOOFED_SNI_FLAG))
+ asd.set_tp_payload_app_id(*p, direction, tp_app_id, change_bits);
tp_app_id = portAppId;
if (appidDebug->is_active())
{