]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3383: appid: add alpn matchers
authorPranav Bhalerao (prbhaler) <prbhaler@cisco.com>
Sat, 30 Apr 2022 02:30:17 +0000 (02:30 +0000)
committerPranav Bhalerao (prbhaler) <prbhaler@cisco.com>
Sat, 30 Apr 2022 02:30:17 +0000 (02:30 +0000)
Merge in SNORT/snort3 from ~PRBHALER/snort3:quic_alpn to master

Squashed commit of the following:

commit 77be6266b97de2535006e3ecaa2dc84c8202aefd
Author: Pranav Bhalerao <prbhaler@cisco.com>
Date:   Mon Apr 4 22:16:02 2022 +0530

    appid: add alpn matchers

27 files changed:
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/appid_api.h
src/network_inspectors/appid/appid_app_descriptor.h
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_eve_process_event_handler.cc
src/network_inspectors/appid/appid_eve_process_event_handler.h
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/application_ids.h
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/service_plugins/alpn_patterns.cc [new file with mode: 0644]
src/network_inspectors/appid/service_plugins/alpn_patterns.h [new file with mode: 0644]
src/network_inspectors/appid/service_plugins/test/CMakeLists.txt
src/network_inspectors/appid/service_plugins/test/alpn_patterns_tests.cc [new file with mode: 0644]
src/network_inspectors/appid/service_plugins/test/service_alpn_patterns_mock.h [new file with mode: 0644]
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_eve_process_event_handler_test.cc
src/network_inspectors/appid/test/appid_mock_definitions.h
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/test/tp_lib_handler_test.cc
src/pub_sub/eve_process_event.h
src/pub_sub/test/pub_sub_eve_process_event_test.cc

index 7b7ff55beceaa24bc728da59b5c7a6b69396e712..a1331e54ff2d2c1e08493ba390fe074afafcf037 100644 (file)
@@ -40,6 +40,8 @@ set ( CP_APPID_SOURCES
 )
 
 set ( SP_APPID_SOURCES
+    service_plugins/alpn_patterns.cc
+    service_plugins/alpn_patterns.h
     service_plugins/dcerpc.cc
     service_plugins/dcerpc.h
     service_plugins/service_bgp.cc
index 313321b566dac25517af8e8091af3e745f61a16a..b979e2bb37ed8b9223c76f565faf928379a11715 100644 (file)
@@ -71,6 +71,7 @@ public:
             case APP_ID_SSHELL:
             case APP_ID_SSL:
             case APP_ID_QUIC:
+            case APP_ID_HTTP3:
                 return true;
         }
 
index 26b142de350d5affcd14c0a7d6e644d51cb51c1d..da6e654349a7cd3c8449ecebf3d06236e27cab76 100644 (file)
@@ -207,8 +207,19 @@ public:
         return service_group;
     }
 
+    void set_alpn_service_app_id(AppId id)
+    {
+        alpn_service_app_id = id;
+    }
+
+    AppId get_alpn_service_app_id() const
+    {
+        return alpn_service_app_id;
+    }
+
 private:
     AppId port_service_id = APP_ID_NONE;
+    AppId alpn_service_app_id = APP_ID_NONE;
     bool deferred = false;
     using ApplicationDescriptor::set_id;
     std::string my_vendor;
index 4f040b53c55e83569f50b621efccc8df3fbac2b7..13cd42f34f678dad0b426fff30454cce07b9829d 100644 (file)
@@ -168,6 +168,7 @@ void OdpContext::initialize(AppIdInspector& inspector)
     client_disco_mgr.finalize_client_patterns();
     http_matchers.finalize_patterns();
     eve_ca_matchers.finalize_patterns();
+    alpn_matchers.finalize_patterns();
     // sip patterns need to be finalized after http patterns because they
     // are dependent on http patterns
     sip_matchers.finalize_patterns(*this);
@@ -188,6 +189,7 @@ void OdpContext::reload()
     sip_matchers.reload_patterns();
     ssl_matchers.reload_patterns();
     dns_matchers.reload_patterns();
+    alpn_matchers.reload_patterns();
 }
 
 void OdpContext::add_port_service_id(IpProtocol proto, uint16_t port, AppId appid)
index 4a23839475b73d93ee616c9c1a08a33b7df51c79..1573fd5000f9f20d182151ba6f0982fec06370fd 100644 (file)
@@ -39,6 +39,7 @@
 #include "length_app_cache.h"
 #include "lua_detector_flow_api.h"
 #include "lua_detector_module.h"
+#include "service_plugins/alpn_patterns.h"
 #include "service_plugins/service_discovery.h"
 #include "detector_plugins/ssh_patterns.h"
 #include "tp_appid_module_api.h"
@@ -209,6 +210,11 @@ public:
         return *service_pattern_detector;
     }
 
+    AlpnPatternMatchers& get_alpn_matchers()
+    {
+        return alpn_matchers;
+    }
+
     void add_port_service_id(IpProtocol, uint16_t, AppId);
     void add_protocol_service_id(IpProtocol, AppId);
     AppId get_port_service_id(IpProtocol, uint16_t);
@@ -228,6 +234,7 @@ private:
     SshPatternMatchers ssh_matchers;
     PatternClientDetector* client_pattern_detector;
     PatternServiceDetector* service_pattern_detector;
+    AlpnPatternMatchers alpn_matchers;
 
     std::array<AppId, APP_ID_PORT_ARRAY_SIZE> tcp_port_only = {}; // port-only TCP services
     std::array<AppId, APP_ID_PORT_ARRAY_SIZE> udp_port_only = {}; // port-only UDP services
index 1789b2b22bdeb882460791812241ab6fef49987c..e3bcf76fbc86575b35ff27f588991d73cb35dd1b 100644 (file)
@@ -34,13 +34,35 @@ using namespace snort;
 void AppIdEveProcessEventHandler::handle(DataEvent& event, Flow* flow)
 {
     assert(flow);
+
+    if (!pkt_thread_odp_ctxt)
+        return;
+
+    Packet* p = DetectionEngine::get_current_packet();
+    assert(p);
+
     AppIdSession* asd = appid_api.get_appid_session(*flow);
-    if (!asd or
-        !asd->get_session_flags(APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED))
+    if (!asd)
+    {
+        AppidSessionDirection dir;
+
+        dir = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+
+        asd = AppIdSession::allocate_session(p, p->get_ip_proto_next(), dir,
+            inspector, *pkt_thread_odp_ctxt);
+        if (appidDebug->is_enabled())
+        {
+            appidDebug->activate(flow, asd, inspector.get_ctxt().config.log_all_sessions);
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s New AppId session at mercury event\n",
+                    appidDebug->get_debug_session());
+        }
+    }
+
+    if (!asd->get_session_flags(APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED))
         return;
 
-    if (!pkt_thread_odp_ctxt or
-        (pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version()))
+    if (pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version())
         return;
 
     const EveProcessEvent &eve_process_event = static_cast<EveProcessEvent&>(event);
@@ -48,27 +70,54 @@ void AppIdEveProcessEventHandler::handle(DataEvent& event, Flow* flow)
     const std::string& name = eve_process_event.get_process_name();
     uint8_t conf = eve_process_event.get_process_confidence();
     const std::string& server_name = eve_process_event.get_server_name();
-    AppId app_id = APP_ID_NONE;
+    const std::string& user_agent = eve_process_event.get_user_agent();
+    std::vector<std::string> alpn_vec = eve_process_event.get_alpn();
+    const bool is_quic = eve_process_event.is_flow_quic();
+
+    AppidChangeBits change_bits;
 
-    if (!name.empty())
+    if (is_quic && alpn_vec.size())
     {
-        app_id = asd->get_odp_ctxt().get_eve_ca_matchers().match_eve_ca_pattern(name,
-            conf);
+        AppId service_id = APP_ID_NONE;
+        service_id = asd->get_odp_ctxt().get_alpn_matchers().match_alpn_pattern(alpn_vec[0]);
+        if (service_id)
+        {
+            asd->set_alpn_service_app_id(service_id);
+            asd->update_encrypted_app_id(service_id);
+        }
+        else
+        {
+            asd->set_service_appid_data(APP_ID_QUIC, change_bits);
+            asd->set_session_flags(APPID_SESSION_SERVICE_DETECTED);
+        }
+    }
+
+    AppId client_id = APP_ID_NONE;
+    if (!user_agent.empty())
+    {
+        char* version = nullptr;
+        AppId service_id = APP_ID_NONE;
 
-        asd->set_eve_client_app_id(app_id);
+        asd->get_odp_ctxt().get_http_matchers().identify_user_agent(user_agent.c_str(),
+            user_agent.size(), service_id, client_id, &version);
+
+        if (client_id != APP_ID_NONE)
+            asd->set_client_appid_data(client_id, change_bits, version);
+
+        snort_free(version);
     }
