mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
SMTP: Add enable_rfc822_msg_file_analysis
Enabling this option will instantiate a new fa_file instance for every top-level RFC 822 message in an SMTP transaction.
This commit is contained in:
parent
fba319857b
commit
6f05fbf2ce
4 changed files with 38 additions and 2 deletions
|
@ -667,6 +667,14 @@ export {
|
||||||
## is introduced and a weird is raised. Conventionally, MIME messages
|
## is introduced and a weird is raised. Conventionally, MIME messages
|
||||||
## have a maximum line length of 1000 octets when properly encoded.
|
## have a maximum line length of 1000 octets when properly encoded.
|
||||||
const bdat_max_line_length = 4096 &redef;
|
const bdat_max_line_length = 4096 &redef;
|
||||||
|
|
||||||
|
## Whether to send data of individual top-level RFC822 messages
|
||||||
|
## in SMTP transactions to the file analysis framework.
|
||||||
|
##
|
||||||
|
## If this option is enabled, the first :zeek:see:`file_over_new_connection`
|
||||||
|
## event for a new SMTP transaction will be for the top-level RFC822
|
||||||
|
## message. The file's :zeek:field:`mime_type` will be ``message/rfc822``.
|
||||||
|
const enable_rfc822_msg_file_analysis = F &redef;
|
||||||
}
|
}
|
||||||
|
|
||||||
module TCP;
|
module TCP;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "zeek/analyzer/protocol/smtp/BDAT.h"
|
#include "zeek/analyzer/protocol/smtp/BDAT.h"
|
||||||
#include "zeek/analyzer/protocol/smtp/consts.bif.h"
|
#include "zeek/analyzer/protocol/smtp/consts.bif.h"
|
||||||
#include "zeek/analyzer/protocol/smtp/events.bif.h"
|
#include "zeek/analyzer/protocol/smtp/events.bif.h"
|
||||||
|
#include "zeek/file_analysis/File.h"
|
||||||
|
#include "zeek/file_analysis/Manager.h"
|
||||||
|
|
||||||
#undef SMTP_CMD_DEF
|
#undef SMTP_CMD_DEF
|
||||||
#define SMTP_CMD_DEF(cmd) #cmd,
|
#define SMTP_CMD_DEF(cmd) #cmd,
|
||||||
|
@ -126,9 +128,13 @@ void SMTP_Analyzer::DeliverStream(int length, const u_char* line, bool orig) {
|
||||||
if ( bdat->RemainingChunkSize() < static_cast<uint64_t>(bdat_len) )
|
if ( bdat->RemainingChunkSize() < static_cast<uint64_t>(bdat_len) )
|
||||||
bdat_len = static_cast<int>(bdat->RemainingChunkSize());
|
bdat_len = static_cast<int>(bdat->RemainingChunkSize());
|
||||||
|
|
||||||
if ( bdat_len > 0 )
|
if ( bdat_len > 0 ) {
|
||||||
bdat->NextStream(bdat_len, line, orig);
|
bdat->NextStream(bdat_len, line, orig);
|
||||||
|
|
||||||
|
if ( ! rfc822_msg_fuid.empty() )
|
||||||
|
Rfc822MsgDataIn(bdat_len, line);
|
||||||
|
}
|
||||||
|
|
||||||
// All BDAT chunks seen?
|
// All BDAT chunks seen?
|
||||||
if ( bdat->IsLastChunk() && bdat->RemainingChunkSize() == 0 )
|
if ( bdat->IsLastChunk() && bdat->RemainingChunkSize() == 0 )
|
||||||
UpdateState(detail::SMTP_CMD_END_OF_DATA, 0, orig);
|
UpdateState(detail::SMTP_CMD_END_OF_DATA, 0, orig);
|
||||||
|
@ -844,7 +850,14 @@ void SMTP_Analyzer::UnexpectedReply(int cmd_code, int reply_code) {
|
||||||
Unexpected(true, "unexpected reply", len, buf);
|
Unexpected(true, "unexpected reply", len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTP_Analyzer::ProcessData(int length, const char* line) { mail->Deliver(length, line, true /* trailing_CRLF */); }
|
void SMTP_Analyzer::ProcessData(int length, const char* line) {
|
||||||
|
mail->Deliver(length, line, true /* trailing_CRLF */);
|
||||||
|
|
||||||
|
if ( ! rfc822_msg_fuid.empty() ) {
|
||||||
|
Rfc822MsgDataIn(length, reinterpret_cast<const u_char*>(line));
|
||||||
|
Rfc822MsgDataIn(2, reinterpret_cast<const u_char*>("\r\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SMTP_Analyzer::ProcessBdatArg(int arg_len, const char* arg, bool orig) {
|
bool SMTP_Analyzer::ProcessBdatArg(int arg_len, const char* arg, bool orig) {
|
||||||
// For the BDAT command, parse out the chunk-size from the line
|
// For the BDAT command, parse out the chunk-size from the line
|
||||||
|
@ -880,6 +893,10 @@ bool SMTP_Analyzer::ProcessBdatArg(int arg_len, const char* arg, bool orig) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SMTP_Analyzer::Rfc822MsgDataIn(int len, const u_char* data) {
|
||||||
|
return file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), true, rfc822_msg_fuid, "message/rfc822");
|
||||||
|
}
|
||||||
|
|
||||||
void SMTP_Analyzer::BeginData(bool orig, detail::SMTP_State new_state) {
|
void SMTP_Analyzer::BeginData(bool orig, detail::SMTP_State new_state) {
|
||||||
state = new_state;
|
state = new_state;
|
||||||
skip_data = false; // reset the flag at the beginning of the mail
|
skip_data = false; // reset the flag at the beginning of the mail
|
||||||
|
@ -890,6 +907,9 @@ void SMTP_Analyzer::BeginData(bool orig, detail::SMTP_State new_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mail = new analyzer::mime::MIME_Mail(this, orig);
|
mail = new analyzer::mime::MIME_Mail(this, orig);
|
||||||
|
|
||||||
|
if ( zeek::BifConst::SMTP::enable_rfc822_msg_file_analysis )
|
||||||
|
rfc822_msg_fuid = Rfc822MsgDataIn(0, reinterpret_cast<const u_char*>(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTP_Analyzer::EndData() {
|
void SMTP_Analyzer::EndData() {
|
||||||
|
@ -911,6 +931,11 @@ void SMTP_Analyzer::EndData() {
|
||||||
delete mail;
|
delete mail;
|
||||||
mail = nullptr;
|
mail = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! rfc822_msg_fuid.empty() ) {
|
||||||
|
file_mgr->EndOfFile(rfc822_msg_fuid);
|
||||||
|
rfc822_msg_fuid.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace zeek::analyzer::smtp
|
} // namespace zeek::analyzer::smtp
|
||||||
|
|
|
@ -61,6 +61,7 @@ protected:
|
||||||
void ProcessExtension(int ext_len, const char* ext);
|
void ProcessExtension(int ext_len, const char* ext);
|
||||||
void ProcessData(int length, const char* line);
|
void ProcessData(int length, const char* line);
|
||||||
bool ProcessBdatArg(int arg_len, const char* arg, bool orig);
|
bool ProcessBdatArg(int arg_len, const char* arg, bool orig);
|
||||||
|
std::string Rfc822MsgDataIn(int len, const u_char* data);
|
||||||
|
|
||||||
void UpdateState(int cmd_code, int reply_code, bool orig);
|
void UpdateState(int cmd_code, int reply_code, bool orig);
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ protected:
|
||||||
std::unique_ptr<detail::SMTP_BDAT_Analyzer> bdat; // if set, BDAT chunk transfer active
|
std::unique_ptr<detail::SMTP_BDAT_Analyzer> bdat; // if set, BDAT chunk transfer active
|
||||||
|
|
||||||
analyzer::mime::MIME_Mail* mail;
|
analyzer::mime::MIME_Mail* mail;
|
||||||
|
std::string rfc822_msg_fuid; // fuid for mail data file analysis
|
||||||
|
|
||||||
private:
|
private:
|
||||||
analyzer::tcp::ContentLine_Analyzer* cl_orig;
|
analyzer::tcp::ContentLine_Analyzer* cl_orig;
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
const SMTP::bdat_max_line_length: count;
|
const SMTP::bdat_max_line_length: count;
|
||||||
|
const SMTP::enable_rfc822_msg_file_analysis: bool;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue