• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jasonish / suricata / 22785952221

06 Mar 2026 11:16PM UTC coverage: 67.722% (-11.5%) from 79.244%
22785952221

push

github

jasonish
github-ci: add schema ordering check for yaml schema

158908 of 234646 relevant lines covered (67.72%)

6673126.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.43
/rust/src/ssh/detect.rs
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
use super::ssh::{
19
    SCSshEnableHassh, SCSshHasshIsEnabled, SSHConnectionState, SSHTransaction, ALPROTO_SSH,
20
};
21
use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
22
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
23
use crate::direction::Direction;
24
use std::os::raw::{c_int, c_void};
25
use std::ptr;
26
use suricata_sys::sys::{
27
    DetectEngineCtx, SCDetectBufferSetActiveList, SCDetectHelperBufferProgressMpmRegister,
28
    SCDetectHelperKeywordAliasRegister, SCDetectHelperKeywordRegister,
29
    SCDetectRegisterBufferLowerMd5Callbacks, SCDetectSignatureSetAppProto,
30
    SCSigMatchSilentErrorEnabled, SCSigTableAppLiteElmt, Signature,
31
};
32

33
#[no_mangle]
34
pub unsafe extern "C" fn SCSshTxGetProtocol(
109✔
35
    tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
109✔
36
) -> bool {
109✔
37
    let tx = cast_pointer!(tx, SSHTransaction);
109✔
38
    match direction.into() {
109✔
39
        Direction::ToServer => {
40
            let m = &tx.cli_hdr.protover;
100✔
41
            if !m.is_empty() {
100✔
42
                *buffer = m.as_ptr();
100✔
43
                *buffer_len = m.len() as u32;
100✔
44
                return true;
100✔
45
            }
×
46
        }
47
        Direction::ToClient => {
48
            let m = &tx.srv_hdr.protover;
9✔
49
            if !m.is_empty() {
9✔
50
                *buffer = m.as_ptr();
9✔
51
                *buffer_len = m.len() as u32;
9✔
52
                return true;
9✔
53
            }
×
54
        }
55
    }
56
    *buffer = ptr::null();
×
57
    *buffer_len = 0;
×
58

×
59
    return false;
×
60
}
109✔
61

62
#[no_mangle]
63
pub unsafe extern "C" fn SCSshTxGetSoftware(
28✔
64
    tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
28✔
65
) -> bool {
28✔
66
    let tx = cast_pointer!(tx, SSHTransaction);
28✔
67
    match direction.into() {
28✔
68
        Direction::ToServer => {
69
            let m = &tx.cli_hdr.swver;
15✔
70
            if !m.is_empty() {
15✔
71
                *buffer = m.as_ptr();
15✔
72
                *buffer_len = m.len() as u32;
15✔
73
                return true;
15✔
74
            }
×
75
        }
76
        Direction::ToClient => {
77
            let m = &tx.srv_hdr.swver;
13✔
78
            if !m.is_empty() {
13✔
79
                *buffer = m.as_ptr();
13✔
80
                *buffer_len = m.len() as u32;
13✔
81
                return true;
13✔
82
            }
×
83
        }
84
    }
85
    *buffer = ptr::null();
×
86
    *buffer_len = 0;
×
87
    return false;
×
88
}
28✔
89

90
#[no_mangle]
91
pub unsafe extern "C" fn SCSshTxGetHassh(
279✔
92
    tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
279✔
93
) -> bool {
279✔
94
    let tx = cast_pointer!(tx, SSHTransaction);
279✔
95
    match direction.into() {
279✔
96
        Direction::ToServer => {
97
            let m = &tx.cli_hdr.hassh;
142✔
98
            if !m.is_empty() {
142✔
99
                *buffer = m.as_ptr();
59✔
100
                *buffer_len = m.len() as u32;
59✔
101
                return true;
59✔
102
            }
83✔
103
        }
104
        Direction::ToClient => {
105
            let m = &tx.srv_hdr.hassh;
137✔
106
            if !m.is_empty() {
137✔
107
                *buffer = m.as_ptr();
71✔
108
                *buffer_len = m.len() as u32;
71✔
109
                return true;
71✔
110
            }
66✔
111
        }
112
    }
113
    *buffer = ptr::null();
149✔
114
    *buffer_len = 0;
149✔
115

149✔
116
    return false;
149✔
117
}
279✔
118

