mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Fix and extend behavior of HookLoadFile
This commit fixes and extends the behavior of HookLoadFile. Before this change, HookLoadFile appended ".bro" to each path that was @loaded, even if the path specified directory names. Furthermore it only gave the path of the file as it was specified in the Bro script without revealing the final path of the file that it was going to load. This patch changes this behavior - in addition to giving the unmodified path given in the @load command, the hook now returns the resolved path of the file or directory it is going to load (if found). The hook is furthermore raises for @load-sigs and @load-plugin; a enum specifies the kind of load that is happening.
This commit is contained in:
parent
bde4404b5e
commit
91dcefe104
8 changed files with 978 additions and 643 deletions
|
@ -569,32 +569,20 @@ void Manager::RequestBroObjDtor(BroObj* obj, Plugin* plugin)
|
|||
obj->NotifyPluginsOnDtor();
|
||||
}
|
||||
|
||||
int Manager::HookLoadFile(const string& file)
|
||||
int Manager::HookLoadFile(const Plugin::LoadType type, const string& file, const string& resolved)
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(HookArgument(type));
|
||||
args.push_back(HookArgument(file));
|
||||
args.push_back(HookArgument(resolved));
|
||||
MetaHookPre(HOOK_LOAD_FILE, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_LOAD_FILE];
|
||||
|
||||
size_t i = file.find_last_of("./");
|
||||
|
||||
string ext;
|
||||
string normalized_file = file;
|
||||
|
||||
if ( i != string::npos && file[i] == '.' )
|
||||
ext = file.substr(i + 1);
|
||||
else
|
||||
{
|
||||
// Add .bro as default extension.
|
||||
normalized_file = file + ".bro";
|
||||
ext = "bro";
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
|
||||
if ( l )
|
||||
|
@ -602,7 +590,7 @@ int Manager::HookLoadFile(const string& file)
|
|||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
rc = p->HookLoadFile(normalized_file, ext);
|
||||
rc = p->HookLoadFile(type, file, resolved);
|
||||
|
||||
if ( rc >= 0 )
|
||||
break;
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
* if a plugin took over the file but had trouble loading it; and -1 if
|
||||
* no plugin was interested in the file at all.
|
||||
*/
|
||||
virtual int HookLoadFile(const string& file);
|
||||
virtual int HookLoadFile(const Plugin::LoadType type, const string& file, const string& resolved);
|
||||
|
||||
/**
|
||||
* Hook that filters calls to a script function/event/hook.
|
||||
|
|
|
@ -345,7 +345,7 @@ void Plugin::RequestBroObjDtor(BroObj* obj)
|
|||
plugin_mgr->RequestBroObjDtor(obj, this);
|
||||
}
|
||||
|
||||
int Plugin::HookLoadFile(const std::string& file, const std::string& ext)
|
||||
int Plugin::HookLoadFile(const LoadType type, const std::string& file, const std::string& resolved)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -403,6 +403,13 @@ public:
|
|||
typedef std::list<BifItem> bif_item_list;
|
||||
typedef std::list<std::pair<HookType, int> > hook_list;
|
||||
|
||||
/**
|
||||
* The different types of @loads supported by HookLoadFile.
|
||||
*/
|
||||
enum LoadType {
|
||||
SCRIPT, SIGNATURES, PLUGIN
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
@ -611,10 +618,15 @@ protected:
|
|||
* script directives. The hook can take over the file, in which case
|
||||
* Bro will not further process it otherwise.
|
||||
*
|
||||
* @param file The filename to be loaded, including extension.
|
||||
* @param type The type of load encountered: script load, signatures load,
|
||||
* or plugin load.
|
||||
*
|
||||
* @param ext The extension of the filename. This is provided
|
||||
* separately just for convenience. The dot is excluded.
|
||||
* @param file The filename that was passed to @load. Only includes
|
||||
* an extension if it was given in @load.
|
||||
*
|
||||
* @param resolved The file or directory name Bro resolved from
|
||||
* the given path and is going to load. Empty string
|
||||
* if Bro was not able to resolve a path.
|
||||
*
|
||||
* @return 1 if the plugin took over the file and loaded it
|
||||
* successfully; 0 if the plugin took over the file but had trouble
|
||||
|
@ -622,7 +634,7 @@ protected:
|
|||
* have printed an error message); and -1 if the plugin wasn't
|
||||
* interested in the file at all.
|
||||
*/
|
||||
virtual int HookLoadFile(const std::string& file, const std::string& ext);
|
||||
virtual int HookLoadFile(const LoadType type, const std::string& file, const std::string& resolved);
|
||||
|
||||
/**
|
||||
* Hook into executing a script-level function/event/hook. Whenever
|
||||
|
|
32
src/scan.l
32
src/scan.l
|
@ -348,6 +348,19 @@ when return TOK_WHEN;
|
|||
@load-sigs{WS}{FILE} {
|
||||
const char* file = skip_whitespace(yytext + 10);
|
||||
string path = find_relative_file(file, "sig");
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SIGNATURES, file, path), -1);
|
||||
if ( rc == 1 )
|
||||
return 0; // A plugin took care of it, just skip.
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
if ( ! reporter->Errors() )
|
||||
reporter->Error("Plugin reported error loading signatures %s", file);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
assert(rc == -1); // No plugin in charge of this file.
|
||||
|
||||
if ( path.empty() )
|
||||
reporter->Error("failed to find file associated with @load-sigs %s",
|
||||
|
@ -358,6 +371,19 @@ when return TOK_WHEN;
|
|||
|
||||
@load-plugin{WS}{ID} {
|
||||
const char* plugin = skip_whitespace(yytext + 12);
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::PLUGIN, plugin, ""), -1);
|
||||
if ( rc == 1 )
|
||||
return 0; // A plugin took care of it, just skip.
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
if ( ! reporter->Errors() )
|
||||
reporter->Error("Plugin reported error loading plugin %s", plugin);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
assert(rc == -1); // No plugin in charge of this file.
|
||||
plugin_mgr->ActivateDynamicPlugin(plugin);
|
||||
}
|
||||
|
||||
|
@ -547,7 +573,8 @@ static bool already_scanned(const string& path)
|
|||
|
||||
static int load_files(const char* orig_file)
|
||||
{
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(orig_file), -1);
|
||||
string file_path = find_relative_file(orig_file, "bro");
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SCRIPT, orig_file, file_path), -1);
|
||||
|
||||
if ( rc == 1 )
|
||||
return 0; // A plugin took care of it, just skip.
|
||||
|
@ -568,7 +595,6 @@ static int load_files(const char* orig_file)
|
|||
// Whether we pushed on a FileInfo that will restore the
|
||||
// current module after the final file has been scanned.
|
||||
bool did_module_restore = false;
|
||||
string file_path;
|
||||
FILE* f = 0;
|
||||
|
||||
if ( streq(orig_file, "-") )
|
||||
|
@ -585,8 +611,6 @@ static int load_files(const char* orig_file)
|
|||
|
||||
else
|
||||
{
|
||||
file_path = find_relative_file(orig_file, "bro");
|
||||
|
||||
if ( file_path.empty() )
|
||||
reporter->FatalError("can't find %s", orig_file);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,10 +46,10 @@ static void describe_hook_args(const plugin::HookArgumentList& args, ODesc* d)
|
|||
}
|
||||
}
|
||||
|
||||
int Plugin::HookLoadFile(const std::string& file, const std::string& ext)
|
||||
int Plugin::HookLoadFile(const LoadType type, const std::string& file, const std::string& resolved)
|
||||
{
|
||||
fprintf(stderr, "%.6f %-15s %s/%s\n", network_time, "| HookLoadFile",
|
||||
file.c_str(), ext.c_str());
|
||||
fprintf(stderr, "%.6f %-15s %s %s\n", network_time, "| HookLoadFile",
|
||||
file.c_str(), resolved.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Demo_Hooks {
|
|||
class Plugin : public ::plugin::Plugin
|
||||
{
|
||||
protected:
|
||||
int HookLoadFile(const std::string& file, const std::string& ext) override;
|
||||
int HookLoadFile(const LoadType type, const std::string& file, const std::string& resolved) override;
|
||||
std::pair<bool, Val*> HookCallFunction(const Func* func, Frame* frame, val_list* args) override;
|
||||
bool HookQueueEvent(Event* event) override;
|
||||
void HookDrainEvents() override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue