From 37c74f65b3da63f13cf7730ce5a9f03831215a2f Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 28 Mar 2009 17:09:55 +0000 Subject: [PATCH] Add checks on the plugin version and the plugin license. Currently only implemented for FD plugins. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8626 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/dir_plugins.c | 2 +- bacula/src/dird/inc_conf.c | 2 +- bacula/src/filed/fd_plugins.c | 56 ++++++++++++++++++++++++++++++-- bacula/src/lib/plugins.c | 20 +++++++++++- bacula/src/lib/plugins.h | 3 +- bacula/src/plugins/fd/bpipe-fd.c | 4 +-- bacula/src/stored/sd_plugins.c | 2 +- bacula/technotes-2.5 | 2 ++ 8 files changed, 81 insertions(+), 10 deletions(-) diff --git a/bacula/src/dird/dir_plugins.c b/bacula/src/dird/dir_plugins.c index a794e5d803..f6e904fbe3 100644 --- a/bacula/src/dird/dir_plugins.c +++ b/bacula/src/dird/dir_plugins.c @@ -116,7 +116,7 @@ void load_dir_plugins(const char *plugin_dir) } plugin_list = New(alist(10, not_owned_by_alist)); - load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type); + load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL); dbg_plugin_add_hook(dump_dir_plugin); } diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 5df66b1ac0..ef15d3f2dd 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + Copyright (C) 2000-2009 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 27c4c2038a..67943bbf72 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -62,6 +62,7 @@ static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, static void *baculaMalloc(bpContext *ctx, const char *file, int line, size_t size); static void baculaFree(bpContext *ctx, const char *file, int line, void *mem); +static bool is_plugin_compatible(Plugin *plugin); /* * These will be plugged into the global pointer structure for @@ -435,6 +436,7 @@ bail_out: /* * Tell the plugin to create the file. Return values are + * This is called only during Restore * * CF_ERROR -- error * CF_SKIP -- skip processing this file @@ -509,6 +511,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) * Reset the file attributes after all file I/O is done -- this allows * the previous access time/dates to be set properly, and it also allows * us to properly set directory permissions. + * Not currently Implemented. */ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { @@ -520,12 +523,15 @@ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) return true; } +/* + * Print to file the plugin info. + */ void dump_fd_plugin(Plugin *plugin, FILE *fp) { if (!plugin) { return ; } - pInfo *info = (pInfo *) plugin->pinfo; + pInfo *info = (pInfo *)plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); @@ -549,7 +555,8 @@ void load_fd_plugins(const char *plugin_dir) } plugin_list = New(alist(10, not_owned_by_alist)); - if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type)) { + if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, + is_plugin_compatible)) { /* Either none found, or some error */ if (plugin_list->size() == 0) { delete plugin_list; @@ -565,15 +572,58 @@ void load_fd_plugins(const char *plugin_dir) plugin_bread = my_plugin_bread; plugin_bwrite = my_plugin_bwrite; plugin_blseek = my_plugin_blseek; + + /* + * Verify that the plugin is acceptable, and print information + * about it. + */ foreach_alist(plugin, plugin_list) { Jmsg(NULL, M_INFO, 0, _("Loaded plugin: %s\n"), plugin->file); Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); - } dbg_plugin_add_hook(dump_fd_plugin); } +/* + * Check if a plugin is compatible. Called by the load_plugin function + * to allow us to verify the plugin. + */ +static bool is_plugin_compatible(Plugin *plugin) +{ + pInfo *info = (pInfo *)plugin->pinfo; + Dmsg0(50, "is_plugin_compatible called\n"); + if (debug_level >= 50) { + dump_fd_plugin(plugin, stdin); + } + if (strcmp(info->plugin_magic, FD_PLUGIN_MAGIC) != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), + plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); + Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", + plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); + + return false; + } + if (info->version != FD_PLUGIN_INTERFACE_VERSION) { + Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); + Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", + plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); + return false; + } + if (strcmp(info->plugin_license, "Bacula GPLv2") != 0 && + strcmp(info->plugin_license, "GPLv2") != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), + plugin->file, info->plugin_license); + Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", + plugin->file, info->plugin_license); + return false; + } + + return true; +} + + /* * Create a new instance of each plugin for this Job * Note, plugin_list can exist but jcr->plugin_ctx_list can diff --git a/bacula/src/lib/plugins.c b/bacula/src/lib/plugins.c index 0f799a5902..739a504899 100644 --- a/bacula/src/lib/plugins.c +++ b/bacula/src/lib/plugins.c @@ -70,7 +70,8 @@ Plugin *new_plugin() /* * Load all the plugins in the specified directory. */ -bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, const char *type) +bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, + const char *type, bool is_plugin_compatible(Plugin *plugin)) { bool found = false; t_loadPlugin loadPlugin; @@ -167,6 +168,11 @@ bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, const char if (loadPlugin(binfo, bfuncs, &plugin->pinfo, &plugin->pfuncs) != bRC_OK) { goto get_out; } + if (!is_plugin_compatible) { + Dmsg0(50, "Plugin compatibility pointer not set.\n"); + } else if (!is_plugin_compatible(plugin)) { + goto get_out; + } found = true; /* found a plugin */ plugin_list->append(plugin); @@ -174,6 +180,18 @@ bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, const char get_out: if (!found && plugin) { + if (plugin->file) { + Dmsg1(50, "Got plugin=%s but not accepted.\n", plugin->file); + } + if (plugin->unloadPlugin) { + plugin->unloadPlugin(); + } + if (plugin->pHandle) { + dlclose(plugin->pHandle); + } + if (plugin->file) { + free(plugin->file); + } free(plugin); } if (entry) { diff --git a/bacula/src/lib/plugins.h b/bacula/src/lib/plugins.h index e7e5b41671..7e84e16cfc 100644 --- a/bacula/src/lib/plugins.h +++ b/bacula/src/lib/plugins.h @@ -80,7 +80,8 @@ public: /* Functions */ extern Plugin *new_plugin(); -extern bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, const char *type); +extern bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, + const char *type, bool is_plugin_compatible(Plugin *plugin)); extern void unload_plugins(); /* Each daemon can register a debug hook that will be called diff --git a/bacula/src/plugins/fd/bpipe-fd.c b/bacula/src/plugins/fd/bpipe-fd.c index abc374a959..52521cd154 100644 --- a/bacula/src/plugins/fd/bpipe-fd.c +++ b/bacula/src/plugins/fd/bpipe-fd.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + Copyright (C) 2007-2009 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -47,7 +47,7 @@ extern "C" { static const int dbglvl = 150; -#define PLUGIN_LICENSE "GPLv2" +#define PLUGIN_LICENSE "Bacula GPLv2" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "January 2008" #define PLUGIN_VERSION "1" diff --git a/bacula/src/stored/sd_plugins.c b/bacula/src/stored/sd_plugins.c index b007032a80..32bbcc51ba 100644 --- a/bacula/src/stored/sd_plugins.c +++ b/bacula/src/stored/sd_plugins.c @@ -117,7 +117,7 @@ void load_sd_plugins(const char *plugin_dir) } plugin_list = New(alist(10, not_owned_by_alist)); - load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type); + load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL); dbg_plugin_add_hook(dump_sd_plugin); } diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index f244b89e04..26399e62bd 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -3,6 +3,8 @@ General: 28Mar09 +kes Add checks on the plugin version and the plugin license. Currently + only implemented for FD plugins. kes Add installation of /usr/share/doc/bacula-VERSION kes Modify plugin checkFile to return bRC_Seen to cause file to remain. Previously was true/false. -- 2.39.5