os/ossrv/ssl/libcrypto/src/crypto/conf/conf_api.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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)