Beispiel #1
0
void *extension_library_open(const char *name)
{
    if (!enable_extension_libraries)
    {
        return NULL;
    }

    if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") == NULL)
    {
        // Only do loading checks if we are not doing tests.
        attempted_loading = true;
    }

    const char *dir = getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR");
    char lib[] = "/lib";
    if (dir)
    {
        lib[0] = '\0';
    }
    else
    {
        dir = GetWorkDir();
    }
    char path[strlen(dir) + strlen(lib) + strlen(name) + 2];
    sprintf(path, "%s%s/%s", dir, lib, name);
    void *handle = shlib_open(path);
    if (!handle)
    {
        return handle;
    }

    // Version check, to avoid binary incompatible plugins.
    const char * (*GetExtensionLibraryVersion)() = shlib_load(handle, "GetExtensionLibraryVersion");
    if (!GetExtensionLibraryVersion)
    {
        Log(LOG_LEVEL_ERR, "Could not retreive version from extension plugin (%s). Not loading the plugin.", name);
        goto close_and_fail;
    }

    const char *plugin_version = GetExtensionLibraryVersion();
    unsigned int bin_major, bin_minor, bin_patch;
    unsigned int plug_major, plug_minor, plug_patch;
    if (sscanf(VERSION, "%u.%u.%u", &bin_major, &bin_minor, &bin_patch) != 3)
    {
        Log(LOG_LEVEL_ERR, "Not able to extract version number from binary (%s). Not loading extension plugin.", name);
        goto close_and_fail;
    }
    if (sscanf(plugin_version, "%u.%u.%u", &plug_major, &plug_minor, &plug_patch) != 3)
    {
        Log(LOG_LEVEL_ERR, "Not able to extract version number from plugin (%s). Not loading extension plugin.", name);
        goto close_and_fail;
    }

    if (bin_major != plug_major || bin_minor != plug_minor || bin_patch != plug_patch)
    {
        Log(LOG_LEVEL_ERR, "Extension plugin version does not match CFEngine Community version "
            "(CFEngine Community v%u.%u.%u, Extension (%s) v%u.%u.%u). Refusing to load it.",
            bin_major, bin_minor, bin_patch, name, plug_major, plug_minor, plug_patch);
        goto close_and_fail;
    }

    return handle;

close_and_fail:
    shlib_close(handle);
    return NULL;
}
Beispiel #2
0
void *extension_library_open(const char *name)
{
    if (!enable_extension_libraries)
    {
        return NULL;
    }

    if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") == NULL)
    {
        // Only do loading checks if we are not doing tests.
        attempted_loading = true;
    }

    const char *dirs_to_try[3] = { NULL };
    const char *dir = getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR");
    char lib[] = "/lib";
    if (dir)
    {
        lib[0] = '\0';
        dirs_to_try[0] = dir;
    }
    else
    {
        dirs_to_try[0] = GetWorkDir();
        if (strcmp(WORKDIR, dirs_to_try[0]) != 0)
        {
            // try to load from the real WORKDIR in case GetWorkDir returned the local workdir to the user
            // We try this because enterprise "make install" is in WORKDIR, not per user
            dirs_to_try[1] = WORKDIR;
        }
    }

    void *handle = NULL;
    for (int i = 0; dirs_to_try[i]; i++)
    {
        char path[strlen(dirs_to_try[i]) + strlen(lib) + strlen(name) + 2];
        xsnprintf(path, sizeof(path), "%s%s/%s", dirs_to_try[i], lib, name);

        Log(LOG_LEVEL_DEBUG, "Trying to shlib_open extension plugin '%s' from '%s'", name, path);

        handle = shlib_open(path);
        if (handle)
        {
            Log(LOG_LEVEL_VERBOSE, "Successfully opened extension plugin '%s' from '%s'", name, path);
            break;
        }
        else
        {
            const char *error;
            if (errno == ENOENT)
            {
                error = "(not installed)";
            }
            else
            {
                error = GetErrorStr();
            }
            Log(LOG_LEVEL_VERBOSE, "Could not open extension plugin '%s' from '%s': %s", name, path, error);
        }
    }

    if (!handle)
    {
        return handle;
    }

    // Version check, to avoid binary incompatible plugins.
    const char * (*GetExtensionLibraryVersion)() = shlib_load(handle, "GetExtensionLibraryVersion");
    if (!GetExtensionLibraryVersion)
    {
        Log(LOG_LEVEL_ERR, "Could not retrieve version from extension plugin (%s). Not loading the plugin.", name);
        goto close_and_fail;
    }

    const char *plugin_version = GetExtensionLibraryVersion();
    unsigned int bin_major, bin_minor, bin_patch;
    unsigned int plug_major, plug_minor, plug_patch;
    if (sscanf(VERSION, "%u.%u.%u", &bin_major, &bin_minor, &bin_patch) != 3)
    {
        Log(LOG_LEVEL_ERR, "Not able to extract version number from binary (%s). Not loading extension plugin.", name);
        goto close_and_fail;
    }
    if (sscanf(plugin_version, "%u.%u.%u", &plug_major, &plug_minor, &plug_patch) != 3)
    {
        Log(LOG_LEVEL_ERR, "Not able to extract version number from plugin (%s). Not loading extension plugin.", name);
        goto close_and_fail;
    }

    if (bin_major != plug_major || bin_minor != plug_minor || bin_patch != plug_patch)
    {
        Log(LOG_LEVEL_ERR, "Extension plugin version does not match CFEngine Community version "
            "(CFEngine Community v%u.%u.%u, Extension (%s) v%u.%u.%u). Refusing to load it.",
            bin_major, bin_minor, bin_patch, name, plug_major, plug_minor, plug_patch);
        goto close_and_fail;
    }

    Log(LOG_LEVEL_VERBOSE, "Successfully loaded extension plugin '%s'", name);

    return handle;

close_and_fail:
    shlib_close(handle);
    return NULL;
}
Beispiel #3
0
void extension_library_close(void *handle)
{
    shlib_close(handle);
}
Beispiel #4
0
static int test_lib(void)
{
    SHLIB ssllib = SHLIB_INIT;
    SHLIB cryptolib = SHLIB_INIT;
    SSL_CTX *ctx;
    union {
        void (*func)(void);
        SHLIB_SYM sym;
    } symbols[3];
    TLS_method_t myTLS_method;
    SSL_CTX_new_t mySSL_CTX_new;
    SSL_CTX_free_t mySSL_CTX_free;
    ERR_get_error_t myERR_get_error;
    OpenSSL_version_num_t myOpenSSL_version_num;
    int result = 0;

    switch (test_type) {
    case JUST_CRYPTO:
        if (!TEST_true(shlib_load(path_crypto, &cryptolib)))
            goto end;
        break;
    case CRYPTO_FIRST:
        if (!TEST_true(shlib_load(path_crypto, &cryptolib))
                || !TEST_true(shlib_load(path_ssl, &ssllib)))
            goto end;
        break;
    case SSL_FIRST:
        if (!TEST_true(shlib_load(path_ssl, &ssllib))
                || !TEST_true(shlib_load(path_crypto, &cryptolib)))
            goto end;
        break;
    }

    if (test_type != JUST_CRYPTO) {
        if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym))
                || !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym))
                || !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)))
            goto end;
        myTLS_method = (TLS_method_t)symbols[0].func;
        mySSL_CTX_new = (SSL_CTX_new_t)symbols[1].func;
        mySSL_CTX_free = (SSL_CTX_free_t)symbols[2].func;
        if (!TEST_ptr(ctx = mySSL_CTX_new(myTLS_method())))
            goto end;
        mySSL_CTX_free(ctx);
    }

    if (!TEST_true(shlib_sym(cryptolib, "ERR_get_error", &symbols[0].sym))
            || !TEST_true(shlib_sym(cryptolib, "OpenSSL_version_num",
                                    &symbols[1].sym)))
        goto end;
    myERR_get_error = (ERR_get_error_t)symbols[0].func;
    if (!TEST_int_eq(myERR_get_error(), 0))
        goto end;
    myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func;
    if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER))
        goto end;

#ifdef OPENSSL_USE_NODELETE
    switch (test_type) {
    case JUST_CRYPTO:
        if (!TEST_true(shlib_close(cryptolib)))
            goto end;
        break;
    case CRYPTO_FIRST:
        if (!TEST_true(shlib_close(cryptolib))
                || !TEST_true(shlib_close(ssllib)))
            goto end;
        break;
    case SSL_FIRST:
        if (!TEST_true(shlib_close(ssllib))
                || !TEST_true(shlib_close(cryptolib)))
            goto end;
        break;
    }
#endif

    result = 1;
end:
    return result;
}