119
#[no_mangle]
120
pub unsafe extern "C" fn SCSshTxGetHasshString(
259✔
121
    tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
259✔
122
) -> bool {
259✔
123
    let tx = cast_pointer!(tx, SSHTransaction);
259✔
124
    match direction.into() {
259✔
125
        Direction::ToServer => {
126
            let m = &tx.cli_hdr.hassh_string;
133✔
127
            if !m.is_empty() {
133✔
128
                *buffer = m.as_ptr();
56✔
129
                *buffer_len = m.len() as u32;
56✔
130
                return true;
56✔
131
            }
77✔
132
        }
133
        Direction::ToClient => {
134
            let m = &tx.srv_hdr.hassh_string;
126✔
135
            if !m.is_empty() {
126✔
136
                *buffer = m.as_ptr();
66✔
137
                *buffer_len = m.len() as u32;
66✔
138
                return true;
66✔
139
            }
60✔
140
        }
141
    }
142
    *buffer = ptr::null();
137✔
143
    *buffer_len = 0;
137✔
144

137✔
145
    return false;
137✔
146
}
259✔
147

148
unsafe extern "C" fn ssh_software_setup(
143✔
149
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
143✔
150
) -> c_int {
143✔
151
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
143✔
152
        return -1;
51✔
153
    }
92✔
154
    if SCDetectBufferSetActiveList(de, s, G_SSH_SOFTWARE_BUFFER_ID) < 0 {
92✔
155
        return -1;
1✔
156
    }
91✔
157
    return 0;
91✔
158
}
143✔
159

160
unsafe extern "C" fn ssh_proto_setup(
152✔
161
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
152✔
162
) -> c_int {
152✔
163
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
152✔
164
        return -1;
18✔
165
    }
134✔
166
    if SCDetectBufferSetActiveList(de, s, G_SSH_PROTO_BUFFER_ID) < 0 {
134✔
167
        return -1;
×
168
    }
134✔
169
    return 0;
134✔
170
}
152✔
171

172
unsafe extern "C" fn ssh_hassh_string_setup(
3,759✔
173
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
3,759✔
174
) -> c_int {
3,759✔
175
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
3,759✔
176
        return -1;
770✔
177
    }
2,989✔
178
    if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_STR_BUFFER_ID) < 0 {
2,989✔
179
        return -1;
372✔
180
    }
2,617✔
181
    /* try to enable Hassh */
2,617✔
182
    SCSshEnableHassh();
2,617✔
183

2,617✔
184
    /* Check if Hassh is disabled */
2,617✔
185
    if !SCSshHasshIsEnabled() {
2,617✔
186
        if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH_STRING) {
1✔
187
            SCLogError!("hassh support is not enabled");
1✔
188
        }
×
189
        return -2;
1✔
190
    }
2,616✔
191
    return 0;
2,616✔
192
}
3,759✔
193

194
unsafe extern "C" fn ssh_hassh_server_string_setup(
1,648✔
195
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
1,648✔
196
) -> c_int {
1,648✔
197
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
1,648✔
198
        return -1;
245✔
199
    }
1,403✔
200
    if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_SRV_STR_BUFFER_ID) < 0 {
1,403✔
201
        return -1;
1✔
202
    }
1,402✔
203
    /* try to enable Hassh */
1,402✔
204
    SCSshEnableHassh();
1,402✔
205

1,402✔
206
    /* Check if Hassh is disabled */
1,402✔
207
    if !SCSshHasshIsEnabled() {
1,402✔
208
        if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH_SERVER_STRING) {
1✔
209
            SCLogError!("hassh support is not enabled");
1✔
210
        }
×
211
        return -2;
1✔
212
    }
1,401✔
213
    return 0;
1,401✔
214
}
1,648✔
215

216
unsafe extern "C" fn ssh_hassh_setup(
10,241✔
217
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
10,241✔
218
) -> c_int {
10,241✔
219
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
10,241✔
220
        return -1;
491✔
221
    }
9,750✔
222
    if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_BUFFER_ID) < 0 {
9,750✔
223
        return -1;
12✔
224
    }
9,738✔
225
    /* try to enable Hassh */
