zeek/src/FileAnalyzer.cc
Jon Siwek 0141f51801 FileAnalysis: load custom mime magic database just once.
This works around a bug in libmagic since version 5.12 (current at
time of writing is 5.14) -- second call to magic_load() w/ non-default
database segfaults.
2013-04-29 12:49:22 -05:00

101 lines
2.3 KiB
C++

#include <algorithm>
#include "file_analysis/Manager.h"
#include "FileAnalyzer.h"
#include "Reporter.h"
#include "util.h"
File_Analyzer::File_Analyzer(AnalyzerTag::Tag tag, Connection* conn)
: TCP_ApplicationAnalyzer(tag, conn)
{
buffer_len = 0;
}
void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
{
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
int n = min(len, BUFFER_SIZE - buffer_len);
if ( n )
{
strncpy(buffer + buffer_len, (const char*) data, n);
buffer_len += n;
if ( buffer_len == BUFFER_SIZE )
Identify();
}
return;
}
void File_Analyzer::Undelivered(int seq, int len, bool orig)
{
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
}
void File_Analyzer::Done()
{
TCP_ApplicationAnalyzer::Done();
if ( buffer_len && buffer_len != BUFFER_SIZE )
Identify();
}
void File_Analyzer::Identify()
{
const char* desc = bro_magic_buffer(magic_desc_cookie, buffer, buffer_len);
const char* mime = bro_magic_buffer(magic_mime_cookie, buffer, buffer_len);
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(new StringVal(buffer_len, buffer));
vl->append(new StringVal(desc ? desc : "<unknown>"));
vl->append(new StringVal(mime ? mime : "<unknown>"));
ConnectionEvent(file_transferred, vl);
}
IRC_Data::IRC_Data(Connection* conn)
: File_Analyzer(AnalyzerTag::IRC_Data, conn)
{
}
void IRC_Data::Done()
{
File_Analyzer::Done();
file_mgr->EndOfFile(GetTag(), Conn());
}
void IRC_Data::DeliverStream(int len, const u_char* data, bool orig)
{
File_Analyzer::DeliverStream(len, data, orig);
file_mgr->DataIn(data, len, GetTag(), Conn(), orig);
}
void IRC_Data::Undelivered(int seq, int len, bool orig)
{
File_Analyzer::Undelivered(seq, len, orig);
file_mgr->Gap(seq, len, GetTag(), Conn(), orig);
}
FTP_Data::FTP_Data(Connection* conn)
: File_Analyzer(AnalyzerTag::FTP_Data, conn)
{
}
void FTP_Data::Done()
{
File_Analyzer::Done();
file_mgr->EndOfFile(GetTag(), Conn());
}
void FTP_Data::DeliverStream(int len, const u_char* data, bool orig)
{
File_Analyzer::DeliverStream(len, data, orig);
file_mgr->DataIn(data, len, GetTag(), Conn(), orig);
}
void FTP_Data::Undelivered(int seq, int len, bool orig)
{
File_Analyzer::Undelivered(seq, len, orig);
file_mgr->Gap(seq, len, GetTag(), Conn(), orig);
}