pull/16515/merge
Giuseppe Longo 10 hours ago committed by GitHub
commit 6079963f55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -3388,3 +3388,27 @@ Example ::
"min_ttl": 1,
"max_ttl": 1
}
Event type: IMAP
----------------
Fields
~~~~~~
* "requests": Array of IMAP request lines sent by the client. Each entry is
formatted as "tag command arguments". ``LOGIN`` arguments and SASL initial
responses on ``AUTHENTICATE`` commands are replaced with ``<redacted>``.
Client responses to SASL continuation requests are not logged.
* "responses": Array of IMAP response lines from the server.
Example ::
"imap": {
"requests": [
"8 UID fetch 1 (UID RFC822.SIZE BODY.PEEK[])"
],
"responses": [
"* 1 FETCH (UID 1 RFC822.SIZE 452 BODY[] {452})",
"8 OK UID FETCH completed"
]
}

@ -0,0 +1,79 @@
IMAP Keywords
=============
.. role:: example-rule-action
.. role:: example-rule-header
.. role:: example-rule-options
.. role:: example-rule-emphasis
imap.request
------------
Matches on IMAP request lines sent from the client to the server.
Each buffer is a request line as sent by the client, without the trailing
CRLF. Literal data is not part of the buffer. Unlike the EVE
``imap.requests`` field, ``LOGIN`` and ``AUTHENTICATE`` arguments are not
redacted.
Syntax::
imap.request; content:"<content to match against>";
``imap.request`` is a 'sticky buffer' and can be used as a ``fast_pattern``.
``imap.request`` supports multiple buffer matching, see :doc:`multi-buffer-matching`.
This keyword maps to the EVE field ``imap.requests[]``
Examples
^^^^^^^^
Example of a signature that would alert if an IMAP request contains a LOGIN command:
.. container:: example-rule
alert imap any any -> any any (msg:"IMAP LOGIN request"; :example-rule-emphasis:`imap.request; content:"LOGIN";` sid:1;)
imap.response
-------------
Matches on IMAP response lines sent from the server to the client.
Syntax::
imap.response; content:"<content to match against>";
``imap.response`` is a 'sticky buffer' and can be used as a ``fast_pattern``.
``imap.response`` supports multiple buffer matching, see :doc:`multi-buffer-matching`.
This keyword maps to the EVE field ``imap.responses[]``
Examples
^^^^^^^^
Example of a signature that would alert if an IMAP response contains "OK":
.. container:: example-rule
alert imap any any -> any any (msg:"IMAP OK response"; :example-rule-emphasis:`imap.response; content:"OK";` sid:1;)
Frames
------
The IMAP parser supports the following frames:
* imap.pdu
imap.pdu
^^^^^^^^
A single IMAP request or response PDU. Each command from the client or
response line from the server creates a separate frame.
.. container:: example-rule
alert imap any any -> any any (\
:example-rule-options:`frame:imap.pdu; content:"LOGIN"; startswith;` \
sid:1;)

@ -41,6 +41,7 @@ Suricata Rules
quic-keywords
nfs-keywords
smtp-keywords
imap-keywords
websocket-keywords
app-layer
decode-layer

@ -94,6 +94,8 @@ following keywords:
* ``http.response_header``
* ``http2.header_name``
* ``ike.vendor``
* ``imap.request``
* ``imap.response``
* ``krb5.cname``
* ``krb5.sname``
* ``ldap.request.attribute_type``

@ -2832,6 +2832,37 @@
}
}
},
"imap": {
"type": "object",
"description": "IMAP transaction data",
"additionalProperties": false,
"properties": {
"requests": {
"type": "array",
"description": "Array of IMAP request lines in this transaction",
"items": {
"type": "string"
},
"suricata": {
"keywords": [
"imap.request"
]
}
},
"responses": {
"type": "array",
"description": "Array of IMAP response lines in this transaction",
"items": {
"type": "string"
},
"suricata": {
"keywords": [
"imap.response"
]
}
}
}
},
"in_iface": {
"type": "string"
},

@ -12,6 +12,7 @@ files.rules \
ftp-events.rules \
http-events.rules \
http2-events.rules \
imap-events.rules \
ipsec-events.rules \
kerberos-events.rules \
ldap-events.rules \

@ -39,6 +39,7 @@ signature IDs.
| PGSQL | 2241000 | 2241999 |
| mDNS | 2242000 | 2242999 |
| Bittorent| 2243000 | 2243999 |
| IMAP | 2244000 | 2244999 |
| MODBUS | 2250000 | 2250999 |
| DNP3 | 2270000 | 2270999 |
| SIP | 2280000 | 2280999 |