9,738✔
226
    SCSshEnableHassh();
9,738✔
227

9,738✔
228
    /* Check if Hassh is disabled */
9,738✔
229
    if !SCSshHasshIsEnabled() {
9,738✔
230
        if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH) {
1✔
231
            SCLogError!("hassh support is not enabled");
1✔
232
        }
×
233
        return -2;
1✔
234
    }
9,737✔
235
    return 0;
9,737✔
236
}
10,241✔
237

238
unsafe extern "C" fn ssh_hassh_server_setup(
6,247✔
239
    de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
6,247✔
240
) -> c_int {
6,247✔
241
    if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
6,247✔
242
        return -1;
109✔
243
    }
6,138✔
244
    if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_SRV_BUFFER_ID) < 0 {
6,138✔
245
        return -1;
184✔
246
    }
5,954✔
247
    /* try to enable Hassh */
5,954✔
248
    SCSshEnableHassh();
5,954✔
249

5,954✔
250
    /* Check if Hassh is disabled */
5,954✔
251
    if !SCSshHasshIsEnabled() {
5,954✔
252
        if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH_SERVER) {
1✔
253
            SCLogError!("hassh support is not enabled");
1✔
254
        }
×
255
        return -2;
1✔
256
    }
5,953✔
257
    return 0;
5,953✔
258
}
6,247✔
259

260
unsafe extern "C" fn ssh_software_obsolete_setup(
727✔
261
    _de: *mut DetectEngineCtx, _s: *mut Signature, _raw: *const std::os::raw::c_char,
727✔
262
) -> c_int {
727✔
263
    SCLogError!("ssh.softwareversion is obsolete, use now ssh.software");
727✔
264
    return -1;
727✔
265
}
727✔
266

267
unsafe extern "C" fn ssh_proto_obsolete_setup(
29✔
268
    _de: *mut DetectEngineCtx, _s: *mut Signature, _raw: *const std::os::raw::c_char,
29✔
269
) -> c_int {
29✔
270
    SCLogError!("ssh.softwareversion is obsolete, use now ssh.software");
29✔
271
    return -1;
29✔
272
}
29✔
273

274
static mut G_SSH_SOFTWARE_BUFFER_ID: c_int = 0;
275
static mut G_SSH_PROTO_BUFFER_ID: c_int = 0;
276
static mut G_SSH_HASSH_STR_BUFFER_ID: c_int = 0;
277
static mut G_SSH_HASSH_SRV_STR_BUFFER_ID: c_int = 0;
278
static mut G_SSH_HASSH_BUFFER_ID: c_int = 0;
279
static mut G_SSH_HASSH_SRV_BUFFER_ID: c_int = 0;
280

281
static mut DETECT_SSH_HASSH_STRING: u16 = 0;
282
static mut DETECT_SSH_HASSH_SERVER_STRING: u16 = 0;
283
static mut DETECT_SSH_HASSH: u16 = 0;
284
static mut DETECT_SSH_HASSH_SERVER: u16 = 0;
285

286
#[no_mangle]
287
pub unsafe extern "C" fn SCDetectSshRegister() {
2,220✔
288
    let kw = SigTableElmtStickyBuffer {
2,220✔
289
        name: String::from("ssh.software"),
2,220✔
290
        desc: String::from("ssh.software sticky buffer"),
2,220✔
291
        url: String::from("/rules/ssh-keywords.html#ssh-software"),
2,220✔
292
        setup: ssh_software_setup,
2,220✔
293
    };
2,220✔
294
    let ssh_software_kw_id = helper_keyword_register_sticky_buffer(&kw);
2,220✔
295
    G_SSH_SOFTWARE_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
296
        b"ssh_software\0".as_ptr() as *const libc::c_char,
2,220✔
297
        b"ssh software field\0".as_ptr() as *const libc::c_char,
2,220✔
298
        ALPROTO_SSH,
2,220✔
299
        STREAM_TOSERVER | STREAM_TOCLIENT,
2,220✔
300
        Some(SCSshTxGetSoftware),
2,220✔
301
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
302
    );
2,220✔
303
    SCDetectHelperKeywordAliasRegister(
2,220✔
304
        ssh_software_kw_id,
2,220✔
305
        b"ssh_software\0".as_ptr() as *const libc::c_char,
2,220✔
306
    );
