mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
Add support of getting server capabilities to IMAP parser.
This commit is contained in:
parent
4a5737708c
commit
1933299543
7 changed files with 99 additions and 4 deletions
|
@ -6,6 +6,7 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI
|
|||
bro_plugin_begin(Bro IMAP)
|
||||
bro_plugin_cc(Plugin.cc)
|
||||
bro_plugin_cc(IMAP.cc)
|
||||
bro_plugin_bif(events.bif)
|
||||
bro_plugin_pac(imap.pac imap-analyzer.pac imap-protocol.pac)
|
||||
bro_plugin_end()
|
||||
|
||||
|
|
10
src/analyzer/protocol/imap/events.bif
Normal file
10
src/analyzer/protocol/imap/events.bif
Normal file
|
@ -0,0 +1,10 @@
|
|||
## Generated for an SSL/TLS client's initial *hello* message. SSL/TLS sessions
|
||||
## start with an unencrypted handshake, and Bro extracts as much information out
|
||||
## of that as it can. This event provides access to the initial information
|
||||
## sent by the client.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## capabilities: The list of IMAP capabilities as sent by the server.
|
||||
event imap_capabilities%(c: connection, capabilities: string_vec%);
|
||||
|
|
@ -49,9 +49,25 @@ refine connection IMAP_Conn += {
|
|||
return true;
|
||||
%}
|
||||
|
||||
function proc_server_capability(capabilities: Capability[]): bool
|
||||
%{
|
||||
VectorVal* capv = new VectorVal(internal_type("string_vec")->AsVectorType());
|
||||
for ( unsigned int i = 0; i< capabilities->size(); i++ )
|
||||
{
|
||||
const bytestring& capability = (*capabilities)[i]->cap();
|
||||
capv ->Assign(i, new StringVal(capability.length(), (const char*)capability.data()));
|
||||
}
|
||||
|
||||
BifEvent::generate_imap_capabilities(bro_analyzer(), bro_analyzer()->Conn(), capv);
|
||||
return true;
|
||||
%}
|
||||
|
||||
};
|
||||
|
||||
refine typeattr IMAP_TOKEN += &let {
|
||||
proc: bool = $context.connection.proc_imap_token(is_orig, tag, command);
|
||||
refine typeattr ImapToken += &let {
|
||||
proc: bool = $context.connection.proc_imap_token(is_orig, tag, command);
|
||||
};
|
||||
|
||||
refine typeattr ServerCapability += &let {
|
||||
proc: bool = $context.connection.proc_server_capability(capabilities);
|
||||
};
|
||||
|
|
|
@ -1,17 +1,70 @@
|
|||
# commands that we support parsing. The numbers do not really mean anything
|
||||
# in this case
|
||||
enum ImapCommand {
|
||||
CMD_CAPABILITY,
|
||||
CMD_UNKNOWN
|
||||
}
|
||||
|
||||
type TAG = RE/[[:alnum:][:punct:]]+/;
|
||||
type CONTENT = RE/[^\r\n]*/;
|
||||
type SPACING = RE/[ ]+/;
|
||||
type OPTIONALSPACING = RE/[ ]*/;
|
||||
type NEWLINE = RE/[\r\n]+/;
|
||||
type OPTIONALNEWLINE = RE/[\r\n]*/;
|
||||
|
||||
type IMAP_PDU(is_orig: bool) = IMAP_TOKEN(is_orig)[] &until($input.length() == 0);
|
||||
type IMAP_PDU(is_orig: bool) = ImapToken(is_orig)[] &until($input.length() == 0);
|
||||
|
||||
type IMAP_TOKEN(is_orig: bool) = record {
|
||||
type ImapToken(is_orig: bool) = record {
|
||||
tag : TAG;
|
||||
: SPACING;
|
||||
command: TAG;
|
||||
: OPTIONALSPACING;
|
||||
client_or_server: case is_orig of {
|
||||
true -> client: UnknownCommand(this) ;
|
||||
false -> server: ServerContentText(this);
|
||||
} &requires(pcommand) ;
|
||||
} &let {
|
||||
pcommand: int = $context.connection.determine_command(is_orig, tag, command);
|
||||
};
|
||||
|
||||
type ServerContentText(rec: ImapToken) = case rec.pcommand of {
|
||||
CMD_CAPABILITY -> capability: ServerCapability(rec);
|
||||
default -> unknown: UnknownCommand(rec);
|
||||
};
|
||||
|
||||
type Capability = record {
|
||||
cap: TAG;
|
||||
: OPTIONALSPACING;
|
||||
nl: OPTIONALNEWLINE;
|
||||
};
|
||||
|
||||
type ServerCapability(rec: ImapToken) = record {
|
||||
capabilities: Capability[] &until($context.connection.strlen($element.nl) > 0);
|
||||
};
|
||||
|
||||
type UnknownCommand(rec: ImapToken) = record {
|
||||
tagcontent: CONTENT;
|
||||
: NEWLINE;
|
||||
};
|
||||
|
||||
refine connection IMAP_Conn += {
|
||||
|
||||
function determine_command(is_orig: bool, tag: bytestring, command: bytestring): int
|
||||
%{
|
||||
string cmdstr = std_str(command);
|
||||
std::transform(cmdstr.begin(), cmdstr.end(), cmdstr.begin(), ::tolower);
|
||||
string tagstr = std_str(tag);
|
||||
|
||||
if ( !is_orig && cmdstr == "capability" && tag == "*" ) {
|
||||
return CMD_CAPABILITY;
|
||||
}
|
||||
|
||||
return CMD_UNKNOWN;
|
||||
%}
|
||||
|
||||
function strlen(str: bytestring): int
|
||||
%{
|
||||
return str.length();
|
||||
%}
|
||||
|
||||
};
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
%include bro.pac
|
||||
|
||||
%extern{
|
||||
#include "events.bif.h"
|
||||
|
||||
namespace analyzer { namespace imap { class IMAP_Analyzer; } }
|
||||
namespace binpac { namespace IMAP { class IMAP_Conn; } }
|
||||
typedef analyzer::imap::IMAP_Analyzer* IMAPAnalyzer;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[IMAP4rev1, CHILDREN, ENABLE, ID, IDLE, LIST-EXTENDED, LIST-STATUS, LITERAL+, MOVE, NAMESPACE, SASL-IR, SORT, SPECIAL-USE, THREAD=ORDEREDSUBJECT, UIDPLUS, UNSELECT, WITHIN, STARTTLS, AUTH=LOGIN, AUTH=PLAIN]
|
12
testing/btest/scripts/base/protocols/imap/capabilities.test
Normal file
12
testing/btest/scripts/base/protocols/imap/capabilities.test
Normal file
|
@ -0,0 +1,12 @@
|
|||
# @TEST-EXEC: bro -b -C -r $TRACES/tls/imap-starttls.pcap %INPUT
|
||||
# @TEST-EXEC: btest-diff .stdout
|
||||
|
||||
@load base/protocols/ssl
|
||||
@load base/protocols/conn
|
||||
@load base/frameworks/dpd
|
||||
@load base/protocols/imap
|
||||
|
||||
event imap_capabilities(c: connection, capabilities: string_vec)
|
||||
{
|
||||
print capabilities;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue