detect/krb5: move krb5.ticket_encryption to rust

Ticket: 8648
pull/15726/head
Philippe Antoine 1 month ago committed by Victor Julien
parent 8f0dbc0b63
commit a81031591e

@ -83,7 +83,7 @@ unsafe extern "C" fn krb5_sname_get_data(
const KRB_TICKET_FASTARRAY_SIZE: usize = 256;
#[derive(Debug)]
pub struct DetectKrb5TicketEncryptionList {
struct DetectKrb5TicketEncryptionList {
positive: [bool; KRB_TICKET_FASTARRAY_SIZE],
negative: [bool; KRB_TICKET_FASTARRAY_SIZE],
other: Vec<EncryptionType>,
@ -96,7 +96,7 @@ impl Default for DetectKrb5TicketEncryptionList {
}
impl DetectKrb5TicketEncryptionList {
pub fn new() -> Self {
fn new() -> Self {
Self {
positive: [false; KRB_TICKET_FASTARRAY_SIZE],
negative: [false; KRB_TICKET_FASTARRAY_SIZE],
@ -105,20 +105,20 @@ impl DetectKrb5TicketEncryptionList {
}
}
// Suppress large enum variant lint as the LIST is very large compared
// Suppress large enum variant lint as the List is very large compared
// to the boolean variant.
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum DetectKrb5TicketEncryptionData {
WEAK(bool),
LIST(DetectKrb5TicketEncryptionList),
enum DetectKrb5TicketEncryptionData {
Weak(bool),
List(DetectKrb5TicketEncryptionList),
}
pub fn detect_parse_encryption_weak(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
fn detect_parse_encryption_weak(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
let (i, neg) = opt(char('!')).parse(i)?;
let (i, _) = tag("weak").parse(i)?;
let value = neg.is_none();
return Ok((i, DetectKrb5TicketEncryptionData::WEAK(value)));
return Ok((i, DetectKrb5TicketEncryptionData::Weak(value)));
}
trait MyFromStr {
@ -175,11 +175,11 @@ impl MyFromStr for EncryptionType {
}
}
pub fn is_alphanumeric_or_dash(chr: char) -> bool {
fn is_alphanumeric_or_dash(chr: char) -> bool {
return chr.is_alphanumeric() || chr == '-';
}
pub fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> {
fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> {
let (i, _) = opt(is_a(" ")).parse(i)?;
let (i, e) = map_res(take_while1(is_alphanumeric_or_dash), |s: &str| {
EncryptionType::from_str(s)
@ -190,7 +190,7 @@ pub fn detect_parse_encryption_item(i: &str) -> IResult<&str, EncryptionType> {
return Ok((i, e));
}
pub fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
let mut l = DetectKrb5TicketEncryptionList::new();
let (i, v) = many1(detect_parse_encryption_item).parse(i)?;
for &val in v.iter() {
@ -204,18 +204,17 @@ pub fn detect_parse_encryption_list(i: &str) -> IResult<&str, DetectKrb5TicketEn
l.other.push(val);
}
}
return Ok((i, DetectKrb5TicketEncryptionData::LIST(l)));
return Ok((i, DetectKrb5TicketEncryptionData::List(l)));
}
pub fn detect_parse_encryption(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
fn detect_parse_encryption(i: &str) -> IResult<&str, DetectKrb5TicketEncryptionData> {
let (i, _) = opt(is_a(" ")).parse(i)?;
let (i, parsed) = alt((detect_parse_encryption_weak, detect_parse_encryption_list)).parse(i)?;
let (i, _) = all_consuming(take_while(|c| c == ' ')).parse(i)?;
return Ok((i, parsed));
}
#[no_mangle]
pub unsafe extern "C" fn SCKrb5DetectEncryptionParse(
unsafe extern "C" fn krb5_detect_encryption_parse(
ustr: *const std::os::raw::c_char,
) -> *mut DetectKrb5TicketEncryptionData {
let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe
@ -228,18 +227,20 @@ pub unsafe extern "C" fn SCKrb5DetectEncryptionParse(
return std::ptr::null_mut();
}
#[no_mangle]
pub unsafe extern "C" fn SCKrb5DetectEncryptionMatch(
tx: &KRB5Transaction, ctx: &DetectKrb5TicketEncryptionData,
) -> std::os::raw::c_int {
unsafe extern "C" fn krb5_ticket_encryption_match(
_de: *mut DetectEngineThreadCtx, _f: *mut Flow, _flags: u8, _state: *mut c_void,
tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx,
) -> c_int {
let tx = cast_pointer!(tx, KRB5Transaction);
let ctx = cast_pointer!(ctx, DetectKrb5TicketEncryptionData);
if let Some(x) = tx.ticket_etype {
match ctx {
DetectKrb5TicketEncryptionData::WEAK(w) => {
DetectKrb5TicketEncryptionData::Weak(w) => {
if (test_weak_encryption(x) && *w) || (!test_weak_encryption(x) && !*w) {
return 1;
}
}
DetectKrb5TicketEncryptionData::LIST(l) => {
DetectKrb5TicketEncryptionData::List(l) => {
let vali = x.0;
if vali < 0 && ((-vali) as usize) < KRB_TICKET_FASTARRAY_SIZE {
if l.negative[(-vali) as usize] {
@ -262,12 +263,6 @@ pub unsafe extern "C" fn SCKrb5DetectEncryptionMatch(
return 0;
}
#[no_mangle]
pub unsafe extern "C" fn SCKrb5DetectEncryptionFree(ctx: &mut DetectKrb5TicketEncryptionData) {
// Just unbox...
std::mem::drop(Box::from_raw(ctx));
}
#[cfg(test)]
mod tests {
@ -278,7 +273,7 @@ mod tests {
match detect_parse_encryption(" weak ") {
Ok((rem, ctx)) => {
match ctx {
DetectKrb5TicketEncryptionData::WEAK(w) => {
DetectKrb5TicketEncryptionData::Weak(w) => {
assert!(w);
}
_ => {
@ -295,7 +290,7 @@ mod tests {
match detect_parse_encryption("!weak") {
Ok((rem, ctx)) => {
match ctx {
DetectKrb5TicketEncryptionData::WEAK(w) => {
DetectKrb5TicketEncryptionData::Weak(w) => {
assert!(!w);
}
_ => {
@ -312,7 +307,7 @@ mod tests {
match detect_parse_encryption(" des-cbc-crc , -128,2 257") {
Ok((rem, ctx)) => {
match ctx {
DetectKrb5TicketEncryptionData::LIST(l) => {
DetectKrb5TicketEncryptionData::List(l) => {
assert!(l.positive[EncryptionType::DES_CBC_CRC.0 as usize]);
assert!(l.negative[128]);
assert!(l.positive[2]);
@ -332,7 +327,7 @@ mod tests {
}
let ctx = detect_parse_encryption("-2147483648").unwrap().1;
match ctx {
DetectKrb5TicketEncryptionData::LIST(l) => {
DetectKrb5TicketEncryptionData::List(l) => {
assert_eq!(l.other.len(), 1);
assert_eq!(l.other[0], EncryptionType(i32::MIN));
}
@ -348,6 +343,8 @@ static mut G_KRB5_GENERIC_BUFFER_ID: c_int = 0;
static mut G_KRB5_ERR_CODE_KW_ID: u16 = 0;
static mut G_KRB5_CNAME_BUFFER_ID: c_int = 0;
static mut G_KRB5_SNAME_BUFFER_ID: c_int = 0;
static mut G_KRB5_TICKET_ENCRYPTION_KW_ID: u16 = 0;
static mut G_KRB5_TICKET_ENCRYPTION_BUFFER_ID: c_int = 0;
// We should apply the derive on the kerberos_parser MessageType
#[repr(u32)]
@ -501,6 +498,36 @@ unsafe extern "C" fn krb5_cname_setup(
return 0;
}
unsafe extern "C" fn krb5_ticket_encryption_setup(
de: *mut DetectEngineCtx, s: *mut Signature, raw: *const libc::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_KRB5 as AppProto) != 0 {
return -1;
}
let ctx = krb5_detect_encryption_parse(raw) as *mut c_void;
if ctx.is_null() {
return -1;
}
if SCSigMatchAppendSMToList(
de,
s,
G_KRB5_TICKET_ENCRYPTION_KW_ID,
ctx as *mut SigMatchCtx,
G_KRB5_TICKET_ENCRYPTION_BUFFER_ID,
)
.is_null()
{
krb5_ticket_encryption_free(std::ptr::null_mut(), ctx);
return -1;
}
return 0;
}
unsafe extern "C" fn krb5_ticket_encryption_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) {
let ctx = cast_pointer!(ctx, DetectKrb5TicketEncryptionData);
std::mem::drop(Box::from_raw(ctx));
}
#[no_mangle]
pub unsafe extern "C" fn SCDetectKrb5Register() {
let kw = SCSigTableAppLiteElmt {
@ -570,4 +597,22 @@ pub unsafe extern "C" fn SCDetectKrb5Register() {
krb5_cname_hdr_kw_id,
b"krb5_cname\0".as_ptr() as *const libc::c_char,
);
let kw = SCSigTableAppLiteElmt {
name: b"krb5.ticket_encryption\0".as_ptr() as *const libc::c_char,
desc: b"match Kerberos 5 ticket encryption\0".as_ptr() as *const libc::c_char,
url: b"/rules/kerberos-keywords.html#krb5-ticket-encryption\0".as_ptr()
as *const libc::c_char,
AppLayerTxMatch: Some(krb5_ticket_encryption_match),
Setup: Some(krb5_ticket_encryption_setup),
Free: Some(krb5_ticket_encryption_free),
flags: 0,
};
G_KRB5_TICKET_ENCRYPTION_KW_ID = SCDetectHelperKeywordRegister(&kw);
G_KRB5_TICKET_ENCRYPTION_BUFFER_ID = SCDetectHelperBufferProgressRegister(
b"krb5_ticket_encryption\0".as_ptr() as *const libc::c_char,
ALPROTO_KRB5 as AppProto,
STREAM_TOCLIENT,
1,
);
}

@ -242,7 +242,6 @@ noinst_HEADERS = \
detect-isdataat.h \
detect-itype.h \
detect-ja4-hash.h \
detect-krb5-ticket-encryption.h \
detect-l3proto.h \
detect-lua-extensions.h \
detect-lua.h \
@ -820,7 +819,6 @@ libsuricata_c_a_SOURCES = \
detect-isdataat.c \
detect-itype.c \
detect-ja4-hash.c \
detect-krb5-ticket-encryption.c \
detect-l3proto.c \
detect-lua-extensions.c \
detect-lua.c \

@ -196,7 +196,6 @@
#include "detect-icmpv6-mtu.h"
#include "detect-ipv4hdr.h"
#include "detect-ipv6hdr.h"
#include "detect-krb5-ticket-encryption.h"
#include "detect-sip-method.h"
#include "detect-sip-uri.h"
#include "detect-target.h"
@ -713,7 +712,6 @@ void SigTableSetup(void)
DetectEtherhdrRegister();
DetectIpv4hdrRegister();
DetectIpv6hdrRegister();
DetectKrb5TicketEncryptionRegister();
DetectSipMethodRegister();
DetectSipUriRegister();
DetectTargetRegister();

@ -258,8 +258,6 @@ enum DetectKeywordId {
DETECT_DNP3IND,
DETECT_DNP3OBJ,
DETECT_KRB5_TICKET_ENCRYPTION,
DETECT_SIP_METHOD,
DETECT_SIP_URI,
DETECT_TEMPLATE,

@ -1,85 +0,0 @@
/* Copyright (C) 2022 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "suricata-common.h"
#include "rust.h"
#include "detect-krb5-ticket-encryption.h"
#include "detect-engine.h"
#include "detect-parse.h"
static int g_krb5_ticket_encryption_list_id = 0;
static void DetectKrb5TicketEncryptionFree(DetectEngineCtx *de_ctx, void *ptr)
{
SCKrb5DetectEncryptionFree(ptr);
}
static int DetectKrb5TicketEncryptionMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
{
const DetectKrb5TicketEncryptionData *dd = (const DetectKrb5TicketEncryptionData *)ctx;
SCEnter();
SCReturnInt(SCKrb5DetectEncryptionMatch(txv, dd));
}
static int DetectKrb5TicketEncryptionSetup(
DetectEngineCtx *de_ctx, Signature *s, const char *krb5str)
{
DetectKrb5TicketEncryptionData *krb5d = NULL;
if (SCDetectSignatureSetAppProto(s, ALPROTO_KRB5) != 0)
return -1;
krb5d = SCKrb5DetectEncryptionParse(krb5str);
if (krb5d == NULL)
goto error;
if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_KRB5_TICKET_ENCRYPTION, (SigMatchCtx *)krb5d,
g_krb5_ticket_encryption_list_id) == NULL) {
goto error;
}
return 0;
error:
if (krb5d != NULL)
DetectKrb5TicketEncryptionFree(de_ctx, krb5d);
return -1;
}
void DetectKrb5TicketEncryptionRegister(void)
{
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].name = "krb5.ticket_encryption";
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].desc = "match Kerberos 5 ticket encryption";
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].url =
"/rules/kerberos-keywords.html#krb5-ticket-encryption";
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Match = NULL;
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].AppLayerTxMatch = DetectKrb5TicketEncryptionMatch;
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Setup = DetectKrb5TicketEncryptionSetup;
sigmatch_table[DETECT_KRB5_TICKET_ENCRYPTION].Free = DetectKrb5TicketEncryptionFree;
// Tickets are only from server to client
DetectAppLayerInspectEngineRegister("krb5_ticket_encryption", ALPROTO_KRB5, SIG_FLAG_TOCLIENT,
0, DetectEngineInspectGenericList, NULL);
g_krb5_ticket_encryption_list_id = DetectBufferTypeRegister("krb5_ticket_encryption");
SCLogDebug("g_krb5_ticket_encryption_list_id %d", g_krb5_ticket_encryption_list_id);
}

@ -1,23 +0,0 @@
/* Copyright (C) 2022 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H
#define SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H
void DetectKrb5TicketEncryptionRegister(void);
#endif /* SURICATA_DETECT_KRB5_TICKET_ENCRYPTION_H */
Loading…
Cancel
Save