2,220✔
307

2,220✔
308
    let kw = SCSigTableAppLiteElmt {
2,220✔
309
        name: b"ssh.softwareversion\0".as_ptr() as *const libc::c_char,
2,220✔
310
        desc: b"obsolete keyword, use now ssh.software\0".as_ptr() as *const libc::c_char,
2,220✔
311
        url: std::ptr::null(),
2,220✔
312
        AppLayerTxMatch: None,
2,220✔
313
        Setup: Some(ssh_software_obsolete_setup),
2,220✔
314
        Free: None,
2,220✔
315
        flags: 0,
2,220✔
316
    };
2,220✔
317
    _ = SCDetectHelperKeywordRegister(&kw);
2,220✔
318

2,220✔
319
    let kw = SCSigTableAppLiteElmt {
2,220✔
320
        name: b"ssh.protoversion\0".as_ptr() as *const libc::c_char,
2,220✔
321
        desc: b"obsolete keyword, use now ssh.proto\0".as_ptr() as *const libc::c_char,
2,220✔
322
        url: std::ptr::null(),
2,220✔
323
        AppLayerTxMatch: None,
2,220✔
324
        Setup: Some(ssh_proto_obsolete_setup),
2,220✔
325
        Free: None,
2,220✔
326
        flags: 0,
2,220✔
327
    };
2,220✔
328
    _ = SCDetectHelperKeywordRegister(&kw);
2,220✔
329

2,220✔
330
    let kw = SigTableElmtStickyBuffer {
2,220✔
331
        name: String::from("ssh.proto"),
2,220✔
332
        desc: String::from("ssh.proto sticky buffer"),
2,220✔
333
        url: String::from("/rules/ssh-keywords.html#ssh-proto"),
2,220✔
334
        setup: ssh_proto_setup,
2,220✔
335
    };
2,220✔
336
    let ssh_proto_kw_id = helper_keyword_register_sticky_buffer(&kw);
2,220✔
337
    G_SSH_PROTO_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
338
        b"ssh.proto\0".as_ptr() as *const libc::c_char,
2,220✔
339
        b"ssh protocol version field\0".as_ptr() as *const libc::c_char,
2,220✔
340
        ALPROTO_SSH,
2,220✔
341
        STREAM_TOSERVER | STREAM_TOCLIENT,
2,220✔
342
        Some(SCSshTxGetProtocol),
2,220✔
343
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
344
    );
2,220✔
345
    SCDetectHelperKeywordAliasRegister(
2,220✔
346
        ssh_proto_kw_id,
2,220✔
347
        b"ssh_proto\0".as_ptr() as *const libc::c_char,
2,220✔
348
    );
2,220✔
349

2,220✔
350
    let kw = SigTableElmtStickyBuffer {
2,220✔
351
        name: String::from("ssh.hassh.string"),
2,220✔
352
        desc: String::from("ssh.hassh.string sticky buffer"),
2,220✔
353
        url: String::from("/rules/ssh-keywords.html#hassh.string"),
2,220✔
354
        setup: ssh_hassh_string_setup,
2,220✔
355
    };
2,220✔
356
    DETECT_SSH_HASSH_STRING = helper_keyword_register_sticky_buffer(&kw);
2,220✔
357
    G_SSH_HASSH_STR_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
358
        b"ssh.hassh.string\0".as_ptr() as *const libc::c_char,
2,220✔
359
        b"Ssh Client Key Exchange methods For ssh Clients\0".as_ptr() as *const libc::c_char,
2,220✔
360
        ALPROTO_SSH,
2,220✔
361
        STREAM_TOSERVER,
2,220✔
362
        Some(SCSshTxGetHasshString),
2,220✔
363
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
364
    );
2,220✔
365
    SCDetectHelperKeywordAliasRegister(
2,220✔
366
        DETECT_SSH_HASSH_STRING,
2,220✔
367
        b"ssh-hassh-string\0".as_ptr() as *const libc::c_char,
2,220✔
368
    );
2,220✔
369

