From 7cb6cf24a6aad19a95768098eeac263508c44a4b Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 9 Jan 2018 12:16:17 -0500 Subject: [PATCH] Functions for retrieving files by their id. There are two new script level functions to query and lookup files from the core by their IDs. These are adding feature parity for similarly named functions for files. The function prototypes are as follows: Files::file_exists(fuid: string): bool Files::lookup_File(fuid: string): fa_file --- scripts/base/frameworks/files/main.bro | 24 +++++++ src/file_analysis/Manager.h | 62 +++++++++---------- src/file_analysis/file_analysis.bif | 22 +++++++ .../.stdout | 9 +++ .../bifs/file_exists_lookup_file.bro | 21 +++++++ 5 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.file_exists_lookup_file/.stdout create mode 100644 testing/btest/scripts/base/frameworks/file-analysis/bifs/file_exists_lookup_file.bro diff --git a/scripts/base/frameworks/files/main.bro b/scripts/base/frameworks/files/main.bro index ed73028236..71147a77aa 100644 --- a/scripts/base/frameworks/files/main.bro +++ b/scripts/base/frameworks/files/main.bro @@ -135,6 +135,20 @@ export { ## The default per-file reassembly buffer size. const reassembly_buffer_size = 524288 &redef; + ## Lookup to see if a particular file id exists and is still valid. + ## + ## fuid: the file id. + ## + ## Returns: T if the file uid is known. + global file_exists: function(fuid: string): bool; + + ## Lookup an :bro:see:`fa_file` record with the file id. + ## + ## fuid: the file id. + ## + ## Returns: the associated :bro:see:`fa_file` record. + global lookup_file: function(fuid: string): fa_file; + ## Allows the file reassembler to be used if it's necessary because the ## file is transferred out of order. ## @@ -338,6 +352,16 @@ function set_info(f: fa_file) f$info$is_orig = f$is_orig; } +function file_exists(fuid: string): bool + { + return __file_exists(fuid); + } + +function lookup_file(fuid: string): fa_file + { + return __lookup_file(fuid); + } + function set_timeout_interval(f: fa_file, t: interval): bool { return __set_timeout_interval(f$id, t); diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index dec308236a..1a5fb55f89 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -256,6 +256,14 @@ public: bool SetExtractionLimit(const string& file_id, RecordVal* args, uint64 n) const; + /** + * Try to retrieve a file that's being analyzed, using its identifier/hash. + * @param file_id the file identifier/hash. + * @return the File object mapped to \a file_id, or a null pointer if no + * mapping exists. + */ + File* LookupFile(const string& file_id) const; + /** * Queue attachment of an analzer to the file identifier. Multiple * analyzers of a given type can be attached per file identifier at a time @@ -332,37 +340,6 @@ protected: typedef PDict(bool) IDSet; typedef PDict(File) IDMap; - /** - * Create a new file to be analyzed or retrieve an existing one. - * @param file_id the file identifier/hash. - * @param conn network connection, if any, over which the file is - * transferred. - * @param tag network protocol, if any, over which the file is transferred. - * @param is_orig true if the file is being sent from connection originator - * or false if is being sent in the opposite direction (or if it - * this file isn't related to a connection). - * @param update_conn whether we need to update connection-related field - * in the \c fa_file record value associated with the file. - * @param an optional value of the source field to fill in. - * @return the File object mapped to \a file_id or a null pointer if - * analysis is being ignored for the associated file. An File - * object may be created if a mapping doesn't exist, and if it did - * exist, the activity time is refreshed along with any - * connection-related fields. - */ - File* GetFile(const string& file_id, Connection* conn = 0, - analyzer::Tag tag = analyzer::Tag::Error, - bool is_orig = false, bool update_conn = true, - const char* source_name = 0); - - /** - * Try to retrieve a file that's being analyzed, using its identifier/hash. - * @param file_id the file identifier/hash. - * @return the File object mapped to \a file_id, or a null pointer if no - * mapping exists. - */ - File* LookupFile(const string& file_id) const; - /** * Evaluate timeout policy for a file and remove the File object mapped to * \a file_id if needed. @@ -392,6 +369,29 @@ protected: */ std::string GetFileID(analyzer::Tag tag, Connection* c, bool is_orig); + /** + * Create a new file to be analyzed or retrieve an existing one. + * @param file_id the file identifier/hash. + * @param conn network connection, if any, over which the file is + * transferred. + * @param tag network protocol, if any, over which the file is transferred. + * @param is_orig true if the file is being sent from connection originator + * or false if is being sent in the opposite direction (or if it + * this file isn't related to a connection). + * @param update_conn whether we need to update connection-related field + * in the \c fa_file record value associated with the file. + * @param an optional value of the source field to fill in. + * @return the File object mapped to \a file_id or a null pointer if + * analysis is being ignored for the associated file. An File + * object may be created if a mapping doesn't exist, and if it did + * exist, the activity time is refreshed along with any + * connection-related fields. + */ + File* GetFile(const string& file_id, Connection* conn = 0, + analyzer::Tag tag = analyzer::Tag::Error, + bool is_orig = false, bool update_conn = true, + const char* source_name = 0); + /** * Check if analysis is available for files transferred over a given * network protocol. diff --git a/src/file_analysis/file_analysis.bif b/src/file_analysis/file_analysis.bif index 480d8c84d8..f445a9cf6a 100644 --- a/src/file_analysis/file_analysis.bif +++ b/src/file_analysis/file_analysis.bif @@ -71,6 +71,28 @@ function Files::__analyzer_name%(tag: Files::Tag%) : string return new StringVal(file_mgr->GetComponentName(tag)); %} +## :bro:see:`Files::file_exists`. +function Files::__file_exists%(fuid: string%): bool + %{ + if ( file_mgr->LookupFile(fuid->CheckString()) != nullptr ) + return new Val(true, TYPE_BOOL); + else + return new Val(false, TYPE_BOOL); + %} + +## :bro:see:`Files::lookup_file`. +function Files::__lookup_file%(fuid: string%): fa_file + %{ + auto f = file_mgr->LookupFile(fuid->CheckString()); + if ( f != nullptr ) + { + return f->GetVal()->Ref(); + } + + reporter->Error("file ID %s not a known file", fuid->CheckString()); + return 0; + %} + module GLOBAL; ## For use within a :bro:see:`get_file_handle` handler to set a unique diff --git a/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.file_exists_lookup_file/.stdout b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.file_exists_lookup_file/.stdout new file mode 100644 index 0000000000..d5dd2cab55 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.file-analysis.bifs.file_exists_lookup_file/.stdout @@ -0,0 +1,9 @@ +error: file ID asdf not a known file +warning: non-void function returns without a value: Files::lookup_file +This should fail but not crash +This should return F +F +lookup fid: FakNcS1Jfe01uljb3 +We should have found the file id: FakNcS1Jfe01uljb3 +This should return T +T diff --git a/testing/btest/scripts/base/frameworks/file-analysis/bifs/file_exists_lookup_file.bro b/testing/btest/scripts/base/frameworks/file-analysis/bifs/file_exists_lookup_file.bro new file mode 100644 index 0000000000..cba82bbfab --- /dev/null +++ b/testing/btest/scripts/base/frameworks/file-analysis/bifs/file_exists_lookup_file.bro @@ -0,0 +1,21 @@ +# @TEST-EXEC: bro -r $TRACES/http/get.trace %INPUT 2>&1 +# @TEST-EXEC: btest-diff .stdout + +event bro_init() + { + print "This should fail but not crash"; + print Files::lookup_file("asdf"); + + print "This should return F"; + print Files::file_exists("asdf"); + } + +event file_sniff(f: fa_file, meta: fa_metadata) + { + print "lookup fid: " + f$id; + local looked_up_file = Files::lookup_file(f$id); + print "We should have found the file id: " + looked_up_file$id ; + + print "This should return T"; + print Files::file_exists(f$id); + }