ssl/libcrypto/src/crypto/conf/conf_api.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* conf_api.c */
       
     2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       
     3  * All rights reserved.
       
     4  *
       
     5  * This package is an SSL implementation written
       
     6  * by Eric Young (eay@cryptsoft.com).
       
     7  * The implementation was written so as to conform with Netscapes SSL.
       
     8  * 
       
     9  * This library is free for commercial and non-commercial use as long as
       
    10  * the following conditions are aheared to.  The following conditions
       
    11  * apply to all code found in this distribution, be it the RC4, RSA,
       
    12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
       
    13  * included with this distribution is covered by the same copyright terms
       
    14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
       
    15  * 
       
    16  * Copyright remains Eric Young's, and as such any Copyright notices in
       
    17  * the code are not to be removed.
       
    18  * If this package is used in a product, Eric Young should be given attribution
       
    19  * as the author of the parts of the library used.
       
    20  * This can be in the form of a textual message at program startup or
       
    21  * in documentation (online or textual) provided with the package.
       
    22  * 
       
    23  * Redistribution and use in source and binary forms, with or without
       
    24  * modification, are permitted provided that the following conditions
       
    25  * are met:
       
    26  * 1. Redistributions of source code must retain the copyright
       
    27  *    notice, this list of conditions and the following disclaimer.
       
    28  * 2. Redistributions in binary form must reproduce the above copyright
       
    29  *    notice, this list of conditions and the following disclaimer in the
       
    30  *    documentation and/or other materials provided with the distribution.
       
    31  * 3. All advertising materials mentioning features or use of this software
       
    32  *    must display the following acknowledgement:
       
    33  *    "This product includes cryptographic software written by
       
    34  *     Eric Young (eay@cryptsoft.com)"
       
    35  *    The word 'cryptographic' can be left out if the rouines from the library
       
    36  *    being used are not cryptographic related :-).
       
    37  * 4. If you include any Windows specific code (or a derivative thereof) from 
       
    38  *    the apps directory (application code) you must include an acknowledgement:
       
    39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
       
    40  * 
       
    41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
       
    42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
       
    45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    51  * SUCH DAMAGE.
       
    52  * 
       
    53  * The licence and distribution terms for any publically available version or
       
    54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
       
    55  * copied and put under another distribution licence
       
    56  * [including the GNU Public Licence.]
       
    57  */
       
    58 
       
    59 /* Part of the code in here was originally in conf.c, which is now removed */
       
    60 
       
    61 #ifndef CONF_DEBUG
       
    62 # undef NDEBUG /* avoid conflicting definitions */
       
    63 # define NDEBUG
       
    64 #endif
       
    65 
       
    66 #include <assert.h>
       
    67 #include <string.h>
       
    68 #include <openssl/conf.h>
       
    69 #include <openssl/conf_api.h>
       
    70 #include "e_os.h"
       
    71 
       
    72 static void value_free_hash(CONF_VALUE *a, LHASH *conf);
       
    73 static void value_free_stack(CONF_VALUE *a,LHASH *conf);
       
    74 static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE *, LHASH *)
       
    75 static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_stack, CONF_VALUE *, LHASH *)
       
    76 /* We don't use function pointer casting or wrapper functions - but cast each
       
    77  * callback parameter inside the callback functions. */
       
    78 /* static unsigned long hash(CONF_VALUE *v); */
       
    79 static unsigned long hash(const void *v_void);
       
    80 /* static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); */
       
    81 static int cmp_conf(const void *a_void,const void *b_void);
       
    82 
       
    83 /* Up until OpenSSL 0.9.5a, this was get_section */
       
    84 EXPORT_C CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
       
    85 	{
       
    86 	CONF_VALUE *v,vv;
       
    87 
       
    88 	if ((conf == NULL) || (section == NULL)) return(NULL);
       
    89 	vv.name=NULL;
       
    90 	vv.section=(char *)section;
       
    91 	v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
       
    92 	return(v);
       
    93 	}
       
    94 
       
    95 /* Up until OpenSSL 0.9.5a, this was CONF_get_section */
       
    96 EXPORT_C STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
       
    97 					       const char *section)
       
    98 	{
       
    99 	CONF_VALUE *v;
       
   100 
       
   101 	v=_CONF_get_section(conf,section);
       
   102 	if (v != NULL)
       
   103 		return((STACK_OF(CONF_VALUE) *)v->value);
       
   104 	else
       
   105 		return(NULL);
       
   106 	}
       
   107 
       
   108 EXPORT_C int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
       
   109 	{
       
   110 	CONF_VALUE *v = NULL;
       
   111 	STACK_OF(CONF_VALUE) *ts;
       
   112 
       
   113 	ts = (STACK_OF(CONF_VALUE) *)section->value;
       
   114 
       
   115 	value->section=section->section;	
       
   116 	if (!sk_CONF_VALUE_push(ts,value))
       
   117 		{
       
   118 		return 0;
       
   119 		}
       
   120 
       
   121 	v = (CONF_VALUE *)lh_insert(conf->data, value);
       
   122 	if (v != NULL)
       
   123 		{
       
   124 		(void)sk_CONF_VALUE_delete_ptr(ts,v);
       
   125 		OPENSSL_free(v->name);
       
   126 		OPENSSL_free(v->value);
       
   127 		OPENSSL_free(v);
       
   128 		}
       
   129 	return 1;
       
   130 	}
       
   131 
       
   132 EXPORT_C char *_CONF_get_string(const CONF *conf, const char *section, const char *name)
       
   133 	{
       
   134 	CONF_VALUE *v,vv;
       
   135 	char *p;
       
   136 
       
   137 	if (name == NULL) return(NULL);
       
   138 	if (conf != NULL)
       
   139 		{
       
   140 		if (section != NULL)
       
   141 			{
       
   142 			vv.name=(char *)name;
       
   143 			vv.section=(char *)section;
       
   144 			v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
       
   145 			if (v != NULL) return(v->value);
       
   146 			if (strcmp(section,"ENV") == 0)
       
   147 				{
       
   148 				p=Getenv(name);
       
   149 				if (p != NULL) return(p);
       
   150 				}
       
   151 			}
       
   152 		vv.section="default";
       
   153 		vv.name=(char *)name;
       
   154 		v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
       
   155 		if (v != NULL)
       
   156 			return(v->value);
       
   157 		else
       
   158 			return(NULL);
       
   159 		}
       
   160 	else
       
   161 		return(Getenv(name));
       
   162 	}
       
   163 
       
   164 #if 0 /* There's no way to provide error checking with this function, so
       
   165 	 force implementors of the higher levels to get a string and read
       
   166 	 the number themselves. */
       
   167 EXPORT_C long _CONF_get_number(CONF *conf, char *section, char *name)
       
   168 	{
       
   169 	char *str;
       
   170 	long ret=0;
       
   171 
       
   172 	str=_CONF_get_string(conf,section,name);
       
   173 	if (str == NULL) return(0);
       
   174 	for (;;)
       
   175 		{
       
   176 		if (conf->meth->is_number(conf, *str))
       
   177 			ret=ret*10+conf->meth->to_int(conf, *str);
       
   178 		else
       
   179 			return(ret);
       
   180 		str++;
       
   181 		}
       
   182 	}
       
   183 #endif
       
   184 
       
   185 EXPORT_C int _CONF_new_data(CONF *conf)
       
   186 	{
       
   187 	if (conf == NULL)
       
   188 		{
       
   189 		return 0;
       
   190 		}
       
   191 	if (conf->data == NULL)
       
   192 		if ((conf->data = lh_new(hash, cmp_conf)) == NULL)
       
   193 			{
       
   194 			return 0;
       
   195 			}
       
   196 	return 1;
       
   197 	}
       
   198 
       
   199 EXPORT_C void _CONF_free_data(CONF *conf)
       
   200 	{
       
   201 	if (conf == NULL || conf->data == NULL) return;
       
   202 
       
   203 	conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()'
       
   204 				  * works as expected */
       
   205 	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_hash),
       
   206 			conf->data);
       
   207 
       
   208 	/* We now have only 'section' entries in the hash table.
       
   209 	 * Due to problems with */
       
   210 
       
   211 	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_stack),
       
   212 			conf->data);
       
   213 	lh_free(conf->data);
       
   214 	}
       
   215 
       
   216 static void value_free_hash(CONF_VALUE *a, LHASH *conf)
       
   217 	{
       
   218 	if (a->name != NULL)
       
   219 		{
       
   220 		a=(CONF_VALUE *)lh_delete(conf,a);
       
   221 		}
       
   222 	}
       
   223 
       
   224 static void value_free_stack(CONF_VALUE *a, LHASH *conf)
       
   225 	{
       
   226 	CONF_VALUE *vv;
       
   227 	STACK *sk;
       
   228 	int i;
       
   229 
       
   230 	if (a->name != NULL) return;
       
   231 
       
   232 	sk=(STACK *)a->value;
       
   233 	for (i=sk_num(sk)-1; i>=0; i--)
       
   234 		{
       
   235 		vv=(CONF_VALUE *)sk_value(sk,i);
       
   236 		OPENSSL_free(vv->value);
       
   237 		OPENSSL_free(vv->name);
       
   238 		OPENSSL_free(vv);
       
   239 		}
       
   240 	if (sk != NULL) sk_free(sk);
       
   241 	OPENSSL_free(a->section);
       
   242 	OPENSSL_free(a);
       
   243 	}
       
   244 
       
   245 /* static unsigned long hash(CONF_VALUE *v) */
       
   246 static unsigned long hash(const void *v_void)
       
   247 	{
       
   248 	CONF_VALUE *v = (CONF_VALUE *)v_void;
       
   249 	return((lh_strhash(v->section)<<2)^lh_strhash(v->name));
       
   250 	}
       
   251 
       
   252 /* static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) */
       
   253 static int cmp_conf(const void *a_void,const  void *b_void)
       
   254 	{
       
   255 	int i;
       
   256 	CONF_VALUE *a = (CONF_VALUE *)a_void;
       
   257 	CONF_VALUE *b = (CONF_VALUE *)b_void;
       
   258 
       
   259 	if (a->section != b->section)
       
   260 		{
       
   261 		i=strcmp(a->section,b->section);
       
   262 		if (i) return(i);
       
   263 		}
       
   264 
       
   265 	if ((a->name != NULL) && (b->name != NULL))
       
   266 		{
       
   267 		i=strcmp(a->name,b->name);
       
   268 		return(i);
       
   269 		}
       
   270 	else if (a->name == b->name)
       
   271 		return(0);
       
   272 	else
       
   273 		return((a->name == NULL)?-1:1);
       
   274 	}
       
   275 
       
   276 /* Up until OpenSSL 0.9.5a, this was new_section */
       
   277 EXPORT_C CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
       
   278 	{
       
   279 	STACK *sk=NULL;
       
   280 	int ok=0,i;
       
   281 	CONF_VALUE *v=NULL,*vv;
       
   282 
       
   283 	if ((sk=sk_new_null()) == NULL)
       
   284 		goto err;
       
   285 	if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
       
   286 		goto err;
       
   287 	i=strlen(section)+1;
       
   288 	if ((v->section=(char *)OPENSSL_malloc(i)) == NULL)
       
   289 		goto err;
       
   290 
       
   291 	memcpy(v->section,section,i);
       
   292 	v->name=NULL;
       
   293 	v->value=(char *)sk;
       
   294 	
       
   295 	vv=(CONF_VALUE *)lh_insert(conf->data,v);
       
   296 	assert(vv == NULL);
       
   297 	ok=1;
       
   298 err:
       
   299 	if (!ok)
       
   300 		{
       
   301 		if (sk != NULL) sk_free(sk);
       
   302 		if (v != NULL) OPENSSL_free(v);
       
   303 		v=NULL;
       
   304 		}
       
   305 	return(v);
       
   306 	}
       
   307 
       
   308 IMPLEMENT_STACK_OF(CONF_VALUE)