2,220✔
370
    let kw = SigTableElmtStickyBuffer {
2,220✔
371
        name: String::from("ssh.hassh.server.string"),
2,220✔
372
        desc: String::from("ssh.hassh.server.string sticky buffer"),
2,220✔
373
        url: String::from("/rules/ssh-keywords.html#ssh.hassh.server.string"),
2,220✔
374
        setup: ssh_hassh_server_string_setup,
2,220✔
375
    };
2,220✔
376
    DETECT_SSH_HASSH_SERVER_STRING = helper_keyword_register_sticky_buffer(&kw);
2,220✔
377
    G_SSH_HASSH_SRV_STR_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
378
        b"ssh.hassh.server.string\0".as_ptr() as *const libc::c_char,
2,220✔
379
        b"Ssh Client Key Exchange methods For ssh Servers\0".as_ptr() as *const libc::c_char,
2,220✔
380
        ALPROTO_SSH,
2,220✔
381
        STREAM_TOCLIENT,
2,220✔
382
        Some(SCSshTxGetHasshString),
2,220✔
383
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
384
    );
2,220✔
385
    SCDetectHelperKeywordAliasRegister(
2,220✔
386
        DETECT_SSH_HASSH_SERVER_STRING,
2,220✔
387
        b"ssh-hassh-server-string\0".as_ptr() as *const libc::c_char,
2,220✔
388
    );
2,220✔
389

2,220✔
390
    let kw = SigTableElmtStickyBuffer {
2,220✔
391
        name: String::from("ssh.hassh"),
2,220✔
392
        desc: String::from("ssh.hassh sticky buffer"),
2,220✔
393
        url: String::from("/rules/ssh-keywords.html#hassh"),
2,220✔
394
        setup: ssh_hassh_setup,
2,220✔
395
    };
2,220✔
396
    DETECT_SSH_HASSH = helper_keyword_register_sticky_buffer(&kw);
2,220✔
397
    G_SSH_HASSH_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
398
        b"ssh.hassh\0".as_ptr() as *const libc::c_char,
2,220✔
399
        b"Ssh Client Fingerprinting For Ssh Clients\0".as_ptr() as *const libc::c_char,
2,220✔
400
        ALPROTO_SSH,
2,220✔
401
        STREAM_TOSERVER,
2,220✔
402
        Some(SCSshTxGetHassh),
2,220✔
403
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
404
    );
2,220✔
405
    SCDetectHelperKeywordAliasRegister(
2,220✔
406
        DETECT_SSH_HASSH,
2,220✔
407
        b"ssh-hassh\0".as_ptr() as *const libc::c_char,
2,220✔
408
    );
2,220✔
409
    SCDetectRegisterBufferLowerMd5Callbacks(b"ssh.hassh\0".as_ptr() as *const libc::c_char);
2,220✔
410

2,220✔
411
    let kw = SigTableElmtStickyBuffer {
2,220✔
412
        name: String::from("ssh.hassh.server"),
2,220✔
413
        desc: String::from("ssh.hassh.server sticky buffer"),
2,220✔
414
        url: String::from("/rules/ssh-keywords.html#ssh.hassh.server"),
2,220✔
415
        setup: ssh_hassh_server_setup,
2,220✔
416
    };
2,220✔
417
    DETECT_SSH_HASSH_SERVER = helper_keyword_register_sticky_buffer(&kw);
2,220✔
418
    G_SSH_HASSH_SRV_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
2,220✔
419
        b"ssh.hassh.server\0".as_ptr() as *const libc::c_char,
2,220✔
420
        b"Ssh Client Fingerprinting For Ssh Servers\0".as_ptr() as *const libc::c_char,
2,220✔
421
        ALPROTO_SSH,
2,220✔
422
        STREAM_TOCLIENT,
2,220✔
423
        Some(SCSshTxGetHassh),
2,220✔
424
        SSHConnectionState::SshStateBannerDone as c_int,
2,220✔
425
    );
2,220✔
426
    SCDetectHelperKeywordAliasRegister(
2,220✔
427
        DETECT_SSH_HASSH_SERVER,
2,220✔
428
        b"ssh-hassh-server\0".as_ptr() as *const libc::c_char,
2,220✔
429
    );
2,220✔
430
    SCDetectRegisterBufferLowerMd5Callbacks(b"ssh.hassh.server\0".as_ptr() as *const libc::c_char);
2,220✔
431
}
2,220✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc