提交 02acf140 编写于 作者: R Richard Levitte

Step 11b of move of engines: Time to make the changes to support

automatic load of dynamic engines.  Add functionality to the dynamic
engine to handle engine directories and loading from those.  This
is currently NOT compatible with the use of LD_LIBRARY_PATH and
similar environment variables.

Note: The changes in step 11 have all been made by Geoff Thorpe.
Credit where credit is due.
上级 6ac3309c
......@@ -80,7 +80,9 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4)
#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
/* The constants used when creating the ENGINE */
static const char *engine_dynamic_id = "dynamic";
......@@ -102,6 +104,14 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
"LIST_ADD",
"Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
ENGINE_CMD_FLAG_NUMERIC},
{DYNAMIC_CMD_DIR_LOAD,
"DIR_LOAD",
"Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
ENGINE_CMD_FLAG_NUMERIC},
{DYNAMIC_CMD_DIR_ADD,
"DIR_ADD",
"Adds a directory from which ENGINEs can be loaded",
ENGINE_CMD_FLAG_STRING},
{DYNAMIC_CMD_LOAD,
"LOAD",
"Load up the ENGINE specified by other settings",
......@@ -136,12 +146,18 @@ struct st_dynamic_data_ctx
const char *DYNAMIC_F1;
/* The symbol name for the "initialise ENGINE structure" function */
const char *DYNAMIC_F2;
/* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
* 'dirs' for loading. Default is to use 'dirs' as a fallback. */
int dir_load;
/* A stack of directories from which ENGINEs could be loaded */
STACK *dirs;
};
/* This is the "ex_data" index we obtain and reserve for use with our context
* structure. */
static int dynamic_ex_data_idx = -1;
static void int_free_str(void *s) { OPENSSL_free(s); }
/* Because our ex_data element may or may not get allocated depending on whether
* a "first-use" occurs before the ENGINE is freed, we have a memory leak
* problem to solve. We can't declare a "new" handler for the ex_data as we
......@@ -161,6 +177,8 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
if(ctx->engine_id)
OPENSSL_free((void*)ctx->engine_id);
if(ctx->dirs)
sk_pop_free(ctx->dirs, int_free_str);
OPENSSL_free(ctx);
}
}
......@@ -188,6 +206,14 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
c->list_add_value = 0;
c->DYNAMIC_F1 = "v_check";
c->DYNAMIC_F2 = "bind_engine";
c->dir_load = 1;
c->dirs = sk_new_null();
if(!c->dirs)
{
ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
OPENSSL_free(c);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
dynamic_ex_data_idx)) == NULL)
......@@ -346,6 +372,34 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
return 1;
case DYNAMIC_CMD_LOAD:
return dynamic_load(e, ctx);
case DYNAMIC_CMD_DIR_LOAD:
if((i < 0) || (i > 2))
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_INVALID_ARGUMENT);
return 0;
}
ctx->dir_load = (int)i;
return 1;
case DYNAMIC_CMD_DIR_ADD:
/* a NULL 'p' or a string of zero-length is the same thing */
if(!p || (strlen((const char *)p) < 1))
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_INVALID_ARGUMENT);
return 0;
}
{
char *tmp_str = BUF_strdup(p);
if(!tmp_str)
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ERR_R_MALLOC_FAILURE);
return 0;
}
sk_insert(ctx->dirs, tmp_str, -1);
}
return 1;
default:
break;
}
......@@ -353,16 +407,53 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
return 0;
}
static int int_load(dynamic_data_ctx *ctx)
{
int num, loop;
/* Unless told not to, try a direct load */
if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
return 1;
/* If we're not allowed to use 'dirs' or we have none, fail */
if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1))
return 0;
for(loop = 0; loop < num; loop++)
{
const char *s = sk_value(ctx->dirs, loop);
char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
if(!merge)
return 0;
if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
{
/* Found what we're looking for */
OPENSSL_free(merge);
return 1;
}
OPENSSL_free(merge);
}
return 0;
}
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
{
ENGINE cpy;
dynamic_fns fns;
if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL,
ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL))
if(!ctx->dynamic_dso)
ctx->dynamic_dso = DSO_new();
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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册