/src/suricata/rust/src/detect/uri.rs
Line | Count | Source |
1 | | /* Copyright (C) 2022 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 | | use super::uint::*; |
19 | | use nom8::branch::alt; |
20 | | use nom8::bytes::complete::{is_a, tag, take_while}; |
21 | | use nom8::character::complete::char; |
22 | | use nom8::combinator::{all_consuming, opt, value}; |
23 | | use nom8::{IResult, Parser}; |
24 | | |
25 | | use std::ffi::CStr; |
26 | | |
27 | | #[derive(Debug)] |
28 | | #[repr(C)] |
29 | | pub struct DetectUrilenData { |
30 | | pub du16: DetectUintData<u16>, |
31 | | pub raw_buffer: bool, |
32 | | } |
33 | | |
34 | 659 | pub fn detect_parse_urilen_raw(i: &str) -> IResult<&str, bool> { |
35 | 659 | let (i, _) = opt(is_a(" ")).parse(i)?; |
36 | 659 | let (i, _) = char(',').parse(i)?; |
37 | 304 | let (i, _) = opt(is_a(" ")).parse(i)?; |
38 | 304 | let (i, v) = alt((value(true, tag("raw")), value(false, tag("norm")))).parse(i)?; |
39 | 270 | let (i, _) = opt(is_a(" ")).parse(i)?; |
40 | 270 | Ok((i, v)) |
41 | 659 | } |
42 | | |
43 | 1.64k | pub fn detect_parse_urilen(i: &str) -> IResult<&str, DetectUrilenData> { |
44 | 1.64k | let (i, du16) = detect_parse_uint_notending::<u16>(i)?; |
45 | 1.40k | let (i, _) = take_while(|c| c == ' ').parse(i)?; |
46 | 1.40k | if i.is_empty() { |
47 | 746 | return Ok(( |
48 | 746 | i, |
49 | 746 | DetectUrilenData { |
50 | 746 | du16, |
51 | 746 | raw_buffer: false, |
52 | 746 | }, |
53 | 746 | )); |
54 | 659 | } |
55 | 659 | let (i, raw_buffer) = all_consuming(detect_parse_urilen_raw).parse(i)?; |
56 | 252 | return Ok((i, DetectUrilenData { du16, raw_buffer })); |
57 | 1.64k | } |
58 | | |
59 | | #[no_mangle] |
60 | 1.64k | pub unsafe extern "C" fn SCDetectUrilenParse( |
61 | 1.64k | ustr: *const std::os::raw::c_char, |
62 | 1.64k | ) -> *mut DetectUrilenData { |
63 | 1.64k | let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe |
64 | 1.64k | if let Ok(s) = ft_name.to_str() { |
65 | 1.64k | if let Ok((_, ctx)) = detect_parse_urilen(s) { |
66 | 998 | let boxed = Box::new(ctx); |
67 | 998 | return Box::into_raw(boxed) as *mut _; |
68 | 645 | } |
69 | 0 | } |
70 | 645 | return std::ptr::null_mut(); |
71 | 1.64k | } |
72 | | |
73 | | #[no_mangle] |
74 | 998 | pub unsafe extern "C" fn SCDetectUrilenFree(ctx: &mut DetectUrilenData) { |
75 | | // Just unbox... |
76 | 998 | std::mem::drop(Box::from_raw(ctx)); |
77 | 998 | } |
78 | | |
79 | | #[cfg(test)] |
80 | | mod tests { |
81 | | use super::*; |
82 | | |
83 | | #[test] |
84 | | fn test_parse_urilen() { |
85 | | let (_, ctx) = detect_parse_urilen("1<>3").unwrap(); |
86 | | assert_eq!(ctx.du16.arg1, 1); |
87 | | assert_eq!(ctx.du16.arg2, 3); |
88 | | assert_eq!(ctx.du16.mode, DetectUintMode::DetectUintModeRange); |
89 | | assert!(detect_parse_urilen("1<>2").is_err()); |
90 | | } |
91 | | } |