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

OISF / suricata / 22550902417

01 Mar 2026 07:32PM UTC coverage: 68.401% (-5.3%) from 73.687%
22550902417

Pull #14922

github

web-flow
github-actions: bump actions/upload-artifact from 6.0.0 to 7.0.0

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #14922: github-actions: bump actions/upload-artifact from 6.0.0 to 7.0.0

218243 of 319063 relevant lines covered (68.4%)

3284926.58 hits per line

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

56.29
/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(
82✔
35
    tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
82✔
36
) -> bool {
82✔
37
    let tx = cast_pointer!(tx, SSHTransaction);
82✔
38
    match direction.into() {
82✔
39
        Direction::ToServer => {
40
            let m = &tx.cli_hdr.protover;
71✔
41
            if !m.is_empty() {
71✔
42
                *buffer = m.as_ptr();
70✔
43
                *buffer_len = m.len() as u32;
70✔
44
                return true;
70✔
45
            }
1✔
46
        }
47
        Direction::ToClient => {
48
            let m = &tx.srv_hdr.protover;
11✔
49
            if !m.is_empty() {
11✔
50
                *buffer = m.as_ptr();
10✔
51
                *buffer_len = m.len() as u32;
10✔
52
                return true;
10✔
53
            }
1✔
54
        }
55
    }
56
    *buffer = ptr::null();
2✔
57
    *buffer_len = 0;
2✔
58

2✔
59
    return false;
2✔
60
}
82✔
61

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

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

×
116
    return false;
×
117
}
×
118

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

×
145
    return false;
×
146
}
×
147

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

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

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

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

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

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

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

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

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

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

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

267
unsafe extern "C" fn ssh_proto_obsolete_setup(
×
268
    _de: *mut DetectEngineCtx, _s: *mut Signature, _raw: *const std::os::raw::c_char,
×
269
) -> c_int {
×
270
    SCLogError!("ssh.softwareversion is obsolete, use now ssh.software");
×
271
    return -1;
×
272
}
×
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() {
37✔
288
    let kw = SigTableElmtStickyBuffer {
37✔
289
        name: String::from("ssh.software"),
37✔
290
        desc: String::from("ssh.software sticky buffer"),
37✔
291
        url: String::from("/rules/ssh-keywords.html#ssh-software"),
37✔
292
        setup: ssh_software_setup,
37✔
293
    };
37✔
294
    let ssh_software_kw_id = helper_keyword_register_sticky_buffer(&kw);
37✔
295
    G_SSH_SOFTWARE_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
37✔
296
        b"ssh_software\0".as_ptr() as *const libc::c_char,
37✔
297
        b"ssh software field\0".as_ptr() as *const libc::c_char,
37✔
298
        ALPROTO_SSH,
37✔
299
        STREAM_TOSERVER | STREAM_TOCLIENT,
37✔
300
        Some(SCSshTxGetSoftware),
37✔
301
        SSHConnectionState::SshStateBannerDone as c_int,
37✔
302
    );
37✔
303
    SCDetectHelperKeywordAliasRegister(
37✔
304
        ssh_software_kw_id,
37✔
305
        b"ssh_software\0".as_ptr() as *const libc::c_char,
37✔
306
    );
37✔
307

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

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

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

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

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

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

37✔
411
    let kw = SigTableElmtStickyBuffer {
37✔
412
        name: String::from("ssh.hassh.server"),
37✔
413
        desc: String::from("ssh.hassh.server sticky buffer"),
37✔
414
        url: String::from("/rules/ssh-keywords.html#ssh.hassh.server"),
37✔
415
        setup: ssh_hassh_server_setup,
37✔
416
    };
37✔
417
    DETECT_SSH_HASSH_SERVER = helper_keyword_register_sticky_buffer(&kw);
37✔
418
    G_SSH_HASSH_SRV_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
37✔
419
        b"ssh.hassh.server\0".as_ptr() as *const libc::c_char,
37✔
420
        b"Ssh Client Fingerprinting For Ssh Servers\0".as_ptr() as *const libc::c_char,
37✔
421
        ALPROTO_SSH,
37✔
422
        STREAM_TOCLIENT,
37✔
423
        Some(SCSshTxGetHassh),
37✔
424
        SSHConnectionState::SshStateBannerDone as c_int,
37✔
425
    );
37✔
426
    SCDetectHelperKeywordAliasRegister(
37✔
427
        DETECT_SSH_HASSH_SERVER,
37✔
428
        b"ssh-hassh-server\0".as_ptr() as *const libc::c_char,
37✔
429
    );
37✔
430
    SCDetectRegisterBufferLowerMd5Callbacks(b"ssh.hassh.server\0".as_ptr() as *const libc::c_char);
37✔
431
}
37✔
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