@ -0,0 +1,8 @@
# IMAP app layer event rules
#
# SID's fall in the 2244000+ range. See rules/README.md
alert imap any any -> any any (msg:"SURICATA IMAP too many transactions"; app-layer-event:imap.too_many_transactions; classtype:protocol-command-decode; sid:2244000; rev:1;)
alert imap any any -> any any (msg:"SURICATA IMAP invalid data"; app-layer-event:imap.invalid_data; classtype:protocol-command-decode; sid:2244001; rev:1;)
alert imap any any -> any any (msg:"SURICATA IMAP line too long"; app-layer-event:imap.line_too_long; classtype:protocol-command-decode; sid:2244002; rev:1;)
alert imap any any -> any any (msg:"SURICATA IMAP data limit reached"; app-layer-event:imap.data_limit_reached; classtype:protocol-command-decode; sid:2244003; rev:1;)

@ -0,0 +1,153 @@
/* Copyright (C) 2026 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.
*/
// Author: Giuseppe Longo <glongo@oisf.net>
use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
use crate::detect::{
SIGMATCH_INFO_MULTI_BUFFER, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT,
SIGMATCH_SUPPORT_FIREWALL,
};
use crate::imap::imap::{ImapTransaction, ALPROTO_IMAP};
use std::ffi::CString;
use std::os::raw::{c_int, c_void};
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, SCDetectBufferSetActiveList,
SCDetectHelperKeywordRegister, SCDetectHelperKeywordSetCleanCString,
SCDetectHelperMultiBufferProgressMpmRegister, SCDetectSignatureSetAppProto,
SCSigTableAppLiteElmt, Signature,
};
static mut G_IMAP_REQUEST_BUFFER_ID: c_int = 0;
static mut G_IMAP_RESPONSE_BUFFER_ID: c_int = 0;
unsafe extern "C" fn imap_detect_request_setup(
de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_IMAP) != 0 {
return -1;
}
if SCDetectBufferSetActiveList(de, s, G_IMAP_REQUEST_BUFFER_ID) < 0 {
return -1;
}
0
}
unsafe extern "C" fn imap_tx_get_request(
_de: *mut DetectEngineThreadCtx, tx: *const c_void, _flags: u8, local_id: u32,
buffer: *mut *const u8, buffer_len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, ImapTransaction);
let Some(request) = tx.requests.get(local_id as usize) else {
return false;
};
*buffer = request.raw_line.as_ptr();
*buffer_len = request.raw_line.len() as u32;
true
}
unsafe extern "C" fn imap_detect_response_setup(
de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_IMAP) != 0 {
return -1;
}
if SCDetectBufferSetActiveList(de, s, G_IMAP_RESPONSE_BUFFER_ID) < 0 {
return -1;
}
0
}
unsafe extern "C" fn imap_tx_get_response(
_de: *mut DetectEngineThreadCtx, tx: *const c_void, _flags: u8, local_id: u32,
buffer: *mut *const u8, buffer_len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, ImapTransaction);
let Some(line) = tx.response_lines.get(local_id as usize) else {
return false;
};
*buffer = line.as_ptr();
*buffer_len = line.len() as u32;
true
}
#[no_mangle]
pub unsafe extern "C" fn SCDetectImapRegister() {
let name = CString::new("imap.request").unwrap().into_raw();
let desc = CString::new("match on IMAP request line")
.unwrap()
.into_raw();
let url = CString::new("/rules/imap-keywords.html#imap-request")
.unwrap()
.into_raw();
let kw = SCSigTableAppLiteElmt {
name,
desc,
url,
Setup: Some(imap_detect_request_setup),
flags: SIGMATCH_NOOPT
| SIGMATCH_INFO_STICKY_BUFFER
| SIGMATCH_INFO_MULTI_BUFFER
| SIGMATCH_SUPPORT_FIREWALL,
AppLayerTxMatch: None,
Free: None,
};
let r = SCDetectHelperKeywordRegister(&kw);
SCDetectHelperKeywordSetCleanCString(r);
G_IMAP_REQUEST_BUFFER_ID = SCDetectHelperMultiBufferProgressMpmRegister(
b"imap.request\0".as_ptr() as *const libc::c_char,
b"IMAP REQUEST LINE\0".as_ptr() as *const libc::c_char,
ALPROTO_IMAP,
STREAM_TOSERVER,
Some(imap_tx_get_request),
0,
);
let name = CString::new("imap.response").unwrap().into_raw();
let desc = CString::new("match on IMAP response line")
.unwrap()
.into_raw();
let url = CString::new("/rules/imap-keywords.html#imap-response")
.unwrap()
.into_raw();
let kw = SCSigTableAppLiteElmt {
name,
desc,
url,
Setup: Some(imap_detect_response_setup),
flags: SIGMATCH_NOOPT
| SIGMATCH_INFO_STICKY_BUFFER
| SIGMATCH_INFO_MULTI_BUFFER
| SIGMATCH_SUPPORT_FIREWALL,
AppLayerTxMatch: None,
Free: None,
};
let r = SCDetectHelperKeywordRegister(&kw);
SCDetectHelperKeywordSetCleanCString(r);
G_IMAP_RESPONSE_BUFFER_ID = SCDetectHelperMultiBufferProgressMpmRegister(
b"imap.response\0".as_ptr() as *const libc::c_char,
b"IMAP RESPONSE LINE\0".as_ptr() as *const libc::c_char,
ALPROTO_IMAP,
STREAM_TOCLIENT,
Some(imap_tx_get_response),
1,
);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,97 @@
/* Copyright (C) 2026 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.
*/
// Author: Giuseppe Longo <glongo@oisf.net>
use std::borrow::Cow;
use crate::imap::imap::ImapTransaction;
use crate::imap::parser::{ImapCommand, ImapMessage, ImapMessageType};
use crate::jsonbuilder::{JsonBuilder, JsonError};
const REDACTED: &str = "<redacted>";
fn log_request_line(
request: &ImapMessage, suppress_continuation_data: bool,
) -> Option<Cow<'_, str>> {
if request.raw_line.is_empty() {
return None;
}
match &request.message {
ImapMessageType::ContinuationData if suppress_continuation_data => None,
ImapMessageType::Command {
command: ImapCommand::Login,
arguments,
..
} if !arguments.is_empty() => {
let tag = request.tag_str();
Some(Cow::Owned(format!("{tag} LOGIN {REDACTED}")))
}
ImapMessageType::Command {
command: ImapCommand::Authenticate,
arguments,
..
} if arguments.len() > 1 => {
let tag = request.tag_str();
let mechanism = String::from_utf8_lossy(&arguments[0]);
Some(Cow::Owned(format!(
"{tag} AUTHENTICATE {mechanism} {REDACTED}"
)))
}
_ => Some(String::from_utf8_lossy(&request.raw_line)),
}
}
fn log_imap(tx: &ImapTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("imap")?;
if !tx.requests.is_empty() {
js.open_array("requests")?;
let suppress_continuation_data = tx.command.eq_ignore_ascii_case(b"AUTHENTICATE")
|| tx.command.eq_ignore_ascii_case(b"LOGIN");
for req in &tx.requests {
if let Some(line) = log_request_line(req, suppress_continuation_data) {
js.append_string(&line)?;
}
}
js.close()?;
}
if !tx.response_lines.is_empty() {
js.open_array("responses")?;
for line in &tx.response_lines {
js.append_string(&String::from_utf8_lossy(line))?;
}
js.close()?;
}
js.close()?;
Ok(())
}
#[no_mangle]
pub unsafe extern "C" fn SCImapLoggerLog(
tx: *mut std::os::raw::c_void, js: &mut JsonBuilder,
) -> bool {
let tx = cast_pointer!(tx, ImapTransaction);
log_imap(tx, js).is_ok()
}

@ -1,4 +1,4 @@
/* Copyright (C) 2024 Open Information Security Foundation
/* Copyright (C) 2026 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
@ -15,14 +15,9 @@
* 02110-1301, USA.
*/
/**
* \file
*
* \author Mahmoud Maatuq <mahmoudmatook.mm@gmail.com>
*
*/
// Author: Giuseppe Longo <glongo@oisf.net>
#ifndef SURICATA_APP_LAYER_IMAP_H
#define SURICATA_APP_LAYER_IMAP_H
void RegisterIMAPParsers(void);
#endif
pub mod detect;
pub mod imap;
pub mod logger;
pub mod parser;

File diff suppressed because it is too large Load Diff

@ -140,6 +140,7 @@ pub mod util;
pub mod websocket;
pub mod x509;
pub use suricata_ffi::direction;
pub mod imap;
pub mod llmnr;
#[allow(unused_imports)]

@ -1332,6 +1332,12 @@ extern "C" {
pp_max_depth: u16,
) -> ::std::os::raw::c_int;
}
extern "C" {
#[doc = " \\brief Get the size of the stream data available for protocol detection\n in the given direction, for use by probing parsers.\n\n \\retval bool false if the flow has no TCP session"]
pub fn SCAppLayerProtoDetectGetStreamDataSize(
f: *const Flow, direction: u8, size: *mut u32,
) -> bool;
}
extern "C" {
pub fn SCAppLayerRequestProtocolTLSUpgrade(f: *mut Flow) -> bool;
}
@ -1874,6 +1880,9 @@ extern "C" {
extern "C" {
pub fn SCFlowGetAppProtocol(f: *const Flow) -> AppProto;
}
extern "C" {
pub fn SCFlowGetAppProtocolToClient(f: *const Flow) -> AppProto;
}
#[doc = " \\brief Function type for flow initialization callbacks.\n\n Once registered with SCFlowRegisterInitCallback, this function will\n be called every time a flow is initialized, or in other words,\n every time Suricata picks up a flow.\n\n \\param tv The ThreadVars data structure for the thread creating the\n flow.\n \\param f The newly initialized flow.\n \\param p The packet related to creating the new flow.\n \\param user The user data provided during callback registration."]
pub type SCFlowInitCallbackFn = ::std::option::Option<
unsafe extern "C" fn(

@ -37,7 +37,6 @@ noinst_HEADERS = \
app-layer-htp.h \
app-layer-http2.h \
app-layer-ike.h \
app-layer-imap.h \
app-layer-modbus.h \
app-layer-nfs-tcp.h \
app-layer-nfs-udp.h \
@ -615,7 +614,6 @@ libsuricata_c_a_SOURCES = \
app-layer-htp.c \
app-layer-http2.c \
app-layer-ike.c \
app-layer-imap.c \
app-layer-modbus.c \
app-layer-nfs-tcp.c \
app-layer-nfs-udp.c \

@ -1668,6 +1668,17 @@ int SCAppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto,
SCReturnInt(r);
}
bool SCAppLayerProtoDetectGetStreamDataSize(const Flow *f, uint8_t direction, uint32_t *size)
{
TcpSession *ssn = (TcpSession *)f->protoctx;
if (f->proto != IPPROTO_TCP || ssn == NULL) {
return false;
}
TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
*size = StreamDataAvailableForProtoDetect(stream);
return true;
}
/***** Setup/General Registration *****/
int AppLayerProtoDetectSetup(void)

@ -93,6 +93,14 @@ int SCAppLayerProtoDetectPMRegisterPatternCIwPP(uint8_t ipproto, AppProto alprot
const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction,
ProbingParserFPtr PPFunc, uint16_t pp_min_depth, uint16_t pp_max_depth);
/**
* \brief Get the size of the stream data available for protocol detection
* in the given direction, for use by probing parsers.
*
* \retval bool false if the flow has no TCP session
*/
bool SCAppLayerProtoDetectGetStreamDataSize(const Flow *f, uint8_t direction, uint32_t *size);
/***** Setup/General Registration *****/
/**

@ -1,133 +0,0 @@
/* Copyright (C) 2024 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.
*/
/**
* \file
*
* \author Mahmoud Maatuq <mahmoudmatook.mm@gmail.com>
*
*/
#include "suricata-common.h"
#include "app-layer-detect-proto.h"
#include "app-layer-imap.h"
#include "app-layer-protos.h"
#include "rust.h"
#include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h"
#include "util-debug.h"
static AppProto ImapClientProbingParser(
const Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir)
{
// This is called after " CAPABILITY" pattern has been found
if (f->alproto_tc == ALPROTO_IMAP) {
// server was already recognised as IMAP, so ok
return ALPROTO_IMAP;
}
for (size_t i = 0; i < len; i++) {
if (input[i] >= '0' && input[i] <= '9') {
// We check if the tag at the beginning of the input contains a number
return ALPROTO_IMAP;
}
if (input[i] == ' ') {
break;
}
}
TcpSession *ssn = (TcpSession *)f->protoctx;
if (ssn == NULL) {
return ALPROTO_FAILED;
}
const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
if (size_tc < 8 && f->alproto_tc == ALPROTO_UNKNOWN) {
// wait for another packet from server
return ALPROTO_UNKNOWN;
}
return ALPROTO_FAILED;
}
static int IMAPRegisterPatternsForProtocolDetection(void)
{
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* OK ", 5, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* NO ", 5, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* BAD ", 6, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* LIST ", 7, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* ESEARCH ", 10, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* STATUS ", 9, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
if (SCAppLayerProtoDetectPMRegisterPatternCI(
IPPROTO_TCP, ALPROTO_IMAP, "* FLAGS ", 8, 0, STREAM_TOCLIENT) < 0) {
return -1;
}
/**
* there is no official document that limits the length of the tag
* some practical implementations limit it to 20 characters
* but keeping depth equal to 31 fails unit tests such AppLayerTest10
* so keeping depth 17 for now to pass unit tests, that might miss some detections
* until we find a better solution for the unit tests.
*
* AppLayerTest10 fails because it expects protocol detection to be completed with only 17 bytes
* as input, and with this new pattern, we would need more bytes to finish protocol detection.
*/
if (SCAppLayerProtoDetectPMRegisterPatternCIwPP(IPPROTO_TCP, ALPROTO_IMAP, " CAPABILITY",
17 /*6 for max tag len + space + len(CAPABILITY)*/, 0, STREAM_TOSERVER,
ImapClientProbingParser, 12, 17) < 0) {
return -1;
}
return 0;
}
void RegisterIMAPParsers(void)
{
const char *proto_name = "imap";
if (SCAppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
SCLogDebug("IMAP protocol detection is enabled.");
AppLayerProtoDetectRegisterProtocol(ALPROTO_IMAP, proto_name);
if (IMAPRegisterPatternsForProtocolDetection() < 0)
SCLogError("Failed to register IMAP protocol detection patterns.");
} else {
SCLogDebug("Protocol detector and parser disabled for IMAP.");
}
}

@ -55,7 +55,6 @@
#include "app-layer-tftp.h"
#include "app-layer-ike.h"
#include "app-layer-http2.h"
#include "app-layer-imap.h"
#include "conf.h"
#include "decode.h"
#include "detect.h"
@ -2056,9 +2055,9 @@ void AppLayerParserRegisterProtocolParsers(void)
SCRegisterRdpParser();
RegisterHTTP2Parsers();
SCRegisterTelnetParser();
RegisterIMAPParsers();
SCRegisterLLMNRUdpParser();
SCRegisterLLMNRTcpParser();
SCRegisterImapParser();
for (size_t i = 0; i < preregistered_callbacks_nb; i++) {
PreRegisteredCallbacks[i]();

@ -861,6 +861,7 @@ void SigTableSetup(void)
SCDetectSipRegister();
SCDetectTemplateRegister();
SCDetectLdapRegister();
SCDetectImapRegister();
SCDetectSdpRegister();
SCDetectDNSRegister();
SCDetectPgsqlRegister();

@ -47,5 +47,6 @@ const uint8_t *SCFlowGetDestinationAddressAsRawPtr(const Flow *flow);
uint32_t SCFlowGetToServerPacketCount(const Flow *flow);
uint32_t SCFlowGetToClientPacketCount(const Flow *flow);
AppProto SCFlowGetAppProtocol(const Flow *f);
AppProto SCFlowGetAppProtocolToClient(const Flow *f);
#endif /* SURICATA_FLOW_BINDGEN_H */

@ -1290,6 +1290,11 @@ AppProto SCFlowGetAppProtocol(const Flow *f)
return f->alproto;
}
AppProto SCFlowGetAppProtocolToClient(const Flow *f)
{
return f->alproto_tc;
}
/**
* \brief Get flow destination port.
*

@ -990,6 +990,7 @@ void OutputRegisterRootLoggers(void)
// underscore instead of dash for bittorrent_dht
RegisterSimpleJsonApplayerLogger(ALPROTO_BITTORRENT_DHT,
(EveJsonSimpleTxLogFunc)SCBittorrentDhtLogger, "bittorrent_dht");
RegisterSimpleJsonApplayerLogger(ALPROTO_IMAP, (EveJsonSimpleTxLogFunc)SCImapLoggerLog, NULL);
OutputPacketLoggerRegister();
OutputFiledataLoggerRegister();
@ -1236,6 +1237,10 @@ void OutputRegisterLoggers(void)
JsonArpLogRegister();
/* LLMNR JSON logger */
JsonLLMNRLogRegister();
/* IMAP JSON logger. */
OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonImapLog", "eve-log.imap",
OutputJsonLogInitSub, ALPROTO_IMAP, JsonGenericDirFlowLogger, JsonLogThreadInit,
JsonLogThreadDeinit);
for (size_t i = 0; i < preregistered_loggers_nb; i++) {
OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", preregistered_loggers[i].logname,

@ -347,6 +347,7 @@ outputs:
- pop3
- llmnr
#- modbus
- imap
- arp:
enabled: no # Many events can be logged. Disabled by default
- dhcp:
@ -1082,7 +1083,8 @@ app-layer:
content-inspect-min-size: 32768
content-inspect-window: 4096
imap:
enabled: detection-only
enabled: yes
# max-tx: 256
pop3:
enabled: yes
detection-ports:

Loading…
Cancel
Save