diff --git a/scripts/base/frameworks/file-analysis/main.bro b/scripts/base/frameworks/file-analysis/main.bro index 2e5feee22b..00ff5b4120 100644 --- a/scripts/base/frameworks/file-analysis/main.bro +++ b/scripts/base/frameworks/file-analysis/main.bro @@ -5,11 +5,6 @@ # TODO: do logging here? @load base/frameworks/logging -# dependendies for file handle determination -@load base/protocols/http/main -@load base/protocols/http/utils -@load base/protocols/ftp/main - module FileAnalysis; export { @@ -110,38 +105,32 @@ export { ## TODO: document global policy: hook(trig: Trigger, info: Info); + type HandleCallback: function(c: connection, is_orig: bool): string; + + const handle_callbacks: table[AnalyzerTag] of HandleCallback = {} &redef; + + const service_handle_callbacks: table[string] of HandleCallback = {} &redef; + global get_handle: function(c: connection, is_orig: bool): string &redef; # TODO: wrapper functions for BiFs ? } -function conn_str(c: connection): string +function get_file_handle_by_service(c: connection, is_orig: bool): string { - return fmt("%s:%s -> %s:%s", c$id$orig_h, c$id$orig_p, - c$id$resp_h, c$id$resp_p); - } + local handle: string = ""; -function get_handle(c: connection, is_orig: bool): string - { - local rval: string = ""; - local cid: conn_id = c$id; - - if ( "ftp-data" in c$service ) - rval = fmt("%s ftp-data: %s", c$start_time, conn_str(c)); - - if ( "irc-dcc-data" in c$service ) - rval = fmt("%s irc-dcc-data: %s", c$start_time, conn_str(c)); - - else if ( c?$http ) + for ( serv in c$service ) { - if ( c$http$range_request ) - rval = fmt("%s http(%s): %s: %s", c$start_time, is_orig, - c$id$orig_h, HTTP::build_url(c$http)); - else - rval = fmt("%s http(%s, %s): %s", c$start_time, is_orig, - c$http$trans_depth, conn_str(c)); + if ( serv in service_handle_callbacks ) + { + handle = service_handle_callbacks[serv](c, is_orig); + if ( handle != "" ) return handle; + } } - - #print fmt("file handle: %s", rval); - return rval; + return handle; } + +redef FileAnalysis::handle_callbacks += { + [ANALYZER_FILE] = get_file_handle_by_service, +}; diff --git a/scripts/base/protocols/ftp/__load__.bro b/scripts/base/protocols/ftp/__load__.bro index 15c61be614..464571dc7d 100644 --- a/scripts/base/protocols/ftp/__load__.bro +++ b/scripts/base/protocols/ftp/__load__.bro @@ -1,4 +1,5 @@ @load ./utils-commands @load ./main +@load ./file-analysis @load ./file-extract @load ./gridftp diff --git a/scripts/base/protocols/ftp/file-analysis.bro b/scripts/base/protocols/ftp/file-analysis.bro new file mode 100644 index 0000000000..c124c1bf25 --- /dev/null +++ b/scripts/base/protocols/ftp/file-analysis.bro @@ -0,0 +1,10 @@ +@load ./main +@load base/utils/conn-ids +@load base/frameworks/file-analysis/main + +redef FileAnalysis::service_handle_callbacks += { + ["ftp-data"] = function(c: connection, is_orig: bool): string + { + return fmt("%s ftp-data: %s", c$start_time, id_string(c$id)); + }, +}; diff --git a/scripts/base/protocols/http/__load__.bro b/scripts/base/protocols/http/__load__.bro index 314f04b872..58618dedc7 100644 --- a/scripts/base/protocols/http/__load__.bro +++ b/scripts/base/protocols/http/__load__.bro @@ -1,5 +1,6 @@ @load ./main @load ./utils +@load ./file-analysis @load ./file-ident @load ./file-hash @load ./file-extract diff --git a/scripts/base/protocols/http/file-analysis.bro b/scripts/base/protocols/http/file-analysis.bro new file mode 100644 index 0000000000..901d82b74c --- /dev/null +++ b/scripts/base/protocols/http/file-analysis.bro @@ -0,0 +1,21 @@ +@load ./main +@load ./utils +@load base/utils/conn-ids +@load base/frameworks/file-analysis/main + +module HTTP; + +function get_file_handle(c: connection, is_orig: bool): string + { + if ( ! c?$http ) return ""; + + if ( c$http$range_request ) + return fmt("%s http(%s): %s: %s", c$start_time, is_orig, + c$id$orig_h, build_url(c$http)); + return fmt("%s http(%s, %s): %s", c$start_time, is_orig, + c$http$trans_depth, id_string(c$id)); + } + +redef FileAnalysis::handle_callbacks += { + [ANALYZER_HTTP] = get_file_handle, +}; diff --git a/scripts/base/protocols/irc/__load__.bro b/scripts/base/protocols/irc/__load__.bro index 240e1487c3..5123385b0c 100644 --- a/scripts/base/protocols/irc/__load__.bro +++ b/scripts/base/protocols/irc/__load__.bro @@ -1,2 +1,3 @@ @load ./main -@load ./dcc-send \ No newline at end of file +@load ./dcc-send +@load ./file-analysis diff --git a/scripts/base/protocols/irc/file-analysis.bro b/scripts/base/protocols/irc/file-analysis.bro new file mode 100644 index 0000000000..dbb06da3ba --- /dev/null +++ b/scripts/base/protocols/irc/file-analysis.bro @@ -0,0 +1,10 @@ +@load ./dcc-send.bro +@load base/utils/conn-ids +@load base/frameworks/file-analysis/main + +redef FileAnalysis::service_handle_callbacks += { + ["irc-dcc-data"] = function(c: connection, is_orig: bool): string + { + return fmt("%s irc-dcc-data: %s", c$start_time, id_string(c$id)); + }, +}; diff --git a/src/FileAnalyzer.h b/src/FileAnalyzer.h index 1b42593bca..c7ba3fb5a9 100644 --- a/src/FileAnalyzer.h +++ b/src/FileAnalyzer.h @@ -34,8 +34,6 @@ protected: static magic_t magic; static magic_t magic_mime; - - string unique_file; }; #endif diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 81fa9824c2..1c2fcc4889 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -4,6 +4,7 @@ #include "Manager.h" #include "Info.h" #include "Action.h" +#include "Var.h" using namespace file_analysis; @@ -16,22 +17,48 @@ Manager::~Manager() Terminate(); } -string Manager::GetFileHandle(Connection* conn, bool is_orig) +string Manager::GetFileHandle(Analyzer* root, Connection* conn, + bool is_orig) const + { + static TableVal* table = 0; + + if ( ! table ) + table = internal_val("FileAnalysis::handle_callbacks")->AsTableVal(); + + if ( ! root ) return ""; + + Val* index = new Val(root->GetTag(), TYPE_COUNT); + const Val* callback = table->Lookup(index); + Unref(index); + + if ( callback ) + { + val_list vl(2); + vl.append(conn->BuildConnVal()); + vl.append(new Val(is_orig, TYPE_BOOL)); + + Val* result = callback->AsFunc()->Call(&vl); + string rval = result->AsString()->CheckString(); + Unref(result); + + if ( ! rval.empty() ) return rval; + } + + for ( analyzer_list::const_iterator it = root->GetChildren().begin(); + it != root->GetChildren().end(); ++it ) + { + string rval = GetFileHandle((*it), conn, is_orig); + if ( ! rval.empty() ) return rval; + } + + return ""; + } + +string Manager::GetFileHandle(Connection* conn, bool is_orig) const { if ( ! conn ) return ""; - const ID* id = global_scope()->Lookup("FileAnalysis::get_handle"); - assert(id); - const Func* func = id->ID_Val()->AsFunc(); - - val_list vl(2); - vl.append(conn->BuildConnVal()); - vl.append(new Val(is_orig, TYPE_BOOL)); - - Val* result = func->Call(&vl); - string rval = result->AsString()->CheckString(); - Unref(result); - return rval; + return GetFileHandle(conn->GetRootAnalyzer(), conn, is_orig); } void Manager::DrainPending() diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index 0a660add26..db9be04a06 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -9,6 +9,7 @@ #include "Net.h" #include "Conn.h" #include "Val.h" +#include "Analyzer.h" #include "Info.h" #include "InfoTimer.h" @@ -141,7 +142,9 @@ protected: * time the function was evaluated (possibly because some events * have not yet been drained from the queue). */ - string GetFileHandle(Connection* conn, bool is_orig); + string GetFileHandle(Connection* conn, bool is_orig) const; + string GetFileHandle(Analyzer* root, Connection* conn, + bool is_orig) const; /** * @return the Info object mapped to \a file_id, or a null pointer if no