diff options
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index e1427bf15..4429d9436 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -50,6 +50,7 @@ struct private_plugin_loader_t { linked_list_t *names; }; +<<<<<<< HEAD #ifdef MONOLITHIC /** * load a single plugin in monolithic mode @@ -59,11 +60,23 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, { char create[128]; plugin_t *plugin; +======= +/** + * create a plugin + * returns: NOT_FOUND, if the constructor was not found + * FAILED, if the plugin could not be constructed + */ +static status_t create_plugin(private_plugin_loader_t *this, void *handle, + char *name, bool integrity, plugin_t **plugin) +{ + char create[128]; +>>>>>>> upstream/4.5.1 plugin_constructor_t constructor; if (snprintf(create, sizeof(create), "%s_plugin_create", name) >= sizeof(create)) { +<<<<<<< HEAD return NULL; } translate(create, "-", "_"); @@ -86,12 +99,46 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, return plugin; } #else +======= + return FAILED; + } + translate(create, "-", "_"); + constructor = dlsym(handle, create); + if (constructor == NULL) + { + DBG2(DBG_LIB, "plugin '%s': failed to load - %s not found", name, + create); + return NOT_FOUND; + } + if (integrity && lib->integrity) + { + if (!lib->integrity->check_segment(lib->integrity, name, constructor)) + { + DBG1(DBG_LIB, "plugin '%s': failed segment integrity test", name); + return FAILED; + } + DBG1(DBG_LIB, "plugin '%s': passed file and segment integrity tests", + name); + } + *plugin = constructor(); + if (*plugin == NULL) + { + DBG1(DBG_LIB, "plugin '%s': failed to load - %s returned NULL", name, + create); + return FAILED; + } + DBG2(DBG_LIB, "plugin '%s': loaded successfully", name); + return SUCCESS; +} + +>>>>>>> upstream/4.5.1 /** * load a single plugin */ static plugin_t* load_plugin(private_plugin_loader_t *this, char *path, char *name) { +<<<<<<< HEAD char create[128]; char file[PATH_MAX]; void *handle; @@ -106,6 +153,28 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, return NULL; } translate(create, "-", "_"); +======= + char file[PATH_MAX]; + void *handle; + plugin_t *plugin; + + switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &plugin)) + { + case SUCCESS: + return plugin; + case NOT_FOUND: + /* try to load the plugin from a file */ + break; + default: + return NULL; + } + + if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, + name) >= sizeof(file)) + { + return NULL; + } +>>>>>>> upstream/4.5.1 if (lib->integrity) { if (!lib->integrity->check_file(lib->integrity, name, file)) @@ -121,6 +190,7 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); return NULL; } +<<<<<<< HEAD constructor = dlsym(handle, create); if (constructor == NULL) { @@ -155,6 +225,39 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, return plugin; } #endif +======= + if (create_plugin(this, handle, name, TRUE, &plugin) != SUCCESS) + { + dlclose(handle); + return NULL; + } + /* we do not store or free dlopen() handles, leak_detective requires + * the modules to keep loaded until leak report */ + return plugin; +} + +/** + * Check if a plugin is already loaded + */ +static bool plugin_loaded(private_plugin_loader_t *this, char *name) +{ + enumerator_t *enumerator; + bool found = FALSE; + char *current; + + enumerator = this->names->create_enumerator(this->names); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (streq(name, current)) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + return found; +} +>>>>>>> upstream/4.5.1 /** * Implementation of plugin_loader_t.load_plugins. @@ -165,12 +268,18 @@ static bool load(private_plugin_loader_t *this, char *path, char *list) char *token; bool critical_failed = FALSE; +<<<<<<< HEAD #ifndef MONOLITHIC +======= +>>>>>>> upstream/4.5.1 if (path == NULL) { path = PLUGINDIR; } +<<<<<<< HEAD #endif +======= +>>>>>>> upstream/4.5.1 enumerator = enumerator_create_token(list, " ", " "); while (!critical_failed && enumerator->enumerate(enumerator, &token)) @@ -186,6 +295,14 @@ static bool load(private_plugin_loader_t *this, char *path, char *list) critical = TRUE; token[len-1] = '\0'; } +<<<<<<< HEAD +======= + if (plugin_loaded(this, token)) + { + free(token); + continue; + } +>>>>>>> upstream/4.5.1 plugin = load_plugin(this, path, token); if (plugin) { |