return false;
}
+bool HostTracker::update_service_user(Port port, IpProtocol proto, const char* user)
+{
+ host_tracker_stats.service_finds++;
+ lock_guard<mutex> lck(host_tracker_lock);
+
+ for ( auto& s : services )
+ {
+ if ( s.port == port and s.proto == proto )
+ {
+ if ( user and strncmp(user, s.user, INFO_SIZE) )
+ {
+ strncpy(s.user, user, INFO_SIZE);
+ s.user[INFO_SIZE-1] = '\0';
+ return true;
+ }
+ return false;
+ }
+ }
+ return false;
+}
+
void HostTracker::remove_inferred_services()
{
lock_guard<mutex> lck(host_tracker_lock);
bool inferred_appid = false;
uint32_t hits = 0;
uint32_t last_seen = 0;
+ char user[INFO_SIZE] = { 0 };
std::vector<HostApplicationInfo, HostAppInfoAllocator> info;
};
void update_service(const HostApplication& ha);
bool update_service_info(HostApplication& ha, const char* vendor, const char* version,
uint16_t max_info);
+ bool update_service_user(Port, IpProtocol, const char* username);
void remove_inferred_services();
size_t get_client_count();
fclose(config_file);
}
-void AppInfoManager::dump_appid_configurations(std::string file_path)
+void AppInfoManager::dump_appid_configurations(const std::string& file_path) const
{
std::ifstream conf_file(file_path);
if (!conf_file.is_open())
void cleanup_appid_info_table();
void dump_app_info_table();
SnortProtocolId add_appid_protocol_reference(const char* protocol, snort::SnortConfig*);
- void dump_appid_configurations(std::string);
+ void dump_appid_configurations(const std::string&) const;
private:
void load_odp_config(OdpContext&, const char* path);
}
}
-void ClientAppDescriptor::update_user(AppId app_id, const char* username)
+void ClientAppDescriptor::update_user(AppId app_id, const char* username, AppidChangeBits& change_bits)
{
if ( my_username != username )
+ {
my_username = username;
+ change_bits.set(APPID_CLIENT_USERNAME_BIT);
+ }
if ( my_user_id != app_id )
{
my_user_id = app_id;
if ( app_id > APP_ID_NONE )
+ {
AppIdPegCounts::inc_user_count(app_id);
+ change_bits.set(APPID_CLIENT_USERID_BIT);
+ }
}
}
my_user_id = APP_ID_NONE;
}
- void update_user(AppId app_id, const char* username);
+ void update_user(AppId app_id, const char* username, AppidChangeBits& change_bits);
AppId get_user_id() const
{
return asd.add_flow_data(data, flow_data_index, fcn);
}
-void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appId, bool success)
+void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appId, bool success,
+ AppidChangeBits& change_bits)
{
- asd.set_client_user(appId, username);
+ asd.set_client_user(appId, username, change_bits);
if ( success )
- asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
+ change_bits.set(APPID_CLIENT_LOGIN_SUCCEEDED_BIT);
else
- asd.clear_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
+ change_bits.reset(APPID_CLIENT_LOGIN_SUCCEEDED_BIT);
}
void AppIdDetector::add_payload(AppIdSession& asd, AppId payload_id)
virtual void* data_get(AppIdSession&);
virtual int data_add(AppIdSession&, void*, AppIdFreeFCN);
- virtual void add_user(AppIdSession&, const char*, AppId, bool);
+ virtual void add_user(AppIdSession&, const char*, AppId, bool, AppidChangeBits&);
virtual void add_payload(AppIdSession&, AppId);
virtual void add_app(AppIdSession& asd, AppId service_id, AppId client_id, const char* version, AppidChangeBits& change_bits)
{
if ( user )
{
if (app_type_flags & APP_TYPE_SERVICE)
- client.update_user(chp_final, user);
+ client.update_user(chp_final, user, change_bits);
else
- client.update_user(asd.get_service_id(), user);
+ client.update_user(asd.get_service_id(), user, change_bits);
user = nullptr;
- asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
+ change_bits.set(APPID_CLIENT_LOGIN_SUCCEEDED_BIT);
}
chp_candidate = 0;
return api.client.get_user_id();
}
- void set_client_user(AppId id, const char* username)
+ void set_client_user(AppId id, const char* username, AppidChangeBits& change_bits)
{
- api.client.update_user(id, username);
+ api.client.update_user(id, username, change_bits);
}
AppId get_payload_id() const
subtype = service.get_subtype();
}
+const char* AppIdSessionApi::get_client_info(AppId& service) const
+{
+ service = client.get_user_id();
+ return client.get_username();
+}
+
AppId AppIdSessionApi::get_misc_app_id(uint32_t stream_index) const
{
if (get_service_app_id() == APP_ID_HTTP2)
#define APPID_SESSION_RESPONDER_CHECKED (1ULL << 26)
#define APPID_SESSION_INITIATOR_CHECKED (1ULL << 27)
#define APPID_SESSION_SSL_SESSION (1ULL << 28)
-#define APPID_SESSION_LOGIN_SUCCEEDED (1ULL << 29)
-#define APPID_SESSION_SPDY_SESSION (1ULL << 30)
-#define APPID_SESSION_ENCRYPTED (1ULL << 31)
-#define APPID_SESSION_APP_REINSPECT (1ULL << 32)
-#define APPID_SESSION_RESPONSE_CODE_CHECKED (1ULL << 33)
-#define APPID_SESSION_REXEC_STDERR (1ULL << 34)
-#define APPID_SESSION_CHP_INSPECTING (1ULL << 35)
-#define APPID_SESSION_STICKY_SERVICE (1ULL << 36)
-#define APPID_SESSION_APP_REINSPECT_SSL (1ULL << 37)
-#define APPID_SESSION_NO_TPI (1ULL << 38)
-#define APPID_SESSION_FUTURE_FLOW_IDED (1ULL << 39)
-#define APPID_SESSION_OOO_CHECK_TP (1ULL << 40)
-#define APPID_SESSION_PAYLOAD_SEEN (1ULL << 41)
-#define APPID_SESSION_HOST_CACHE_MATCHED (1ULL << 42)
-#define APPID_SESSION_DECRYPT_MONITOR (1ULL << 43)
-#define APPID_SESSION_HTTP_TUNNEL (1ULL << 44)
+#define APPID_SESSION_SPDY_SESSION (1ULL << 29)
+#define APPID_SESSION_ENCRYPTED (1ULL << 30)
+#define APPID_SESSION_APP_REINSPECT (1ULL << 31)
+#define APPID_SESSION_RESPONSE_CODE_CHECKED (1ULL << 32)
+#define APPID_SESSION_REXEC_STDERR (1ULL << 33)
+#define APPID_SESSION_CHP_INSPECTING (1ULL << 34)
+#define APPID_SESSION_STICKY_SERVICE (1ULL << 35)
+#define APPID_SESSION_APP_REINSPECT_SSL (1ULL << 36)
+#define APPID_SESSION_NO_TPI (1ULL << 37)
+#define APPID_SESSION_FUTURE_FLOW_IDED (1ULL << 38)
+#define APPID_SESSION_OOO_CHECK_TP (1ULL << 39)
+#define APPID_SESSION_PAYLOAD_SEEN (1ULL << 40)
+#define APPID_SESSION_HOST_CACHE_MATCHED (1ULL << 41)
+#define APPID_SESSION_DECRYPT_MONITOR (1ULL << 42)
+#define APPID_SESSION_HTTP_TUNNEL (1ULL << 43)
#define APPID_SESSION_IGNORE_ID_FLAGS \
(APPID_SESSION_FUTURE_FLOW | \
APPID_SESSION_NOT_A_SERVICE | \
AppId get_service_app_id() const;
void get_service_info(const char*& vendor, const char*& version,
const AppIdServiceSubtype*& subtype) const;
+ const char* get_client_info(AppId& service) const;
AppId get_misc_app_id(uint32_t stream_index = 0) const;
AppId get_client_app_id(uint32_t stream_index = 0) const;
AppId get_payload_app_id(uint32_t stream_index = 0) const;
char username[USERNAME_LEN];
if ( check_username(cur, tlv, username, username + USERNAME_LEN - 1) )
- add_user(args.asd, username, APP_ID_AOL_INSTANT_MESSENGER, true);
+ add_user(args.asd, username, APP_ID_AOL_INSTANT_MESSENGER, true, args.change_bits);
}
break;
case 0x0003:
user_size = TNS_MAX_INFO_SIZE;
memcpy(username, &args.data[user_start], user_size);
username[user_size] = 0;
- add_user(args.asd, username, APP_ID_ORACLE_DATABASE, true);
+ add_user(args.asd, username, APP_ID_ORACLE_DATABASE, true, args.change_bits);
}
return APPID_SUCCESS;
}
void AppIdDetector::reload() { }
int AppIdDetector::data_add(AppIdSession&, void*, AppIdFreeFCN){return 0;}
void* AppIdDetector::data_get(AppIdSession&) {return nullptr;}
-void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool){}
+void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool, AppidChangeBits&){}
void AppIdDetector::add_payload(AppIdSession&, AppId){}
void AppIdDetector::add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&){}
void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int,
}
static int imap_server_validate(ImapDetectorData* dd, const uint8_t* data, uint16_t size,
- AppIdSession& asd, AppIdDetector* detector)
+ AppIdSession& asd, AppidChangeBits& change_bits, AppIdDetector* detector)
{
const uint8_t* end = data + size;
ImapServiceData* id = &dd->server;
case IMAP_STATE_MID_OK_LOGIN:
// add user successful - note: use of LOGIN cmd implies no IMAPS
if ((id->flags & IMAP_FLAG_RESULT_OK) && dd->client.username[0])
- detector->add_user(asd, dd->client.username, APP_ID_IMAP, true);
+ detector->add_user(asd, dd->client.username, APP_ID_IMAP, true, change_bits);
id->state = IMAP_STATE_MID_LINE;
break;
id->state = IMAP_STATE_ALNUM_CODE_TERM;
// add user login failed - note: use of LOGIN cmd implies no IMAPS
if ((id->flags & IMAP_FLAG_RESULT_NO) && dd->client.username[0])
- detector->add_user(asd, dd->client.username, APP_ID_IMAP, false);
+ detector->add_user(asd, dd->client.username, APP_ID_IMAP, false, change_bits);
}
}
else
if (args.dir == APP_ID_FROM_RESPONDER)
{
- if (imap_server_validate(dd, args.data, args.size, args.asd, this))
+ if (imap_server_validate(dd, args.data, args.size, args.asd, args.change_bits, this))
args.asd.clear_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return APPID_INPROCESS;
}
return APPID_SUCCESS;
}
- if (!imap_server_validate(dd, args.data, args.size, args.asd, this))
+ if (!imap_server_validate(dd, args.data, args.size, args.asd, args.change_bits, this))
{
if ((id->flags & IMAP_FLAG_RESULT_OK) &&
dd->client.state == IMAP_CLIENT_STATE_STARTTLS_CMD)
{
krb_service_detector->add_user(asd,
(krbs->flags & KRB_FLAG_USER_DETECTED) ? krbs->cname : reqCname,
- APP_ID_LDAP, false);
+ 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);
+ krb_service_detector->add_user(asd, krbs->cname, APP_ID_LDAP, true, change_bits);
krbs->flags = 0;
}
{
if (pd->error)
{
- pop3_service_detector->add_user(asd, dd->client.username, APP_ID_POP3, false);
+ pop3_service_detector->add_user(asd, dd->client.username, APP_ID_POP3, false, change_bits);
snort_free(dd->client.username);
dd->client.username = nullptr;
}
else
{
- pop3_service_detector->add_user(asd, dd->client.username, APP_ID_POP3, true);
+ pop3_service_detector->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;
client->add_app(asd, APP_ID_SIP, client_id, client_version, change_bits);
if ( !fd->user_name.empty() )
- client->add_user(asd, fd->user_name.c_str(), APP_ID_SIP, true);
+ client->add_user(asd, fd->user_name.c_str(), APP_ID_SIP, true, change_bits);
}
void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd,
void ApplicationDescriptor::set_id(AppId){}
void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
void ServiceAppDescriptor::update_stats(AppId, bool){}
-void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_user(AppId, const char*, AppidChangeBits&){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
void ServiceDiscovery::initialize() {}
const char* userName = lua_tostring(L, 2);
unsigned int service_id = lua_tonumber(L, 3);
ud->cd->add_user(*lsd->ldp.asd, userName,
- ud->get_odp_ctxt().get_app_info_mgr().get_appid_by_service_id(service_id), true);
+ ud->get_odp_ctxt().get_app_info_mgr().get_appid_by_service_id(service_id), true,
+ *lsd->ldp.change_bits);
lua_pushnumber(L, 0);
return 1;
}
if (args.asd.get_odp_ctxt().mdns_user_reporting)
{
MatchedPatterns* pattern_list = nullptr;
- analyze_user(args.asd, args.pkt, args.size, pattern_list);
+ analyze_user(args.asd, args.pkt, args.size, args.change_bits, pattern_list);
destroy_match_list(pattern_list);
goto success;
}
3. Calls the function which does the Username reporting along with the host
MDNS User Analysis*/
int MdnsServiceDetector::analyze_user(AppIdSession& asd, const Packet* pkt, uint16_t size,
- MatchedPatterns*& pattern_list)
+ AppidChangeBits& change_bits, MatchedPatterns*& pattern_list)
{
int start_index = 0;
uint16_t data_size = size;
user_index++;
}
- add_user(asd, user_name, APP_ID_MDNS, true);
+ add_user(asd, user_name, APP_ID_MDNS, true, change_bits);
break;
}
memcpy(user_name, user_name_bkp + user_index,
user_name_len - user_index);
user_name[ user_name_len - user_index ] = '\0';
- add_user(asd, user_name, APP_ID_MDNS, true);
+ add_user(asd, user_name, APP_ID_MDNS, true, change_bits);
return 1;
}
else
void destroy_match_list(MatchedPatterns*& pattern_list);
int validate_reply(const uint8_t* data, uint16_t size);
int analyze_user(AppIdSession&, const snort::Packet*, uint16_t size,
- MatchedPatterns*& pattern_list);
+ AppidChangeBits& change_bits, MatchedPatterns*& pattern_list);
int reference_pointer(const char* start_ptr, const char** resp_endptr, int* start_index,
uint16_t data_size, uint8_t* user_name_len, unsigned size, MatchedPatterns*& pattern_list);
void AppIdDetector::reload() { }
int AppIdDetector::data_add(AppIdSession&, void*, AppIdFreeFCN){return 0;}
void* AppIdDetector::data_get(AppIdSession&) {return nullptr;}
-void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool){}
+void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool, AppidChangeBits&){}
void AppIdDetector::add_payload(AppIdSession&, AppId){}
void AppIdDetector::add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&){}
void ApplicationDescriptor::set_id(AppId){}
void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
void ServiceAppDescriptor::update_stats(AppId, bool){}
-void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_user(AppId, const char*, AppidChangeBits&){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int,
CHECK_EQUAL(service, APPID_UT_ID);
CHECK_EQUAL(client, APPID_UT_ID);
CHECK_EQUAL(payload, APPID_UT_ID);
- STRCMP_EQUAL("Published change_bits == 00000000000000000", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000000000000", test_log);
service = APP_ID_NONE;
client = APP_ID_NONE;
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 == 00000000100011000", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log);
mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits);
mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits);
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 == 00000000100011000", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log);
string host = "";
val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
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 == 00000000100000000", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000100000000", test_log);
mock().checkExpectations();
}
{
const char* username = "snorty";
AppIdDetector* ad = new TestDetector;
- ad->add_user(*mock_session, username, APPID_UT_ID, true);
+ AppidChangeBits cb;
+ ad->add_user(*mock_session, username, APPID_UT_ID, true, cb);
STRCMP_EQUAL(mock_session->get_client_user(), username);
CHECK_TRUE((mock_session->get_client_user_id() == APPID_UT_ID));
- CHECK_TRUE((mock_session->get_session_flags(APPID_SESSION_LOGIN_SUCCEEDED)
- & APPID_SESSION_LOGIN_SUCCEEDED));
delete ad;
}
}
void ServiceAppDescriptor::update_stats(AppId, bool){}
void ServiceAppDescriptor::set_port_service_id(AppId){}
-void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_user(AppId, const char*, AppidChangeBits&){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
// Detect changes in service, client, payload, and misc appid
mock().checkExpectations();
- STRCMP_EQUAL("Published change_bits == 00000000001111100", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000001111100", test_log);
delete &asd->get_api();
delete asd;
// Detect changes in service, client, payload, and misc appid
mock().checkExpectations();
- STRCMP_EQUAL("Published change_bits == 00000000001111100", test_log);
+ STRCMP_EQUAL("Published change_bits == 00000000000001111100", test_log);
delete &asd->get_api();
delete asd;
delete flow;
change_bits.set();
change_bits_to_string(change_bits, str);
STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host,"
- " tls-host, url, user-agent, response, referrer, dns-host, version, service-vendor, service-subtype");
+ " tls-host, url, user-agent, response, referrer, dns-host, version, service-vendor, service-subtype,"
+ " client-username, client-userid, client-login-succeeded");
// Failure of this test is a reminder that enum is changed, hence translator needs update
- CHECK_EQUAL(APPID_MAX_BIT, 17);
+ CHECK_EQUAL(APPID_MAX_BIT, 20);
}
int main(int argc, char** argv)
void ServiceAppDescriptor::set_id(AppId app_id, OdpContext&){ set_id(app_id); }
void ServiceAppDescriptor::update_stats(AppId, bool){}
void ServiceAppDescriptor::set_port_service_id(AppId app_id){ port_service_id = app_id;}
-void ClientAppDescriptor::update_user(AppId app_id, const char* username)
+void ClientAppDescriptor::update_user(AppId app_id, const char* username, AppidChangeBits& change_bits)
{
my_username = username;
my_user_id = app_id;
+ change_bits.set(APPID_CLIENT_USERNAME_BIT);
+ change_bits.set(APPID_CLIENT_USERID_BIT);
}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
service_port = APPID_UT_SERVICE_PORT;
AppidChangeBits change_bits;
- set_client_user(APPID_UT_ID, APPID_UT_USERNAME);
+ set_client_user(APPID_UT_ID, APPID_UT_USERNAME, change_bits);
set_client_version(APPID_UT_CLIENT_VERSION, change_bits);
set_service_vendor(APPID_UT_SERVICE_VENDOR, change_bits);
void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
void ServiceAppDescriptor::update_stats(AppId, bool){}
void ServiceAppDescriptor::set_port_service_id(AppId){}
-void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_user(AppId, const char*, AppidChangeBits&){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
AppIdConfig::~AppIdConfig() { }
}
static inline void process_ftp_control(AppIdSession& asd,
- ThirdPartyAppIDAttributeData& attribute_data)
+ ThirdPartyAppIDAttributeData& attribute_data, AppidChangeBits& change_bits)
{
const string* field=0;
if (!asd.get_odp_ctxt().ftp_userid_disabled &&
(field=attribute_data.ftp_command_user()) != nullptr)
{
- asd.set_client_user(APP_ID_FTP_CONTROL, field->c_str());
- asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
- // attribute_data.ftpCommandUser = nullptr;
+ asd.set_client_user(APP_ID_FTP_CONTROL, field->c_str(), change_bits);
+ change_bits.set(APPID_CLIENT_LOGIN_SUCCEEDED_BIT);
}
}
process_rtmp(asd, attribute_data, confidence, change_bits);
else if (contains(proto_list, APP_ID_FTP_CONTROL))
- process_ftp_control(asd, attribute_data);
+ process_ftp_control(asd, attribute_data, change_bits);
else if (contains(proto_list, APP_ID_QUIC))
process_quic(asd, attribute_data, change_bits);
src_mac, conf, logger, p->flow->client_port, service);
}
- if (appid_change_bits[APPID_CLIENT_BIT] and client > APP_ID_NONE
+ if ( appid_change_bits[APPID_CLIENT_BIT] and client > APP_ID_NONE
and service > APP_ID_NONE )
{
const char* version = appid_session_api.get_client_version();
service);
}
+ // Appid supports only login success event. Change checks once login failure and
+ // logoff is supported
+ if ( appid_change_bits[APPID_CLIENT_LOGIN_SUCCEEDED_BIT] and filter.is_user_monitored(p) )
+ {
+ AppId service;
+ const char* username = appid_session_api.get_client_info(service);
+ if ( service > APP_ID_NONE and username and *username )
+ discover_user(p, ht, (const struct in6_addr*) src_ip->get_ip6_ptr(), src_mac,
+ logger, username, service, proto);
+ }
+
if ( p->is_from_client() and ( appid_change_bits[APPID_HOST_BIT] or
appid_change_bits[APPID_USERAGENT_BIT] ) )
{
}
}
+void RnaAppDiscovery::discover_user(const Packet* p, RnaTracker& rt,
+ const struct in6_addr* src_ip, const uint8_t* src_mac, RnaLogger& logger,
+ const char* username, AppId service, IpProtocol proto)
+{
+ if ( rt->update_service_user(p->flow->server_port, proto, username) )
+ {
+ logger.log(RUA_EVENT, CHANGE_USER_LOGIN, p, &rt, src_ip, src_mac, username,
+ service, (uint32_t) packet_time());
+ }
+}
+
void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, const char* host,
const char* uagent, RnaTracker& rt, const SfIp* ip, const uint8_t* src_mac, RnaLogger& logger)
{
static void discover_client(const snort::Packet* p, RnaTracker& rt,
const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf,
RnaLogger& logger, const char* version, AppId client, AppId service);
+
+ static void discover_user(const snort::Packet*, RnaTracker&, const struct in6_addr*,
+ const uint8_t* src_mac, RnaLogger&, const char* username, AppId, IpProtocol);
private:
static void update_service_info(const snort::Packet* p, IpProtocol proto, const char* vendor,
const char* version, RnaTracker& rt, const snort::SfIp* ip, const uint8_t* src_mac,
ip.set(rle.ip); // using this instead of packet's ip to support ARP
debug_logf(rna_trace, nullptr, "RNA log: type %u, subtype %u, mac %s, ip %s\n",
rle.type, rle.subtype, macbuf, ip.ntop(ipbuf));
- if (rle.hc)
+ if ( rle.hc )
{
- if (rle.hc->version[0] != '\0')
+ if ( rle.hc->version[0] != '\0' )
debug_logf(rna_trace, nullptr,
"RNA client log: client %u, service %u, version %s\n",
rle.hc->id, rle.hc->service, rle.hc->version);
debug_logf(rna_trace, nullptr, "RNA client log: client %u, service %u\n",
rle.hc->id, rle.hc->service);
}
- if (rle.ha)
+ if ( rle.ha )
{
debug_logf(rna_trace, nullptr,
"RNA Service Info log: appid: %d proto %u, port: %u\n",
rle.ha->appid, (uint32_t)rle.ha->proto, rle.ha->port);
- for (auto& s: rle.ha->info)
+ for ( auto& s: rle.ha->info )
{
- if (s.vendor[0] != '\0')
+ if ( s.vendor[0] != '\0' )
debug_logf(rna_trace, nullptr, "RNA Service Info log: vendor: %s\n",
s.vendor);
- if (s.version[0] != '\0')
+ if ( s.version[0] != '\0' )
debug_logf(rna_trace, nullptr, "RNA Service Info log: version: %s\n",
s.version);
}
}
+
+ if ( rle.user )
+ {
+ if ( rle.user and *rle.user )
+ debug_logf(rna_trace, nullptr,
+ "RNA user login: service %u, user name %s\n", rle.appid, rle.user);
+ }
}
else
debug_logf(rna_trace, nullptr, "RNA log: type %u, subtype %u, mac %s\n",
const struct in6_addr* src_ip, const uint8_t* src_mac, const HostApplication* ha)
{
log(type, subtype, src_ip, src_mac, ht, p, 0, 0,
- nullptr, ha, nullptr, nullptr, nullptr);
+ nullptr, ha);
+}
+
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+ const struct in6_addr* src_ip, const uint8_t* src_mac, const char* user, AppId appid,
+ uint32_t event_time)
+{
+ log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
+ nullptr, nullptr, nullptr, nullptr, nullptr, user, appid);
}
void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
uint32_t event_time)
{
log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
- nullptr, nullptr, fp, nullptr, nullptr);
+ nullptr, nullptr, fp);
}
void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t event_time)
{
- log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
- nullptr, nullptr, nullptr, nullptr, nullptr);
+ log(type, subtype, src_ip, src_mac, ht, p, event_time);
}
void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
const struct in6_addr* src_ip, const uint8_t* src_mac, const HostMac* hm, uint32_t event_time)
{
- log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
- hm, nullptr, nullptr, nullptr, nullptr);
+ log(type, subtype, src_ip, src_mac, ht, p, event_time, 0, hm);
}
void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
uint16_t proto, const uint8_t* src_mac, const struct in6_addr* src_ip, uint32_t event_time)
{
- log(type, subtype, src_ip, src_mac, ht, p, event_time, proto,
- nullptr, nullptr, nullptr, nullptr, nullptr);
+ log(type, subtype, src_ip, src_mac, ht, p, event_time, proto);
}
void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, const uint8_t* src_mac,
const struct in6_addr* src_ip, RnaTracker* ht, uint32_t event_time, void* cond_var)
{
log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
- nullptr, nullptr, nullptr, cond_var, nullptr);
+ nullptr, nullptr, nullptr, cond_var);
}
bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip,
const uint8_t* src_mac, RnaTracker* ht, const Packet* p, uint32_t event_time,
uint16_t proto, const HostMac* hm, const HostApplication* ha,
- const FpFingerprint* fp, void* cond_var, const HostClient* hc)
+ const FpFingerprint* fp, void* cond_var, const HostClient* hc,
+ const char* user, AppId appid)
{
if ( !enabled )
return false;
assert(ht);
- RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var, ha, fp, hc);
+ RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var, ha, fp, hc, user, appid);
if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) )
rle.ip = src_ip;
else
{
RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker* rt,
const snort::HostMac* hmp, uint16_t pr, void* cv, const snort::HostApplication* hap,
- const snort::FpFingerprint* fpr, const snort::HostClient* hcp) : type(t), subtype(st),
- mac(mc), ht(rt), hm(hmp), proto(pr), cond_var(cv), ha(hap), fp(fpr), hc(hcp)
- { }
+ const snort::FpFingerprint* fpr, const snort::HostClient* hcp, const char* u,
+ int32_t app) : type(t), subtype(st), mac(mc), ht(rt), hm(hmp),
+ proto(pr), cond_var(cv), ha(hap), fp(fpr), hc(hcp), user(u), appid(app) { }
uint32_t event_time = 0;
uint16_t type;
const snort::HostApplication* ha;
const snort::FpFingerprint* fp;
const snort::HostClient* hc;
+ const char* user;
+ AppId appid;
};
class RnaLogger
void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::HostClient* hcp);
+ // for host user
+ void log(uint16_t type, uint16_t subtype, const snort::Packet*, RnaTracker*,
+ const struct in6_addr*, const uint8_t* src_mac, const char* user,
+ AppId appid, uint32_t event_time);
+
// for fingerprint
void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::FpFingerprint* fp,
// for all
bool log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip,
- const uint8_t* src_mac, RnaTracker* ht, const snort::Packet* p,
- uint32_t event_time, uint16_t proto, const snort::HostMac* hm,
- const snort::HostApplication* ha, const snort::FpFingerprint* fp,
- void* cond_var, const snort::HostClient* hc);
+ const uint8_t* src_mac, RnaTracker* ht, const snort::Packet* p = nullptr,
+ uint32_t event_time = 0, uint16_t proto = 0, const snort::HostMac* hm = nullptr,
+ const snort::HostApplication* ha = nullptr, const snort::FpFingerprint* fp = nullptr,
+ void* cond_var = nullptr, const snort::HostClient* hc = nullptr,
+ const char* user = nullptr, AppId appid = APP_ID_NONE);
private:
const bool enabled;
#define CHANGE_HOST_TYPE 16
#define CHANGE_VLAN_TAG 18
+#define RUA_EVENT 1004
+ #define CHANGE_USER_LOGIN 2
+
#endif
APPID_VERSION_BIT,
APPID_SERVICE_VENDOR_BIT,
APPID_SERVICE_SUBTYPE_BIT,
+ APPID_CLIENT_USERNAME_BIT,
+ APPID_CLIENT_USERID_BIT,
+ APPID_CLIENT_LOGIN_SUCCEEDED_BIT,
APPID_MAX_BIT
};
--n? str.append("service-vendor, ") : str.append("service-vendor");
if (change_bits.test(APPID_SERVICE_SUBTYPE_BIT))
--n? str.append("service-subtype, ") : str.append("service-subtype");
+ if (change_bits.test(APPID_CLIENT_USERNAME_BIT))
+ --n? str.append("client-username, ") : str.append("client-username");
+ if (change_bits.test(APPID_CLIENT_USERID_BIT))
+ --n? str.append("client-userid, ") : str.append("client-userid");
+ if (change_bits.test(APPID_CLIENT_LOGIN_SUCCEEDED_BIT))
+ --n? str.append("client-login-succeeded, ") : str.append("client-login-succeeded");
if (n != 0) // make sure all bits from AppidChangeBit enum get translated
str.append("change_bits_to_string error!");
}