Coverage Report

Created: 2026-05-16 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/rust/src/ike/detect.rs
Line
Count
Source
1
/* Copyright (C) 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
// Author: Frank Honza <frank.honza@dcso.de>
19
20
use super::ipsec_parser::IkeV2Transform;
21
use crate::ike::ike::*;
22
use std::ffi::CStr;
23
use std::ptr;
24
25
#[no_mangle]
26
65
pub extern "C" fn rs_ike_state_get_exch_type(tx: &mut IKETransaction, exch_type: *mut u8) -> u8 {
27
65
    debug_validate_bug_on!(exch_type.is_null());
28
29
65
    if tx.ike_version == 1 {
30
65
        if let Some(r) = tx.hdr.ikev1_header.exchange_type {
31
65
            unsafe {
32
65
                *exch_type = r;
33
65
            }
34
65
            return 1;
35
0
        }
36
0
    } else if tx.ike_version == 2 {
37
0
        unsafe {
38
0
            *exch_type = tx.hdr.ikev2_header.exch_type.0;
39
0
        }
40
0
        return 1;
41
0
    }
42
43
0
    return 0;
44
65
}
45
46
#[no_mangle]
47
312
pub extern "C" fn rs_ike_state_get_spi_initiator(
48
312
    tx: &mut IKETransaction, buffer: *mut *const u8, buffer_len: *mut u32,
49
312
) -> u8 {
50
312
    debug_validate_bug_on!(buffer.is_null() || buffer_len.is_null());
51
52
312
    unsafe {
53
312
        *buffer = tx.hdr.spi_initiator.as_ptr();
54
312
        *buffer_len = tx.hdr.spi_initiator.len() as u32;
55
312
    }
56
312
    return 1;
57
312
}
58
59
#[no_mangle]
60
65
pub extern "C" fn rs_ike_state_get_spi_responder(
61
65
    tx: &mut IKETransaction, buffer: *mut *const u8, buffer_len: *mut u32,
62
65
) -> u8 {
63
65
    debug_validate_bug_on!(buffer.is_null() || buffer_len.is_null());
64
65
65
    unsafe {
66
65
        *buffer = tx.hdr.spi_responder.as_ptr();
67
65
        *buffer_len = tx.hdr.spi_responder.len() as u32;
68
65
    }
69
65
    return 1;
70
65
}
71
72
#[no_mangle]
73
153
pub extern "C" fn rs_ike_state_get_nonce(
74
153
    tx: &mut IKETransaction, buffer: *mut *const u8, buffer_len: *mut u32,
75
153
) -> u8 {
76
153
    debug_validate_bug_on!(buffer.is_null() || buffer_len.is_null());
77
78
153
    if tx.ike_version == 1 && !tx.hdr.ikev1_header.nonce.is_empty() {
79
30
        let p = &tx.hdr.ikev1_header.nonce;
80
30
        unsafe {
81
30
            *buffer = p.as_ptr();
82
30
            *buffer_len = p.len() as u32;
83
30
        }
84
30
        return 1;
85
123
    }
86
87
123
    unsafe {
88
123
        *buffer = ptr::null();
89
123
        *buffer_len = 0;
90
123
    }
91
92
123
    return 0;
93
153
}
94
95
#[no_mangle]
96
54
pub extern "C" fn rs_ike_state_get_key_exchange(
97
54
    tx: &mut IKETransaction, buffer: *mut *const u8, buffer_len: *mut u32,
98
54
) -> u8 {
99
54
    debug_validate_bug_on!(buffer.is_null() || buffer_len.is_null());
100
101
54
    if tx.ike_version == 1 && !tx.hdr.ikev1_header.key_exchange.is_empty() {
102
10
        let p = &tx.hdr.ikev1_header.key_exchange;
103
10
        unsafe {
104
10
            *buffer = p.as_ptr();
105
10
            *buffer_len = p.len() as u32;
106
10
        }
107
10
        return 1;
108
44
    }
109
110
44
    unsafe {
111
44
        *buffer = ptr::null();
112
44
        *buffer_len = 0;
113
44
    }
114
115
44
    return 0;
116
54
}
117
118
#[no_mangle]
119
379
pub extern "C" fn rs_ike_tx_get_vendor(
120
379
    tx: &IKETransaction, i: u32, buf: *mut *const u8, len: *mut u32,
121
379
) -> u8 {
122
379
    if tx.ike_version == 1 && i < tx.hdr.ikev1_header.vendor_ids.len() as u32 {
123
250
        unsafe {
124
250
            *len = tx.hdr.ikev1_header.vendor_ids[i as usize].len() as u32;
125
250
            *buf = tx.hdr.ikev1_header.vendor_ids[i as usize].as_ptr();
126
250
        }
127
250
        return 1;
128
129
    }
129
130
129
    unsafe {
131
129
        *buf = ptr::null();
132
129
        *len = 0;
133
129
    }
134
135
129
    return 0;
136
379
}
137
138
#[no_mangle]
139
247
pub extern "C" fn rs_ike_state_get_sa_attribute(
140
247
    tx: &mut IKETransaction, sa_type: *const std::os::raw::c_char, value: *mut u32,
141
247
) -> u8 {
142
247
    debug_validate_bug_on!(value.is_null());
143
247
    let mut ret_val = 0;
144
247
    let mut ret_code = 0;
145
    let sa_type_s: Result<_, _>;
146
147
247
    unsafe { sa_type_s = CStr::from_ptr(sa_type).to_str() }
148
    SCLogDebug!("{:#?}", sa_type_s);
149
150
247
    if let Ok(sa) = sa_type_s {
151
247
        if tx.ike_version == 1 {
152
242
            if !tx.hdr.ikev1_transforms.is_empty() {
153
                // there should be only one chosen server_transform, check event
154
100
                if let Some(server_transform) = tx.hdr.ikev1_transforms.first() {
155
327
                    for attr in server_transform {
156
309
                        if attr.attribute_type.to_string() == sa {
157
86
                            if let Some(numeric_value) = attr.numeric_value {
158
82
                                ret_val = numeric_value;
159
82
                                ret_code = 1;
160
82
                                break;
161
4
                            }
162
223
                        }
163
                    }
164
0
                }
165
142
            }
166
5
        } else if tx.ike_version == 2 {
167
5
            for attr in tx.hdr.ikev2_transforms.iter() {
168
0
                match attr {
169
0
                    IkeV2Transform::Encryption(e) => {
170
0
                        if sa == "alg_enc" {
171
0
                            ret_val = e.0 as u32;
172
0
                            ret_code = 1;
173
0
                            break;
174
0
                        }
175
                    }
176
0
                    IkeV2Transform::Auth(e) => {
177
0
                        if sa == "alg_auth" {
178
0
                            ret_val = e.0 as u32;
179
0
                            ret_code = 1;
180
0
                            break;
181
0
                        }
182
                    }
183
0
                    IkeV2Transform::PRF(ref e) => {
184
0
                        if sa == "alg_prf" {
185
0
                            ret_val = e.0 as u32;
186
0
                            ret_code = 1;
187
0
                            break;
188
0
                        }
189
                    }
190
0
                    IkeV2Transform::DH(ref e) => {
191
0
                        if sa == "alg_dh" {
192
0
                            ret_val = e.0 as u32;
193
0
                            ret_code = 1;
194
0
                            break;
195
0
                        }
196
                    }
197
0
                    _ => (),
198
                }
199
            }
200
0
        }
201
0
    }
202
203
247
    unsafe {
204
247
        *value = ret_val;
205
247
    }
206
247
    return ret_code;
207
247
}
208
209
#[no_mangle]
210
54
pub unsafe extern "C" fn rs_ike_state_get_key_exchange_payload_length(
211
54
    tx: &mut IKETransaction, value: *mut u32,
212
54
) -> u8 {
213
54
    debug_validate_bug_on!(value.is_null());
214
215
54
    if tx.ike_version == 1 && !tx.hdr.ikev1_header.key_exchange.is_empty() {
216
13
        *value = tx.hdr.ikev1_header.key_exchange.len() as u32;
217
13
        return 1;
218
41
    }
219
220
41
    *value = 0;
221
41
    return 0;
222
54
}
223
224
#[no_mangle]
225
91
pub unsafe extern "C" fn rs_ike_state_get_nonce_payload_length(
226
91
    tx: &mut IKETransaction, value: *mut u32,
227
91
) -> u8 {
228
91
    debug_validate_bug_on!(value.is_null());
229
230
91
    if tx.ike_version == 1 && !tx.hdr.ikev1_header.nonce.is_empty() {
231
17
        *value = tx.hdr.ikev1_header.nonce.len() as u32;
232
17
        return 1;
233
74
    }
234
235
74
    *value = 0;
236
74
    return 0;
237
91
}