/* conf_mod.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
/* ====================================================================
*/
#include <stdio.h>
+#include <ctype.h>
#include <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/conf.h>
static void module_free(CONF_MODULE *md);
static void module_finish(CONF_IMODULE *imod);
-static int module_run(CONF *cnf, char *name, char *value, unsigned long flags);
+static int module_run(const CONF *cnf, char *name, char *value,
+ unsigned long flags);
static CONF_MODULE *module_add(DSO *dso, const char *name,
conf_init_func *ifunc, conf_finish_func *ffunc);
static CONF_MODULE *module_find(char *name);
-static int module_init(CONF_MODULE *pmod, char *name, char *value, CONF *cnf);
-static CONF_MODULE *module_load_dso(CONF *cnf, char *name, char *value, unsigned long flags);
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+ const CONF *cnf);
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+ unsigned long flags);
/* Main function: load modules from a CONF structure */
-int CONF_modules_load(CONF *cnf, char *appname, unsigned long flags)
+int CONF_modules_load(const CONF *cnf, const char *appname,
+ unsigned long flags)
{
STACK_OF(CONF_VALUE) *values;
CONF_VALUE *vl;
- char *vsection;
+ char *vsection = NULL;
int ret, i;
- if (!cnf || !appname)
+ if (!cnf)
return 1;
+ if (appname)
+ vsection = NCONF_get_string(cnf, NULL, appname);
- vsection = NCONF_get_string(cnf, NULL, appname);
+ if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+ vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
if (!vsection)
{
}
-int CONF_modules_load_file(char *filename, char *appname, unsigned long flags)
+int CONF_modules_load_file(const char *filename, const char *appname,
+ unsigned long flags)
{
+ char *file = NULL;
CONF *conf = NULL;
int ret = 0;
conf = NCONF_new(NULL);
if (!conf)
goto err;
- if (NCONF_load(conf, filename, NULL) <= 0)
+ if (filename == NULL)
+ {
+ file = CONF_get1_default_config_file();
+ if (!file)
+ goto err;
+ }
+ else
+ file = (char *)filename;
+
+ if (NCONF_load(conf, file, NULL) <= 0)
+ {
+ if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
+ (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE))
+ {
+ ERR_clear_error();
+ ret = 1;
+ }
goto err;
+ }
ret = CONF_modules_load(conf, appname, flags);
err:
+ if (filename == NULL)
+ OPENSSL_free(file);
NCONF_free(conf);
return ret;
}
-static int module_run(CONF *cnf, char *name, char *value, unsigned long flags)
+static int module_run(const CONF *cnf, char *name, char *value,
+ unsigned long flags)
{
CONF_MODULE *md;
int ret;
md = module_find(name);
/* Module not found: try to load DSO */
- if (!md)
+ if (!md && !(flags & CONF_MFLAGS_NO_DSO))
md = module_load_dso(cnf, name, value, flags);
if (!md)
{
if (!(flags & CONF_MFLAGS_SILENT))
{
- char rcode[10];
- CONFerr(CONF_F_CONF_MODULES_LOAD, CONF_R_MODULE_INITIALIZATION_ERROR);
- sprintf(rcode, "%-8d", ret);
+ char rcode[DECIMAL_SIZE(ret)+1];
+ CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
+ BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode);
}
}
}
/* Load a module from a DSO */
-static CONF_MODULE *module_load_dso(CONF *cnf, char *name, char *value, unsigned long flags)
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+ unsigned long flags)
{
DSO *dso = NULL;
conf_init_func *ifunc;
path = NCONF_get_string(cnf, value, "path");
if (!path)
{
- ERR_get_error();
+ ERR_clear_error();
path = name;
}
dso = DSO_load(NULL, path, NULL, 0);
goto err;
}
ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
- if (!ffunc)
- {
- errcode = CONF_R_MISSING_FINISH_FUNCTION;
- goto err;
- }
/* All OK, add module */
md = module_add(dso, name, ifunc, ffunc);
/* add module to list */
static CONF_MODULE *module_add(DSO *dso, const char *name,
- conf_init_func *ifunc, conf_finish_func *ffunc)
+ conf_init_func *ifunc, conf_finish_func *ffunc)
{
CONF_MODULE *tmod = NULL;
if (supported_modules == NULL)
}
/* initialize a module */
-static int module_init(CONF_MODULE *pmod, char *name, char *value, CONF *cnf)
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+ const CONF *cnf)
{
int ret = 1;
int init_called = 0;
{
int i;
CONF_MODULE *md;
+ CONF_modules_finish();
/* unload modules in reverse order */
for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--)
{
if (((md->links > 0) || !md->dso) && !all)
continue;
/* Since we're working in reverse this is OK */
- sk_CONF_MODULE_delete(supported_modules, i);
+ (void)sk_CONF_MODULE_delete(supported_modules, i);
module_free(md);
}
if (sk_CONF_MODULE_num(supported_modules) == 0)
static void module_finish(CONF_IMODULE *imod)
{
- imod->pmod->finish(imod);
+ if (imod->pmod->finish)
+ imod->pmod->finish(imod);
imod->pmod->links--;
OPENSSL_free(imod->name);
OPENSSL_free(imod->value);
/* Utility functions */
-char *CONF_imodule_get_name(CONF_IMODULE *md)
+const char *CONF_imodule_get_name(const CONF_IMODULE *md)
{
return md->name;
}
-char *CONF_imodule_get_value(CONF_IMODULE *md)
+const char *CONF_imodule_get_value(const CONF_IMODULE *md)
{
return md->value;
}
-void *CONF_imodule_get_usr_data(CONF_IMODULE *md)
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
{
return md->usr_data;
}
md->usr_data = usr_data;
}
-CONF_MODULE *CONF_imodule_get_module(CONF_IMODULE *md)
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
{
return md->pmod;
}
-unsigned long CONF_imodule_get_flags(CONF_IMODULE *md)
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
{
return md->flags;
}
pmod->usr_data = usr_data;
}
+/* Return default config file name */
+
+char *CONF_get1_default_config_file(void)
+ {
+ char *file;
+ int len;
+
+ file = getenv("OPENSSL_CONF");
+ if (file)
+ return BUF_strdup(file);
+
+ len = strlen(X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+ len++;
+#endif
+ len += strlen(OPENSSL_CONF);
+
+ file = OPENSSL_malloc(len + 1);
+
+ if (!file)
+ return NULL;
+ BUF_strlcpy(file,X509_get_default_cert_area(),len + 1);
+#ifndef OPENSSL_SYS_VMS
+ BUF_strlcat(file,"/",len + 1);
+#endif
+ BUF_strlcat(file,OPENSSL_CONF,len + 1);
+
+ return file;
+ }
+
+/* This function takes a list separated by 'sep' and calls the
+ * callback function giving the start and length of each member
+ * optionally stripping leading and trailing whitespace. This can
+ * be used to parse comma separated lists for example.
+ */
+
+int CONF_parse_list(const char *list_, int sep, int nospc,
+ int (*list_cb)(const char *elem, int len, void *usr), void *arg)
+ {
+ int ret;
+ const char *lstart, *tmpend, *p;
+
+ if(list_ == NULL)
+ {
+ CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+ return 0;
+ }
+
+ lstart = list_;
+ for(;;)
+ {
+ if (nospc)
+ {
+ while(*lstart && isspace((unsigned char)*lstart))
+ lstart++;
+ }
+ p = strchr(lstart, sep);
+ if (p == lstart || !*lstart)
+ ret = list_cb(NULL, 0, arg);
+ else
+ {
+ if (p)
+ tmpend = p - 1;
+ else
+ tmpend = lstart + strlen(lstart) - 1;
+ if (nospc)
+ {
+ while(isspace((unsigned char)*tmpend))
+ tmpend--;
+ }
+ ret = list_cb(lstart, tmpend - lstart + 1, arg);
+ }
+ if (ret <= 0)
+ return ret;
+ if (p == NULL)
+ return 1;
+ lstart = p + 1;
+ }
+ }
+