Example #1
0
static int dlfcn_load(DSO *dso)
	{
	void *ptr = NULL;
	/* See applicable comments in dso_dl.c */
	char *filename = DSO_convert_filename(dso, NULL);

	if(filename == NULL)
		{
		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
		goto err;
		}
	ptr = dlopen(filename, DLOPEN_FLAG);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
		ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
		goto err;
		}
	if(!sk_push(dso->meth_data, (char *)ptr))
		{
		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
		goto err;
		}
	/* Success */
	dso->loaded_filename = filename;
	return(1);
err:
	/* Cleanup! */
	if(filename != NULL)
		OPENSSL_free(filename);
	if(ptr != NULL)
		dlclose(ptr);
	return(0);
}
Example #2
0
static int beos_load (DSO * dso)
{
    image_id id;

    /* See applicable comments from dso_dl.c */
    char *filename = DSO_convert_filename (dso, NULL);

    if (filename == NULL)
    {
        DSOerr (DSO_F_BEOS_LOAD, DSO_R_NO_FILENAME);
        goto err;
    }
    id = load_add_on (filename);
    if (id < 1)
    {
        DSOerr (DSO_F_BEOS_LOAD, DSO_R_LOAD_FAILED);
        ERR_add_error_data (3, "filename(", filename, ")");
        goto err;
    }
    if (!sk_push (dso->meth_data, (char *) id))
    {
        DSOerr (DSO_F_BEOS_LOAD, DSO_R_STACK_ERROR);
        goto err;
    }
    /* Success */
    dso->loaded_filename = filename;
    return (1);
  err:
    /* Cleanup ! */
    if (filename != NULL)
        OPENSSL_free (filename);
    if (id > 0)
        unload_add_on (id);
    return (0);
}
Example #3
0
static int dlfcn_load(DSO *dso)
{
    void *ptr = NULL;
    /* See applicable comments in dso_dl.c */
    char *filename = DSO_convert_filename(dso, NULL);
    int flags = DLOPEN_FLAG;

    if (filename == NULL) {
        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
        goto err;
    }
# ifdef RTLD_GLOBAL
    if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
        flags |= RTLD_GLOBAL;
# endif
    ptr = dlopen(filename, flags);
    if (ptr == NULL) {
        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
        ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
        goto err;
    }
    if (!sk_void_push(dso->meth_data, (char *)ptr)) {
        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
        goto err;
    }
    /* Success */
    dso->loaded_filename = filename;
    return 1;
 err:
    /* Cleanup! */
    OPENSSL_free(filename);
    if (ptr != NULL)
        dlclose(ptr);
    return 0;
}
static int win32_load(DSO *dso)
	{
	HINSTANCE h = NULL, *p = NULL;
	/* See applicable comments from dso_dl.c */
	char *filename = DSO_convert_filename(dso, NULL);

	if(filename == NULL)
		{
		DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
		goto err;
		}
	h = LoadLibraryA(filename);
	if(h == NULL)
		{
		DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
		ERR_add_error_data(3, "filename(", filename, ")");
		goto err;
		}
	p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
	if(p == NULL)
		{
		DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	*p = h;
	if(!sk_void_push(dso->meth_data, p))
		{
		DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
		goto err;
		}
	/* Success */
	dso->loaded_filename = filename;
	return(1);
err:
	/* Cleanup !*/
	if(filename != NULL)
		OPENSSL_free(filename);
	if(p != NULL)
		OPENSSL_free(p);
	if(h != NULL)
		FreeLibrary(h);
	return(0);
	}
Example #5
0
static int dl_load(DSO *dso)
{
    shl_t ptr = NULL;
    /*
     * We don't do any fancy retries or anything, just take the method's (or
     * DSO's if it has the callback set) best translation of the
     * platform-independent filename and try once with that.
     */
    char *filename = DSO_convert_filename(dso, NULL);

    if (filename == NULL) {
        DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME);
        goto err;
    }
    ptr = shl_load(filename, BIND_IMMEDIATE |
                   (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 :
                    DYNAMIC_PATH), 0L);
    if (ptr == NULL) {
        char errbuf[160];
        DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED);
        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
            ERR_add_error_data(4, "filename(", filename, "): ", errbuf);
        goto err;
    }
    if (!sk_push(dso->meth_data, (char *)ptr)) {
        DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR);
        goto err;
    }
    /*
     * Success, stick the converted filename we've loaded under into the DSO
     * (it also serves as the indicator that we are currently loaded).
     */
    dso->loaded_filename = filename;
    return (1);
 err:
    /* Cleanup! */
    OPENSSL_free(filename);
    if (ptr != NULL)
        shl_unload(ptr);
    return (0);
}
Example #6
0
static int
dlfcn_load(DSO *dso)
{
	void *ptr = NULL;
	/* See applicable comments in dso_dl.c */
	char *filename = DSO_convert_filename(dso, NULL);
	int flags = RTLD_LAZY;

	if (filename == NULL) {
		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
		goto err;
	}

	if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
		flags |= RTLD_GLOBAL;
	ptr = dlopen(filename, flags);
	if (ptr == NULL) {
		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
		ERR_asprintf_error_data("filename(%s): %s", filename,
		    dlerror());
		goto err;
	}
	if (!sk_void_push(dso->meth_data, (char *)ptr)) {
		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
		goto err;
	}
	/* Success */
	dso->loaded_filename = filename;
	return (1);

err:
	/* Cleanup! */
	free(filename);
	if (ptr != NULL)
		dlclose(ptr);
	return (0);
}
Example #7
0
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
{
    ENGINE cpy;
    dynamic_fns fns;

    if (ctx->dynamic_dso == NULL)
        ctx->dynamic_dso = DSO_new();
    if (ctx->dynamic_dso == NULL)
        return 0;
    if (!ctx->DYNAMIC_LIBNAME) {
        if (!ctx->engine_id)
            return 0;
        ctx->DYNAMIC_LIBNAME =
            DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
    }
    if (!int_load(ctx)) {
        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND);
        DSO_free(ctx->dynamic_dso);
        ctx->dynamic_dso = NULL;
        return 0;
    }
    /* We have to find a bind function otherwise it'll always end badly */
    if (!
        (ctx->bind_engine =
         (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso,
                                             ctx->DYNAMIC_F2))) {
        ctx->bind_engine = NULL;
        DSO_free(ctx->dynamic_dso);
        ctx->dynamic_dso = NULL;
        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE);
        return 0;
    }
    /* Do we perform version checking? */
    if (!ctx->no_vcheck) {
        unsigned long vcheck_res = 0;
        /*
         * Now we try to find a version checking function and decide how to
         * cope with failure if/when it fails.
         */
        ctx->v_check =
            (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso,
                                               ctx->DYNAMIC_F1);
        if (ctx->v_check)
            vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
        /*
         * We fail if the version checker veto'd the load *or* if it is
         * deferring to us (by returning its version) and we think it is too
         * old.
         */
        if (vcheck_res < OSSL_DYNAMIC_OLDEST) {
            /* Fail */
            ctx->bind_engine = NULL;
            ctx->v_check = NULL;
            DSO_free(ctx->dynamic_dso);
            ctx->dynamic_dso = NULL;
            ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
                      ENGINE_R_VERSION_INCOMPATIBILITY);
            return 0;
        }
    }
    /*
     * First binary copy the ENGINE structure so that we can roll back if the
     * hand-over fails
     */
    memcpy(&cpy, e, sizeof(ENGINE));
    /*
     * Provide the ERR, "ex_data", memory, and locking callbacks so the
     * loaded library uses our state rather than its own. FIXME: As noted in
     * engine.h, much of this would be simplified if each area of code
     * provided its own "summary" structure of all related callbacks. It
     * would also increase opaqueness.
     */
    fns.static_state = ENGINE_get_static_state();
    fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
    fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
    fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
    fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
    fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
    /*
     * Now that we've loaded the dynamic engine, make sure no "dynamic"
     * ENGINE elements will show through.
     */
    engine_set_all_null(e);

    /* Try to bind the ENGINE onto our own ENGINE structure */
    if (!ctx->bind_engine(e, ctx->engine_id, &fns)) {
        ctx->bind_engine = NULL;
        ctx->v_check = NULL;
        DSO_free(ctx->dynamic_dso);
        ctx->dynamic_dso = NULL;
        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED);
        /* Copy the original ENGINE structure back */
        memcpy(e, &cpy, sizeof(ENGINE));
        return 0;
    }
    /* Do we try to add this ENGINE to the internal list too? */
    if (ctx->list_add_value > 0) {
        if (!ENGINE_add(e)) {
            /* Do we tolerate this or fail? */
            if (ctx->list_add_value > 1) {
                /*
                 * Fail - NB: By this time, it's too late to rollback, and
                 * trying to do so allows the bind_engine() code to have
                 * created leaks. We just have to fail where we are, after
                 * the ENGINE has changed.
                 */
                ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
                          ENGINE_R_CONFLICTING_ENGINE_ID);
                return 0;
            }
            /* Tolerate */
            ERR_clear_error();
        }
    }
    return 1;
}
Example #8
0
static int vms_load(DSO *dso)
{
    void *ptr = NULL;
    /* See applicable comments in dso_dl.c */
    char *filename = DSO_convert_filename(dso, NULL);

/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
# if __INITIAL_POINTER_SIZE == 64
#  define DSO_MALLOC _malloc32
#  pragma pointer_size save
#  pragma pointer_size 32
# else                          /* __INITIAL_POINTER_SIZE == 64 */
#  define DSO_MALLOC OPENSSL_malloc
# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */

    DSO_VMS_INTERNAL *p = NULL;

# if __INITIAL_POINTER_SIZE == 64
#  pragma pointer_size restore
# endif                         /* __INITIAL_POINTER_SIZE == 64 */

    const char *sp1, *sp2;      /* Search result */
    const char *ext = NULL;	/* possible extension to add */

    if (filename == NULL) {
        DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME);
        goto err;
    }

    /*-
     * A file specification may look like this:
     *
     *      node::dev:[dir-spec]name.type;ver
     *
     * or (for compatibility with TOPS-20):
     *
     *      node::dev:<dir-spec>name.type;ver
     *
     * and the dir-spec uses '.' as separator.  Also, a dir-spec
     * may consist of several parts, with mixed use of [] and <>:
     *
     *      [dir1.]<dir2>
     *
     * We need to split the file specification into the name and
     * the rest (both before and after the name itself).
     */
    /*
     * Start with trying to find the end of a dir-spec, and save the position
     * of the byte after in sp1
     */
    sp1 = strrchr(filename, ']');
    sp2 = strrchr(filename, '>');
    if (sp1 == NULL)
        sp1 = sp2;
    if (sp2 != NULL && sp2 > sp1)
        sp1 = sp2;
    if (sp1 == NULL)
        sp1 = strrchr(filename, ':');
    if (sp1 == NULL)
        sp1 = filename;
    else
        sp1++;                  /* The byte after the found character */
    /* Now, let's see if there's a type, and save the position in sp2 */
    sp2 = strchr(sp1, '.');
    /*
     * If there is a period and the next character is a semi-colon,
     * we need to add an extension
     */
    if (sp2 != NULL && sp2[1] == ';')
        ext = ".EXE";
    /*
     * If we found it, that's where we'll cut.  Otherwise, look for a version
     * number and save the position in sp2
     */
    if (sp2 == NULL) {
        sp2 = strchr(sp1, ';');
        ext = ".EXE";
    }
    /*
     * If there was still nothing to find, set sp2 to point at the end of the
     * string
     */
    if (sp2 == NULL)
        sp2 = sp1 + strlen(sp1);

    /* Check that we won't get buffer overflows */
    if (sp2 - sp1 > FILENAME_MAX
        || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) {
        DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG);
        goto err;
    }

    p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL));
    if (p == NULL) {
        DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    strncpy(p->filename, sp1, sp2 - sp1);
    p->filename[sp2 - sp1] = '\0';

    strncpy(p->imagename, filename, sp1 - filename);
    p->imagename[sp1 - filename] = '\0';
    if (ext) {
        strcat(p->imagename, ext);
        if (*sp2 == '.')
            sp2++;
    }
    strcat(p->imagename, sp2);

    p->filename_dsc.dsc$w_length = strlen(p->filename);
    p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
    p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
    p->filename_dsc.dsc$a_pointer = p->filename;
    p->imagename_dsc.dsc$w_length = strlen(p->imagename);
    p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
    p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
    p->imagename_dsc.dsc$a_pointer = p->imagename;

    if (!sk_void_push(dso->meth_data, (char *)p)) {
        DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR);
        goto err;
    }

    /* Success (for now, we lie.  We actually do not know...) */
    dso->loaded_filename = filename;
    return (1);
 err:
    /* Cleanup! */
    if (p != NULL)
        OPENSSL_free(p);
    if (filename != NULL)
        OPENSSL_free(filename);
    return (0);
}
Example #9
0
/*
 * Internal version that doesn't affect the store flags, and thereby avoid
 * locking.  Direct callers must remember to set the store flags when
 * appropriate
 */
