1 //--------------------------------------------------------------------------
2 // Copyright (C) 2015-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_http.h author Tom Peters <thopeter@cisco.com>
19 
20 #ifndef IPS_HTTP_H
21 #define IPS_HTTP_H
22 
23 #include <array>
24 
25 #include "profiler/profiler.h"
26 #include "framework/ips_option.h"
27 #include "framework/module.h"
28 #include "framework/range.h"
29 
30 #include "http_buffer_info.h"
31 #include "http_enum.h"
32 
33 class HttpInspect;
34 
35 enum PsIdx { PSI_CLIENT_BODY, PSI_COOKIE, PSI_HEADER, PSI_METHOD, PSI_PARAM,
36     PSI_RAW_BODY, PSI_RAW_COOKIE, PSI_RAW_HEADER, PSI_RAW_REQUEST, PSI_RAW_STATUS,
37     PSI_RAW_TRAILER, PSI_RAW_URI, PSI_STAT_CODE, PSI_STAT_MSG, PSI_TRAILER,
38     PSI_TRUE_IP, PSI_URI, PSI_VERSION, PSI_JS_DATA, PSI_VBA_DATA,
39     PSI_RANGE_NUM_HDRS, PSI_RANGE_NUM_TRAILERS, PSI_MAX };
40 
41 class HttpRuleOptModule : public snort::Module
42 {
43 public:
HttpRuleOptModule(const char * key_,const char * help,HttpEnums::HTTP_RULE_OPT rule_opt_index_,snort::CursorActionType cat_,PsIdx psi_)44     HttpRuleOptModule(const char* key_, const char* help, HttpEnums::HTTP_RULE_OPT rule_opt_index_,
45         snort::CursorActionType cat_, PsIdx psi_)
46         : snort::Module(key_, help), key(key_), rule_opt_index(rule_opt_index_),
47           cat(cat_), psi(psi_) {}
HttpRuleOptModule(const char * key_,const char * help,HttpEnums::HTTP_RULE_OPT rule_opt_index_,snort::CursorActionType cat_,PsIdx psi_,const snort::Parameter params[])48     HttpRuleOptModule(const char* key_, const char* help, HttpEnums::HTTP_RULE_OPT rule_opt_index_,
49         snort::CursorActionType cat_, PsIdx psi_, const snort::Parameter params[])
50         : snort::Module(key_, help, params), key(key_), rule_opt_index(rule_opt_index_),
51         cat(cat_), psi(psi_) {}
get_profile()52     snort::ProfileStats* get_profile() const override { return &http_ps[psi]; }
mod_dtor(snort::Module * m)53     static void mod_dtor(snort::Module* m) { delete m; }
54     bool begin(const char*, int, snort::SnortConfig*) override;
55     bool set(const char*, snort::Value&, snort::SnortConfig*) override;
56     bool end(const char*, int, snort::SnortConfig*) override;
57 
get_usage()58     Usage get_usage() const override
59     { return DETECT; }
60 
61 private:
62     friend class HttpIpsOption;
63     static THREAD_LOCAL std::array<snort::ProfileStats, PsIdx::PSI_MAX> http_ps;
64 
65     struct HttpRuleParaList
66     {
67     public:
68         std::string field;        // provide buffer containing specific header field
69         std::string param;        // provide buffer containing specific parameter
70         bool nocase;              // case insensitive match
71         bool request;             // provide buffer from request not response
72         bool with_header;         // provide buffer with a later section than it appears in
73         bool with_body;
74         bool with_trailer;
75         bool scheme;              // provide buffer with one of the six URI subcomponents
76         bool host;
77         bool port;
78         bool path;
79         bool query;
80         bool fragment;
81         snort::RangeCheck range;
82 
83         void reset();
84     };
85 
86     const char* const key;
87     const HttpEnums::HTTP_RULE_OPT rule_opt_index;
88     const snort::CursorActionType cat;
89     const PsIdx psi;
90 
91     HttpRuleParaList para_list;
92     HttpEnums::InspectSection inspect_section;
93     uint64_t sub_id;
94     uint64_t form;
95 };
96 
97 class HttpIpsOption : public snort::IpsOption
98 {
99 public:
HttpIpsOption(const HttpRuleOptModule * cm)100     HttpIpsOption(const HttpRuleOptModule* cm) :
101         snort::IpsOption(cm->key, RULE_OPTION_TYPE_BUFFER_SET),
102         key(cm->key), cat(cm->cat), psi(cm->psi),
103         inspect_section(cm->inspect_section),
104         buffer_info(cm->rule_opt_index, cm->sub_id, cm->form,
105         cm->para_list.param, cm->para_list.nocase), range(cm->para_list.range){}
get_cursor_type()106     snort::CursorActionType get_cursor_type() const override { return cat; }
107     EvalStatus eval(Cursor&, snort::Packet*) override;
108     uint32_t hash() const override;
109     bool operator==(const snort::IpsOption& ips) const override;
110     bool retry(Cursor&, const Cursor&) override;
opt_ctor(snort::Module * m,OptTreeNode *)111     static IpsOption* opt_ctor(snort::Module* m, OptTreeNode*)
112         { return new HttpIpsOption((HttpRuleOptModule*)m); }
opt_dtor(snort::IpsOption * p)113     static void opt_dtor(snort::IpsOption* p) { delete p; }
114 
115 private:
116     const char* const key;
117     const snort::CursorActionType cat;
118     const PsIdx psi;
119     const HttpEnums::InspectSection inspect_section;
120     HttpBufferInfo buffer_info;
121     const snort::RangeCheck range;
122 };
123 
124 #endif
125 
126