+    else if (!name.empty())
+    {
+        client_id = asd->get_odp_ctxt().get_eve_ca_matchers().match_eve_ca_pattern(name,
+            conf);
 
-    if (appidDebug->is_active())
-        LogMessage("AppIdDbg %s encrypted client app %d process name '%s', "
-            "confidence: %d, server name '%s'\n", appidDebug->get_debug_session(), app_id,
-            name.c_str(), conf, server_name.c_str());
+        asd->set_eve_client_app_id(client_id);
+    }
 
     if (!server_name.empty())
     {
-        AppId client_id;
-        AppId payload_id;
-        AppidChangeBits change_bits;
-        snort::Packet* p = snort::DetectionEngine::get_current_packet();
+        AppId client_id = APP_ID_NONE;
+        AppId payload_id = APP_ID_NONE;
 
         if (!asd->tsession)
             asd->tsession = new TlsSession();
@@ -80,7 +129,34 @@ void AppIdEveProcessEventHandler::handle(DataEvent& event, Flow* flow)
             server_name.length(), client_id, payload_id);
         asd->set_payload_id(payload_id);
         asd->set_ss_application_ids_payload(payload_id, change_bits);
+    }
 
-        asd->publish_appid_event(change_bits, *p);
+    if (appidDebug->is_active())
+    {
+        std::string debug_str;
+
+        debug_str += "encrypted client app: " + std::to_string(client_id);
+        if (!name.empty())
+            debug_str += ", process name: " + name + ", confidence: " + std::to_string(conf);
+
+        if (!server_name.empty())
+            debug_str += ", server name: " + server_name;
+
+        if (!user_agent.empty())
+            debug_str += ", user agent: " + user_agent;
+
+        if (is_quic && alpn_vec.size())
+        {
+            debug_str += ", alpn: [ ";
+            for(unsigned int i = 0; i < alpn_vec.size(); i++)
+                debug_str += alpn_vec[i] + " ";
+            debug_str += "]";
+        }
+
+        LogMessage("AppIdDbg %s %s\n",
+            appidDebug->get_debug_session(), debug_str.c_str());
     }
+
+    if (change_bits.any())
+        asd->publish_appid_event(change_bits, *p);
 }
index 38454feabbe9915cec6f919f3865e7cea434f50a..13046eed364d5a3266f91707e85fbd06af59bd7c 100644 (file)
 class AppIdEveProcessEventHandler : public snort::DataHandler
 {
 public:
-    AppIdEveProcessEventHandler() : DataHandler(MOD_NAME) { }
+    AppIdEveProcessEventHandler(AppIdInspector& inspector) :
+        DataHandler(MOD_NAME), inspector(inspector) { }
 
     void handle(snort::DataEvent& event, snort::Flow* flow) override;
+
+private:
+    AppIdInspector& inspector;
 };
 
 #endif
index ac6521849a40df6eac001de094f60e59601a3496..34d01362b2cada0f09b194e17e7b3b9e0a3fce69 100644 (file)
@@ -138,7 +138,7 @@ bool AppIdInspector::configure(SnortConfig* sc)
 
     DataBus::subscribe_global(OPPORTUNISTIC_TLS_EVENT, new AppIdOpportunisticTlsEventHandler(), *sc);
 
-    DataBus::subscribe_global(EVE_PROCESS_EVENT, new AppIdEveProcessEventHandler(), *sc);
+    DataBus::subscribe_global(EVE_PROCESS_EVENT, new AppIdEveProcessEventHandler(*this), *sc);
 
     DataBus::subscribe_global(SSH_EVENT, new SshEventHandler(), *sc);
 
index 6a510e644fee5f581d73a2106a15f2ad9a4d5f06..7e4cf57a6cfc79945e14cc646959436b0489f50c 100644 (file)
@@ -493,6 +493,9 @@ void AppIdSession::update_encrypted_app_id(AppId service_id)
     case APP_ID_POP3:
         misc_app_id = APP_ID_POP3S;
         break;
+    case APP_ID_HTTP3:
+    case APP_ID_SMB_OVER_QUIC:
+        misc_app_id = APP_ID_QUIC;
     default:
         break;
     }
@@ -768,6 +771,9 @@ AppId AppIdSession::pick_service_app_id() const
 {
     AppId rval = APP_ID_NONE;
 
+    if (api.service.get_alpn_service_app_id() > APP_ID_NONE)
+        return api.service.get_alpn_service_app_id();
+
     if (!tp_appid_ctxt)
     {
         if (is_service_detected())
index 32db58ea625eef60ce0355f84ba1d027a21b8f81..792deb0d8dac35182299ab2cbac4582d85dee1b9 100644 (file)
@@ -526,6 +526,16 @@ public:
             (api.client.get_id() == APP_ID_SSL_CLIENT or api.client.get_id() <= APP_ID_NONE));
     }
 
+    void set_alpn_service_app_id(AppId id)
+    {
+        api.service.set_alpn_service_app_id(id);
+    }
+
+    AppId get_alpn_service_app_id() const
+    {
+        return api.service.get_alpn_service_app_id();
+    }
+
     AppId get_payload_id() const
     {
         return api.payload.get_id();
index 8ad49b09555ad63cbf85ea2095e80678186be435..c9223a05afc15a03d92fff8909e2246a161a9040 100644 (file)
@@ -1015,6 +1015,8 @@ enum ApplicationIds : AppId
     APP_ID_SMB_VERSION_1                  = 4645,
     APP_ID_SMB_VERSION_2                  = 4646,
     APP_ID_SMB_VERSION_3                  = 4647,
+    APP_ID_HTTP3                          = 4667,
+    APP_ID_SMB_OVER_QUIC                  = 4668,
 #ifdef REG_TEST
     APP_ID_DNS_OVER_TLS                   = 4615,
     APP_ID_REGTEST                        = 10000,
index 9db13097d176f99a632dcbb7cbbd9ff846dfef3c..c1f38cfe8235e6cf14a9098e453e9fbedaba90ba 100644 (file)
@@ -156,6 +156,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 
 ClientDetector::ClientDetector() { }
 
index 2fe6aebf91859f72a9d052da99c8154035c36f71..303b9224b3b9d387f42ff182810e375be54fa004 100644 (file)
@@ -87,6 +87,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 void AppIdModule::reset_stats() {}
 bool AppIdInspector::configure(snort::SnortConfig*) { return true; }
 
index 6cbc2593ebf3691f37932c7ae925019cca6902f7..7780d71368c20b4ac224ed4505055d7b5d3b50fd 100644 (file)
@@ -173,7 +173,8 @@ static int service_init(lua_State* L)
     auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     // auto pServiceName = luaL_checkstring(L, 2);
     auto pValidator = luaL_checkstring(L, 3);
@@ -986,6 +987,40 @@ static int client_add_payload(lua_State* L)
     return 1;
 }
 
+/** Add a alpn to service app mapping.
+ *  @param Lua_State* - Lua state variable.
+ *  @param appid/stack - the AppId to map the data to.
+ *  @param alpn  - application protocol negotiations string.
+ */
+static int add_alpn_to_service_mapping(lua_State* L)
+{
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L))
+        return 0;
+    int index = 1;
+
+    uint32_t appid = lua_tointeger(L, ++index);
+
+    // Verify that alpn is a valid string
+    const char* tmp_string = lua_tostring(L, ++index);
+    if (!tmp_string)
+    {
+        ErrorMessage("appid: Invalid alpn service string: appid %u.\n", appid);
+        return 0;
+    }
+    const std::string service_name(tmp_string);
+    const std::string detector_name = ud->get_detector()->get_name();
+
+    ud->get_odp_ctxt().get_alpn_matchers().add_alpn_pattern(appid, service_name, detector_name);
+
+    ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appid);
+
+    return 0;
+}
+
+
 /** Add a fp process to client app mapping.
  *  @param Lua_State* - Lua state variable.
  *  @param appid/stack - the AppId to map the fp data to
@@ -997,7 +1032,8 @@ static int add_process_to_client_mapping(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
     int index = 1;
 
     uint32_t appid = lua_tointeger(L, ++index);
@@ -1054,7 +1090,8 @@ static int detector_add_http_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1096,7 +1133,8 @@ static int detector_add_ssl_cert_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1123,7 +1161,8 @@ static int detector_add_dns_host_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1149,7 +1188,8 @@ static int detector_add_ssl_cname_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1176,7 +1216,8 @@ static int detector_add_host_port_application(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     SfIp ip_address;
     int index = 1;
@@ -1255,7 +1296,8 @@ static int detector_add_content_type_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     size_t stringSize = 0;
     int index = 1;
@@ -1284,7 +1326,8 @@ static int detector_add_ssh_client_pattern(lua_State* L)
 {
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     size_t string_size = 0;
     int index = 1;
@@ -1476,7 +1519,8 @@ static int detector_chp_create_application(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1628,7 +1672,8 @@ static int detector_add_chp_action(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     HttpFieldIds ptype;
     size_t psize;
@@ -1719,7 +1764,8 @@ static int detector_add_chp_multi_action(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     HttpFieldIds ptype;
     size_t psize;
@@ -1765,7 +1811,8 @@ static int detector_port_only_service(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -1911,7 +1958,8 @@ static int detector_add_url_application(lua_State* L)
     // Verify detector user data and that we are NOT in packet context
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2004,7 +2052,8 @@ static int detector_add_rtmp_url(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2097,7 +2146,8 @@ static int detector_add_sip_user_agent(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2216,7 +2266,8 @@ static int add_http_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2255,7 +2306,8 @@ static int add_url_pattern(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2348,7 +2400,8 @@ static int add_port_pattern_client(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     size_t patternSize = 0;
     int index = 1;
@@ -2402,7 +2455,8 @@ static int add_port_pattern_service(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     size_t patternSize = 0;
     int index = 1;
@@ -2437,7 +2491,8 @@ static int detector_add_sip_server(lua_State* L)
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
-    if (!init(L)) return 0;
+    if (!init(L))
+        return 0;
 
     int index = 1;
 
@@ -2725,6 +2780,7 @@ static const luaL_Reg detector_methods[] =
 
     /* add client mapping for process name derived by fingerprinting */
     { "addProcessToClientMapping", add_process_to_client_mapping },
+    { "addAlpnToServiceMapping",  add_alpn_to_service_mapping },
 
     //HTTP Multi Pattern engine
     { "CHPCreateApp",             detector_chp_create_application },
diff --git a/src/network_inspectors/appid/service_plugins/alpn_patterns.cc b/src/network_inspectors/appid/service_plugins/alpn_patterns.cc
new file mode 100644 (file)
index 0000000..44abafa
--- /dev/null
@@ -0,0 +1,117 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// alpn_patterns.cc author Pranav Bhalerao <prbhaler@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "alpn_patterns.h"
+
+#include <algorithm>
+
+#include "log/messages.h"
+#include "utils/util.h"
+#include "appid_debug.h"
+
+using namespace snort;
+using namespace std;
+
+void AlpnPatternMatchers::add_alpn_pattern(AppId app_id, const string& pattern_str,
+    const string& detector)
+{
+    auto match = find_if(alpn_load_list.begin(), alpn_load_list.end(),
+        [pattern_str] (AlpnPattern* alpn) { return alpn->pattern == pattern_str; });
+    if (match != alpn_load_list.end())
+    {
+        if ((*match)->app_id != app_id)
+            WarningMessage("appid: detector %s - alpn '%s' for service app %d is already "
+                "mapped to service app %d\n", detector.c_str(), (*match)->pattern.c_str(), app_id,
+                (*match)->app_id);
+    }
+    else
+    {
+        AlpnPattern* new_alpn_pattern = new AlpnPattern(app_id, pattern_str);
+        alpn_load_list.push_back(new_alpn_pattern);
+    }
+}
+
+static int alpn_pattern_match(void* id, void*, int, void* data, void*)
+{
+    AlpnPatternList* alpn_match_list = (AlpnPatternList *)data;
+    alpn_match_list->push_back((AlpnPattern *)id);
+    return 0;
+}
+
+AppId AlpnPatternMatchers::match_alpn_pattern(const string& pattern)
+{
+    AlpnPatternList* alpn_match_list = new AlpnPatternList();
+    AlpnPattern* best_match = nullptr;
+
+    alpn_pattern_matcher.find_all(pattern.data(), pattern.size(), alpn_pattern_match,
+        false, alpn_match_list);
+
+    for (auto &mp : *alpn_match_list)
+    {
+        if (mp->pattern.size() == pattern.size())
+        {
+            best_match = mp;
+        }
+        else if (!best_match or (mp->pattern.size() > best_match->pattern.size()))
+        {
+            best_match = mp;
+            continue;
+        }
+    }
+
+    AppId ret_app_id = APP_ID_NONE;
+    if (best_match)
+        ret_app_id = best_match->app_id;
+
+    delete alpn_match_list;
+
+    return ret_app_id;
+}
+
+AlpnPatternMatchers::~AlpnPatternMatchers()
+{
+    for (auto& p : alpn_load_list)
+        delete p;
+    alpn_load_list.clear();
+}
+
+void AlpnPatternMatchers::finalize_patterns()
+{
+    for (auto& p : alpn_load_list)
+    {
+        alpn_pattern_matcher.add(p->pattern.data(), p->pattern.size(), p, true);
+
+        #ifdef REG_TEST
+            LogMessage("Adding ALPN service App pattern %d %s\n",
+                p->app_id, p->pattern.c_str());
+        #endif
+    }
+    alpn_pattern_matcher.prep();
+}
+
+void AlpnPatternMatchers::reload_patterns()
+{
+    alpn_pattern_matcher.reload();
+}
+
diff --git a/src/network_inspectors/appid/service_plugins/alpn_patterns.h b/src/network_inspectors/appid/service_plugins/alpn_patterns.h
new file mode 100644 (file)
index 0000000..a2aa88f
--- /dev/null
@@ -0,0 +1,58 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// alpn_patterns.h author Pranav Bhalerao <prbhaler@cisco.com>
+
+#ifndef ALPN_PATTERNS_H
+#define ALPN_PATTERNS_H
+
+#include <vector>
+
+#include "search_engines/search_tool.h"
+#include "application_ids.h"
+
+struct AlpnPattern
+{
+    const AppId app_id;
+    const std::string pattern;
+
+    AlpnPattern(AppId id, const std::string& name) : app_id(id), pattern(name){}
+
+    ~AlpnPattern() {}
+};
+
+typedef std::vector<AlpnPattern*> AlpnPatternList;
+
+class AlpnPatternMatchers
+{
+public:
+    ~AlpnPatternMatchers();
+    AppId match_alpn_pattern(const std::string&);
+    void add_alpn_pattern(AppId, const std::string&, const std::string&);
+    void finalize_patterns();
+    void reload_patterns();
+
+    const AlpnPatternList& get_alpn_load_list() const { return alpn_load_list; }
+
+private:
+    snort::SearchTool alpn_pattern_matcher = snort::SearchTool();
+    AlpnPatternList alpn_load_list;
+};
+
+#endif
+
index d221dfda36fa2e1ac06799902aed674b878ec245..de668cdb2946e8a70a507bbc39bb8191d2fd14e7 100644 (file)
@@ -2,4 +2,5 @@
 include_directories ( appid PRIVATE ${APPID_INCLUDE_DIR} )
 
 add_cpputest( service_rsync_test )
+add_cpputest( alpn_patterns_tests )
 
diff --git a/src/network_inspectors/appid/service_plugins/test/alpn_patterns_tests.cc b/src/network_inspectors/appid/service_plugins/test/alpn_patterns_tests.cc
new file mode 100644 (file)
index 0000000..891735a
--- /dev/null
@@ -0,0 +1,98 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+//
+// alpn_patterns_tests.cc author Pranav Bhalerao <prbhaler@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "service_plugins/alpn_patterns.cc"
+#include "service_alpn_patterns_mock.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+static AlpnPatternMatchers* alpn_matcher = nullptr;
+AlpnPattern alpn_pattern(APPID_UT_ID, "h3");
+
+namespace snort
+{
+int SearchTool::find_all(const char* pattern, unsigned, MpseMatch, bool, void* data)
+{
+    if (strcmp(pattern, "h3") == 0)
+        alpn_pattern_match(&alpn_pattern, nullptr, 0, data, nullptr);
+    return 0;
+}
+}
+
+TEST_GROUP(alpn_patterns_tests)
+{
+    void setup() override
+    {
+        alpn_matcher = new AlpnPatternMatchers();
+    }
+    void teardown() override
+    {
+        delete alpn_matcher;
+    }
+};
+
+
+TEST(alpn_patterns_tests, alpn_pattern_match)
+{
+    AlpnPatternList data;
+    AlpnPattern alpn1(APPID_UT_ID + 1, "h3");
+    alpn_pattern_match(&alpn1, nullptr, 0, &data, nullptr);
+    AlpnPattern* alpn = data.back();
+    CHECK(alpn->app_id == alpn1.app_id);
+    CHECK(alpn->pattern == alpn1.pattern);
+
+    AlpnPattern alpn2(APPID_UT_ID + 2, "smb");
+    alpn_pattern_match(&alpn2, nullptr, 0, &data, nullptr);
+    alpn = data.back();
+    CHECK(alpn->app_id == alpn2.app_id);
+    CHECK(alpn->pattern == alpn2.pattern);
+}
+
+TEST(alpn_patterns_tests, match_alpn_pattern)
+{
+    // 1. pattern not present in pattern matcher list
+    CHECK(alpn_matcher->match_alpn_pattern("smb") == 0);
+
+    // 2. pattern present in pattern matcher list
+    CHECK(alpn_matcher->match_alpn_pattern("h3") == APPID_UT_ID);
+}
+
+TEST(alpn_patterns_tests, add_alpn_pattern)
+{
+    // same alpn mapped to different appid
+    alpn_matcher->add_alpn_pattern(APPID_UT_ID + 1, "h3", "custom_detector.lua");
+    alpn_matcher->add_alpn_pattern(APPID_UT_ID + 2, "h3", "odp_detector.lua");
+
+    CHECK(alpn_matcher->get_alpn_load_list().size() == 1);
+    CHECK(alpn_matcher->get_alpn_load_list()[0]->app_id == APPID_UT_ID + 1);
+}
+
+int main(int argc, char** argv)
+{
+    int return_value = CommandLineTestRunner::RunAllTests(argc, argv);
+    return return_value;
+}
+
diff --git a/src/network_inspectors/appid/service_plugins/test/service_alpn_patterns_mock.h b/src/network_inspectors/appid/service_plugins/test/service_alpn_patterns_mock.h
new file mode 100644 (file)
index 0000000..d2c107a
--- /dev/null
@@ -0,0 +1,38 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2022 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// alpn_patterns_mock.h author Pranav Bhalerao <prbhaler@cisco.com>
+
+#define APPID_UT_ID 1492
+
+namespace snort
+{
+// Stubs for  messages
+void LogMessage(const char*,...) { }
+void WarningMessage(const char*,...) { }
+
+// Stubs for search_tool.cc
+SearchTool::SearchTool(bool) { }
+SearchTool::~SearchTool() = default;
+void SearchTool::add(const char*, unsigned, int, bool) { }
+void SearchTool::add(const char*, unsigned, void*, bool) { }
+void SearchTool::add(const uint8_t*, unsigned, int, bool) { }
+void SearchTool::add(const uint8_t*, unsigned, void*, bool) { }
+void SearchTool::prep() { }
+void SearchTool::reload() { }
+}
+
index 40d83fae4f9acca661bfa338eed63b80c8b57b48..2e6729c1507035a5505ae4b585dad99e9efc07d6 100644 (file)
@@ -24,6 +24,8 @@
 #include "appid_peg_counts.h"
 #include "utils/stats.h"
 
+#define APPID_UT_ID 1492
+
 namespace snort
 {
 // Stubs for messages
@@ -80,6 +82,7 @@ AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
     StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
 }
 
+AlpnPatternMatchers::~AlpnPatternMatchers() {}
 EveCaPatternMatchers::~EveCaPatternMatchers() { }
 SslPatternMatchers::~SslPatternMatchers() { }
 SipPatternMatchers::~SipPatternMatchers() { }
index 281f143832be3e3037b330cccafc8b2726dda4c4..39fdcc59e5817ae6e67a309c603acbe97760b5ad 100644 (file)
@@ -143,6 +143,7 @@ EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
 void ApplicationDescriptor::set_id(AppId app_id){my_id = app_id;}
index 58def9f446c7e4146614ece2a61785428aca1f3a..9b59fbb95aafd04dad346bb68ea3ec7c6dd864f8 100644 (file)
@@ -60,13 +60,20 @@ Packet* DetectionEngine::get_current_packet()
 }
 }
 
+AppIdSession* AppIdSession::allocate_session(const Packet*, IpProtocol,
+    AppidSessionDirection, AppIdInspector&, OdpContext&)
+{
+    return nullptr;
+}
+
 void AppIdSession::publish_appid_event(AppidChangeBits&, const Packet&, bool, uint32_t)
 {
     return;
 }
 
-bool SslPatternMatchers::scan_hostname(const uint8_t*, size_t, AppId&, AppId&)
+bool SslPatternMatchers::scan_hostname(const uint8_t*, size_t, AppId&, AppId& payload)
 {
+    payload = APPID_UT_ID + 1;
     return true;
 }
 
@@ -75,11 +82,34 @@ void AppIdSession::set_ss_application_ids_payload(AppId, AppidChangeBits&)
     return;
 }
 
+void AppIdSession::set_client_appid_data(AppId, AppidChangeBits&, char*)
+{
+    set_client_id(APPID_UT_ID);
+    return;
+}
+
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection,
     AppId, AppidChangeBits&) { }
 void AppIdModule::reset_stats() { }
 void AppIdDebug::activate(snort::Flow const*, AppIdSession const*, bool) { }
 