static int provider_activate(OSSL_PROVIDER *prov)
{
    const OSSL_DISPATCH *provider_dispatch = NULL;

    if (prov->flag_initialized)
        return 1;

    /*
     * If the init function isn't set, it indicates that this provider is
     * a loadable module.
     */
    if (prov->init_function == NULL) {
        if (prov->module == NULL) {
            char *allocated_path = NULL;
            const char *module_path = NULL;
            char *merged_path = NULL;
            const char *load_dir = ossl_safe_getenv("OPENSSL_MODULES");

            if ((prov->module = DSO_new()) == NULL) {
                /* DSO_new() generates an error already */
                return 0;
            }

            if (load_dir == NULL)
                load_dir = MODULESDIR;

            DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS,
                     DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL);

            module_path = prov->path;
            if (module_path == NULL)
                module_path = allocated_path =
                    DSO_convert_filename(prov->module, prov->name);
            if (module_path != NULL)
                merged_path = DSO_merge(prov->module, module_path, load_dir);

            if (merged_path == NULL
                || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) {
                DSO_free(prov->module);
                prov->module = NULL;
            }

            OPENSSL_free(merged_path);
            OPENSSL_free(allocated_path);
        }

        if (prov->module != NULL)
            prov->init_function = (OSSL_provider_init_fn *)
                DSO_bind_func(prov->module, "OSSL_provider_init");
    }

    if (prov->init_function == NULL
        || !prov->init_function(prov, core_dispatch, &provider_dispatch)) {
        CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
        ERR_add_error_data(2, "name=", prov->name);
        DSO_free(prov->module);
        prov->module = NULL;
        return 0;
    }

    for (; provider_dispatch->function_id != 0; provider_dispatch++) {
        switch (provider_dispatch->function_id) {
        case OSSL_FUNC_PROVIDER_TEARDOWN:
            prov->teardown =
                OSSL_get_provider_teardown(provider_dispatch);
            break;
        case OSSL_FUNC_PROVIDER_GET_PARAM_TYPES:
            prov->get_param_types =
                OSSL_get_provider_get_param_types(provider_dispatch);
            break;
        case OSSL_FUNC_PROVIDER_GET_PARAMS:
            prov->get_params =
                OSSL_get_provider_get_params(provider_dispatch);
            break;
        case OSSL_FUNC_PROVIDER_QUERY_OPERATION:
            prov->query_operation =
                OSSL_get_provider_query_operation(provider_dispatch);
            break;
        }
    }

    /* With this flag set, this provider has become fully "loaded". */
    prov->flag_initialized = 1;

    return 1;
}