/src/suricata7/src/detect-nfs-version.c
Line | Count | Source |
1 | | /* Copyright (C) 2017-2020 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | /** |
19 | | * \file |
20 | | * |
21 | | * \author Victor Julien <victor@inliniac.net> |
22 | | */ |
23 | | |
24 | | #include "suricata-common.h" |
25 | | #include "threads.h" |
26 | | #include "decode.h" |
27 | | #include "detect.h" |
28 | | |
29 | | #include "detect-parse.h" |
30 | | #include "detect-engine.h" |
31 | | #include "detect-engine-mpm.h" |
32 | | #include "detect-content.h" |
33 | | #include "detect-pcre.h" |
34 | | #include "detect-nfs-version.h" |
35 | | #include "detect-engine-uint.h" |
36 | | |
37 | | #include "app-layer-parser.h" |
38 | | |
39 | | #include "flow.h" |
40 | | #include "flow-util.h" |
41 | | #include "flow-var.h" |
42 | | |
43 | | #include "util-unittest.h" |
44 | | #include "util-unittest-helper.h" |
45 | | #include "util-byte.h" |
46 | | |
47 | | #include "app-layer-nfs-tcp.h" |
48 | | #include "rust.h" |
49 | | |
50 | | |
51 | | static int DetectNfsVersionSetup (DetectEngineCtx *, Signature *s, const char *str); |
52 | | static void DetectNfsVersionFree(DetectEngineCtx *de_ctx, void *); |
53 | | static int g_nfs_request_buffer_id = 0; |
54 | | |
55 | | static int DetectNfsVersionMatch (DetectEngineThreadCtx *, Flow *, |
56 | | uint8_t, void *, void *, const Signature *, |
57 | | const SigMatchCtx *); |
58 | | |
59 | | /** |
60 | | * \brief Registration function for nfs_procedure keyword. |
61 | | */ |
62 | | void DetectNfsVersionRegister (void) |
63 | 73 | { |
64 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].name = "nfs.version"; |
65 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].alias = "nfs_version"; |
66 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].desc = "match NFS version"; |
67 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].url = "/rules/nfs-keywords.html#version"; |
68 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].AppLayerTxMatch = DetectNfsVersionMatch; |
69 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].Setup = DetectNfsVersionSetup; |
70 | 73 | sigmatch_table[DETECT_AL_NFS_VERSION].Free = DetectNfsVersionFree; |
71 | | // unit tests were the same as DetectNfsProcedureRegisterTests |
72 | 73 | DetectAppLayerInspectEngineRegister2( |
73 | 73 | "nfs_request", ALPROTO_NFS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); |
74 | | |
75 | 73 | g_nfs_request_buffer_id = DetectBufferTypeGetByName("nfs_request"); |
76 | | |
77 | 73 | SCLogDebug("g_nfs_request_buffer_id %d", g_nfs_request_buffer_id); |
78 | 73 | } |
79 | | |
80 | | /** |
81 | | * \internal |
82 | | * \brief Function to match version of a TX |
83 | | * |
84 | | * \param t Pointer to thread vars. |
85 | | * \param det_ctx Pointer to the pattern matcher thread. |
86 | | * \param f Pointer to the current flow. |
87 | | * \param flags Flags. |
88 | | * \param state App layer state. |
89 | | * \param s Pointer to the Signature. |
90 | | * \param m Pointer to the sigmatch that we will cast into |
91 | | * DetectU32Data. |
92 | | * |
93 | | * \retval 0 no match. |
94 | | * \retval 1 match. |
95 | | */ |
96 | | static int DetectNfsVersionMatch (DetectEngineThreadCtx *det_ctx, |
97 | | Flow *f, uint8_t flags, void *state, |
98 | | void *txv, const Signature *s, |
99 | | const SigMatchCtx *ctx) |
100 | 11.3k | { |
101 | 11.3k | SCEnter(); |
102 | | |
103 | 11.3k | const DetectU32Data *dd = (const DetectU32Data *)ctx; |
104 | 11.3k | uint32_t version; |
105 | 11.3k | rs_nfs_tx_get_version(txv, &version); |
106 | 11.3k | SCLogDebug("version %u mode %u lo %u hi %u", version, dd->mode, dd->arg1, dd->arg2); |
107 | 11.3k | if (DetectU32Match(version, dd)) |
108 | 5.30k | SCReturnInt(1); |
109 | 11.3k | SCReturnInt(0); |
110 | 11.3k | } |
111 | | |
112 | | /** |
113 | | * \internal |
114 | | * \brief Function to parse options passed via tls validity keywords. |
115 | | * |
116 | | * \param rawstr Pointer to the user provided options. |
117 | | * |
118 | | * \retval dd pointer to DetectU32Data on success. |
119 | | * \retval NULL on failure. |
120 | | */ |
121 | | static DetectU32Data *DetectNfsVersionParse(const char *rawstr) |
122 | 21.1k | { |
123 | 21.1k | return rs_detect_u32_parse_inclusive(rawstr); |
124 | 21.1k | } |
125 | | |
126 | | |
127 | | |
128 | | /** |
129 | | * \brief Function to add the parsed tls validity field into the current signature. |
130 | | * |
131 | | * \param de_ctx Pointer to the Detection Engine Context. |
132 | | * \param s Pointer to the Current Signature. |
133 | | * \param rawstr Pointer to the user provided flags options. |
134 | | * \param type Defines if this is notBefore or notAfter. |
135 | | * |
136 | | * \retval 0 on Success. |
137 | | * \retval -1 on Failure. |
138 | | */ |
139 | | static int DetectNfsVersionSetup (DetectEngineCtx *de_ctx, Signature *s, |
140 | | const char *rawstr) |
141 | 2.95k | { |
142 | 2.95k | SCLogDebug("\'%s\'", rawstr); |
143 | | |
144 | 2.95k | if (DetectSignatureSetAppProto(s, ALPROTO_NFS) != 0) |
145 | 65 | return -1; |
146 | | |
147 | 2.89k | DetectU32Data *dd = DetectNfsVersionParse(rawstr); |
148 | 2.89k | if (dd == NULL) { |
149 | 1.40k | SCLogError("Parsing \'%s\' failed", rawstr); |
150 | 1.40k | return -1; |
151 | 1.40k | } |
152 | | |
153 | | /* okay so far so good, lets get this into a SigMatch |
154 | | * and put it in the Signature. */ |
155 | 1.48k | SigMatch *sm = SigMatchAlloc(); |
156 | 1.48k | if (sm == NULL) |
157 | 0 | goto error; |
158 | | |
159 | 1.48k | sm->type = DETECT_AL_NFS_VERSION; |
160 | 1.48k | sm->ctx = (void *)dd; |
161 | | |
162 | 1.48k | SCLogDebug("low %u hi %u", dd->arg1, dd->arg2); |
163 | 1.48k | SigMatchAppendSMToList(s, sm, g_nfs_request_buffer_id); |
164 | 1.48k | return 0; |
165 | | |
166 | 0 | error: |
167 | 0 | DetectNfsVersionFree(de_ctx, dd); |
168 | 0 | return -1; |
169 | 1.48k | } |
170 | | |
171 | | /** |
172 | | * \internal |
173 | | * \brief Function to free memory associated with DetectU32Data. |
174 | | * |
175 | | * \param de_ptr Pointer to DetectU32Data. |
176 | | */ |
177 | | void DetectNfsVersionFree(DetectEngineCtx *de_ctx, void *ptr) |
178 | 12.8k | { |
179 | 12.8k | rs_detect_u32_free(ptr); |
180 | 12.8k | } |