1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // ips_metadata.cc author Russ Combs <rucombs@cisco.com>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "detection/treenodes.h"
25 #include "framework/decode_data.h"
26 #include "framework/ips_option.h"
27 #include "framework/module.h"
28 #include "main/snort_config.h"
29 
30 using namespace snort;
31 using namespace std;
32 
33 #define s_name "metadata"
34 
35 //-------------------------------------------------------------------------
36 // module
37 //-------------------------------------------------------------------------
38 
39 static const Parameter s_params[] =
40 {
41     { "*", Parameter::PT_STRING, nullptr, nullptr,
42       "comma-separated list of arbitrary name value pairs" },
43 
44     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
45 };
46 
47 #define s_help \
48     "rule option for conveying arbitrary comma-separated name, value data within the rule text"
49 
50 class MetadataModule : public Module
51 {
52 public:
MetadataModule()53     MetadataModule() : Module(s_name, s_help, s_params) { }
54 
55     bool begin(const char*, int, SnortConfig*) override;
56     bool set(const char*, Value&, SnortConfig*) override;
57 
get_usage() const58     Usage get_usage() const override
59     { return DETECT; }
60 
61     bool match = false;
62 };
63 
begin(const char *,int,SnortConfig *)64 bool MetadataModule::begin(const char*, int, SnortConfig*)
65 {
66     match = false;
67     return true;
68 }
69 
set(const char *,Value & v,SnortConfig * sc)70 bool MetadataModule::set(const char*, Value& v, SnortConfig* sc)
71 {
72     assert(v.is("*"));
73 
74     if ( !match and !sc->metadata_filter.empty() )
75         match = strstr(v.get_string(), sc->metadata_filter.c_str()) != nullptr;
76 
77     return true;
78 }
79 
80 //-------------------------------------------------------------------------
81 // api methods
82 //-------------------------------------------------------------------------
83 
mod_ctor()84 static Module* mod_ctor()
85 {
86     return new MetadataModule;
87 }
88 
mod_dtor(Module * m)89 static void mod_dtor(Module* m)
90 {
91     delete m;
92 }
93 
metadata_ctor(Module * p,OptTreeNode * otn)94 static IpsOption* metadata_ctor(Module* p, OptTreeNode* otn)
95 {
96     MetadataModule* m = (MetadataModule*)p;
97     if ( m->match )
98         otn->set_metadata_match();
99     return nullptr;
100 }
101 
102 static const IpsApi metadata_api =
103 {
104     {
105         PT_IPS_OPTION,
106         sizeof(IpsApi),
107         IPSAPI_VERSION,
108         0,
109         API_RESERVED,
110         API_OPTIONS,
111         s_name,
112         s_help,
113         mod_ctor,
114         mod_dtor
115     },
116     OPT_TYPE_META,
117     0, PROTO_BIT__NONE,
118     nullptr,
119     nullptr,
120     nullptr,
121     nullptr,
122     metadata_ctor,
123     nullptr,
124     nullptr
125 };
126 
127 const BaseApi* ips_metadata = &metadata_api.base;
128 
129