+void AppIdSession::update_encrypted_app_id(AppId) {}
+void HttpPatternMatchers::identify_user_agent(const char*, int, AppId&, AppId& client, char**)
+{
+    client = APPID_UT_ID;
+}
+
+void AppIdSession::set_service_appid_data(AppId, AppidChangeBits&, char*)
+{
+}
+
+AppId AlpnPatternMatchers::match_alpn_pattern(const string& str)
+{
+    if (!str.compare("h3"))
+        return APPID_UT_ID + 2;
+    else
+        return APP_ID_NONE;
+}
 
 AppId EveCaPatternMatchers::match_eve_ca_pattern(const string&, uint8_t)
 {
@@ -109,13 +139,65 @@ TEST(appid_eve_process_event_handler_tests, eve_process_event_handler)
 {
     Packet p;
     EveProcessEvent event(p, "firefox", 90);
-    AppIdEveProcessEventHandler event_handler;
+    AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
     Flow* flow = new Flow();
     event_handler.handle(event, flow);
     CHECK(session->get_eve_client_app_id() == APPID_UT_ID);
     delete flow;
 }
 
+TEST(appid_eve_process_event_handler_tests, eve_user_agent_event_handler)
+{
+    Packet p;
+    EveProcessEvent event(p, "firefox", 90);
+    event.set_user_agent("chrome");
+    AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
+    Flow* flow = new Flow();
+    event_handler.handle(event, flow);
+    CHECK(session->get_client_id() == APPID_UT_ID);
+    delete flow;
+}
+
+TEST(appid_eve_process_event_handler_tests, eve_server_name_event_handler)
+{
+    Packet p;
+    EveProcessEvent event(p, "firefox", 90);
+    event.set_server_name("www.google.com");
+    AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
+    Flow* flow = new Flow();
+    event_handler.handle(event, flow);
+    CHECK(session->get_payload_id() == APPID_UT_ID + 1);
+    delete flow;
+}
+
+TEST(appid_eve_process_event_handler_tests, eve_alpn_event_handler)
+{
+    Packet p;
+    vector<string> alpn = {"h3"};
+    EveProcessEvent event(p, "firefox", 90);
+    event.set_alpn(alpn);
+    event.set_quic(true);
+    AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
+    Flow* flow = new Flow();
+    event_handler.handle(event, flow);
+    CHECK(session->get_alpn_service_app_id() == APPID_UT_ID + 2);
+    delete flow;
+}
+
+TEST(appid_eve_process_event_handler_tests, eve_unknown_alpn_event_handler)
+{
+    Packet p;
+    vector<string> alpn = {"smb"};
+    EveProcessEvent event(p, "firefox", 90);
+    event.set_alpn(alpn);
+    event.set_quic(true);
+    AppIdEveProcessEventHandler event_handler(dummy_appid_inspector);
+    Flow* flow = new Flow();
+    event_handler.handle(event, flow);
+    CHECK(session->get_alpn_service_app_id() == APP_ID_NONE);
+    delete flow;
+}
+
 int main(int argc, char** argv)
 {
     int return_value = CommandLineTestRunner::RunAllTests(argc, argv);
index 054df4f5fdf7c68cadb9464220fd68d8e78dc946..844bdab08600658bb3b4668ef0fde4fcd1121547 100644 (file)
@@ -84,6 +84,7 @@ EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 
 void Field::set(int32_t length, const uint8_t* start, bool own_the_buffer_)
 {
index 507d583915b4617f373db6beadf08fa55fbcaf27..031da2b59af411e6b188745ab65e909e6379bd5f 100644 (file)
@@ -125,6 +125,7 @@ EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 snort::SearchTool::SearchTool(bool) { }
 snort::SearchTool::~SearchTool() = default;
 
index 0f3848a5aa83cf8933f228efa34130629a97d4f0..6045ac200aa8ac572e33e610d9a8e06b9effb341 100644 (file)
@@ -60,6 +60,7 @@ EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
+AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 AppIdConfig::~AppIdConfig() = default;
 OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
 void ServiceDiscovery::initialize(AppIdInspector&) { }
index 764b6b116610ffd8e15a9894f6a924c070880bbd..53d425cebdde9d7cb9d4cf51738e282344a7a8b5 100644 (file)
@@ -56,11 +56,45 @@ public:
             server_name = server;
     }
 
+    const std::string& get_user_agent() const
+    {
+        return user_agent;
+    }
+
+    void set_user_agent(const char* u_a)
+    {
+        if (u_a)
+            user_agent = u_a;
+    }
+
+    const std::vector<std::string> get_alpn() const
+    {
+        return alpn;
+    }
+
+    void set_alpn(std::vector<std::string>& alpn_vec)
+    {
+        if(alpn_vec.size())
+            alpn = alpn_vec;
+    }
+
+    void set_quic(bool flag)
+    {
+        is_quic = flag;
+    }
+
+    bool is_flow_quic() const
+    {
+        return is_quic;
+    }
+
 private:
     const snort::Packet &p;
     std::string process_name;
     uint8_t process_confidence = 0;
     std::string server_name;
+    std::string user_agent;
+    std::vector<std::string> alpn;
+    bool is_quic = false;
 };
-
 #endif
index 4690ca1f2e475237b8706ca6dc1f855fdf71528e..70d06f58a01a68a4c54f9a8f74a97a3e767c8121 100644 (file)
@@ -44,9 +44,16 @@ TEST_GROUP(pub_sub_eve_process_event_test)
 TEST(pub_sub_eve_process_event_test, eve_process_event)
 {
     Packet p;
+    std::vector<std::string> alpn = {"h3"};
     EveProcessEvent event(p, "process", 10);
+    event.set_user_agent("chrome");
+    event.set_server_name("www.google.com");
+    event.set_alpn(alpn);
     CHECK(event.get_process_name() == "process");
     CHECK(event.get_process_confidence() == 10);
+    CHECK(event.get_user_agent() == "chrome");
+    CHECK(event.get_server_name() == "www.google.com");
+    CHECK(event.get_alpn()[0] == "h3");
     CHECK(event.get_packet() == &p);
 }