ssl/libcrypto/src/crypto/conf/conf_def.c
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 /* crypto/conf/conf.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  © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
    60  */
       
    61 
       
    62 /* Part of the code in here was originally in conf.c, which is now removed */
       
    63 
       
    64 #include <stdio.h>
       
    65 #include <string.h>
       
    66 #include "cryptlib.h"
       
    67 #include <openssl/stack.h>
       
    68 #include <openssl/lhash.h>
       
    69 #include <openssl/conf.h>
       
    70 #include <openssl/conf_api.h>
       
    71 #include "conf_def.h"
       
    72 #include <openssl/buffer.h>
       
    73 #include <openssl/err.h>
       
    74 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
       
    75 #include "libcrypto_wsd_macros.h"
       
    76 #include "libcrypto_wsd.h"
       
    77 #endif
       
    78 
       
    79 static char *eat_ws(CONF *conf, char *p);
       
    80 static char *eat_alpha_numeric(CONF *conf, char *p);
       
    81 static void clear_comments(CONF *conf, char *p);
       
    82 static int str_copy(CONF *conf,char *section,char **to, char *from);
       
    83 static char *scan_quote(CONF *conf, char *p);
       
    84 static char *scan_dquote(CONF *conf, char *p);
       
    85 #define scan_esc(conf,p)	(((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
       
    86 
       
    87 static CONF *def_create(CONF_METHOD *meth);
       
    88 static int def_init_default(CONF *conf);
       
    89 static int def_init_WIN32(CONF *conf);
       
    90 static int def_destroy(CONF *conf);
       
    91 static int def_destroy_data(CONF *conf);
       
    92 static int def_load(CONF *conf, const char *name, long *eline);
       
    93 static int def_load_bio(CONF *conf, BIO *bp, long *eline);
       
    94 static int def_dump(const CONF *conf, BIO *bp);
       
    95 static int def_is_number(const CONF *conf, char c);
       
    96 static int def_to_int(const CONF *conf, char c);
       
    97 
       
    98 const char CONF_def_version[]="CONF_def" OPENSSL_VERSION_PTEXT;
       
    99 
       
   100 #ifndef EMULATOR
       
   101 static CONF_METHOD default_method = {
       
   102 	"OpenSSL default",
       
   103 	def_create,
       
   104 	def_init_default,
       
   105 	def_destroy,
       
   106 	def_destroy_data,
       
   107 	def_load_bio,
       
   108 	def_dump,
       
   109 	def_is_number,
       
   110 	def_to_int,
       
   111 	def_load
       
   112 	};
       
   113 
       
   114 static CONF_METHOD WIN32_method = {
       
   115 	"WIN32",
       
   116 	def_create,
       
   117 	def_init_WIN32,
       
   118 	def_destroy,
       
   119 	def_destroy_data,
       
   120 	def_load_bio,
       
   121 	def_dump,
       
   122 	def_is_number,
       
   123 	def_to_int,
       
   124 	def_load
       
   125 	};
       
   126 #else
       
   127 GET_STATIC_VAR_FROM_TLS(default_method,conf_def,CONF_METHOD)
       
   128 #define default_method (*GET_WSD_VAR_NAME(default_method,conf_def, s)())
       
   129 const CONF_METHOD temp_s_default_method = {
       
   130 	"OpenSSL default",
       
   131 	def_create,
       
   132 	def_init_default,
       
   133 	def_destroy,
       
   134 	def_destroy_data,
       
   135 	def_load_bio,
       
   136 	def_dump,
       
   137 	def_is_number,
       
   138 	def_to_int,
       
   139 	def_load
       
   140 	};
       
   141 
       
   142 GET_STATIC_VAR_FROM_TLS(WIN32_method,conf_def,CONF_METHOD)
       
   143 #define WIN32_method (*GET_WSD_VAR_NAME(WIN32_method,conf_def, s)())
       
   144 const CONF_METHOD temp_s_WIN32_method = {
       
   145 	"WIN32",
       
   146 	def_create,
       
   147 	def_init_WIN32,
       
   148 	def_destroy,
       
   149 	def_destroy_data,
       
   150 	def_load_bio,
       
   151 	def_dump,
       
   152 	def_is_number,
       
   153 	def_to_int,
       
   154 	def_load
       
   155 	};
       
   156 
       
   157 
       
   158 #endif	
       
   159 
       
   160 EXPORT_C CONF_METHOD *NCONF_default()
       
   161 	{
       
   162 	return &default_method;
       
   163 	}
       
   164 CONF_METHOD *NCONF_WIN32()
       
   165 	{
       
   166 	return &WIN32_method;
       
   167 	}
       
   168 
       
   169 static CONF *def_create(CONF_METHOD *meth)
       
   170 	{
       
   171 	CONF *ret;
       
   172 
       
   173 	ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
       
   174 	if (ret)
       
   175 		if (meth->init(ret) == 0)
       
   176 			{
       
   177 			OPENSSL_free(ret);
       
   178 			ret = NULL;
       
   179 			}
       
   180 	return ret;
       
   181 	}
       
   182 	
       
   183 static int def_init_default(CONF *conf)
       
   184 	{
       
   185 	if (conf == NULL)
       
   186 		return 0;
       
   187 
       
   188 	conf->meth = &default_method;
       
   189 	conf->meth_data = (void *)CONF_type_default;
       
   190 	conf->data = NULL;
       
   191 
       
   192 	return 1;
       
   193 	}
       
   194 
       
   195 static int def_init_WIN32(CONF *conf)
       
   196 	{
       
   197 	if (conf == NULL)
       
   198 		return 0;
       
   199 
       
   200 	conf->meth = &WIN32_method;
       
   201 	conf->meth_data = (void *)CONF_type_win32;
       
   202 	conf->data = NULL;
       
   203 
       
   204 	return 1;
       
   205 	}
       
   206 
       
   207 static int def_destroy(CONF *conf)
       
   208 	{
       
   209 	if (def_destroy_data(conf))
       
   210 		{
       
   211 		OPENSSL_free(conf);
       
   212 		return 1;
       
   213 		}
       
   214 	return 0;
       
   215 	}
       
   216 
       
   217 static int def_destroy_data(CONF *conf)
       
   218 	{
       
   219 	if (conf == NULL)
       
   220 		return 0;
       
   221 	_CONF_free_data(conf);
       
   222 	return 1;
       
   223 	}
       
   224 
       
   225 static int def_load(CONF *conf, const char *name, long *line)
       
   226 	{
       
   227 	int ret;
       
   228 	BIO *in=NULL;
       
   229 
       
   230 #ifdef OPENSSL_SYS_VMS
       
   231 	in=BIO_new_file(name, "r");
       
   232 #else
       
   233 	in=BIO_new_file(name, "rb");
       
   234 #endif
       
   235 	if (in == NULL)
       
   236 		{
       
   237 		if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
       
   238 			CONFerr(CONF_F_DEF_LOAD,CONF_R_NO_SUCH_FILE);
       
   239 		else
       
   240 			CONFerr(CONF_F_DEF_LOAD,ERR_R_SYS_LIB);
       
   241 		return 0;
       
   242 		}
       
   243 
       
   244 	ret = def_load_bio(conf, in, line);
       
   245 	BIO_free(in);
       
   246 
       
   247 	return ret;
       
   248 	}
       
   249 
       
   250 static int def_load_bio(CONF *conf, BIO *in, long *line)
       
   251 	{
       
   252 /* The macro BUFSIZE conflicts with a system macro in VxWorks */
       
   253 #define CONFBUFSIZE	512
       
   254 	int bufnum=0,i,ii;
       
   255 	BUF_MEM *buff=NULL;
       
   256 	char *s,*p,*end;
       
   257 	int again,n;
       
   258 	long eline=0;
       
   259 	char btmp[DECIMAL_SIZE(eline)+1];
       
   260 	CONF_VALUE *v=NULL,*tv;
       
   261 	CONF_VALUE *sv=NULL;
       
   262 	char *section=NULL,*buf;
       
   263 	STACK_OF(CONF_VALUE) *section_sk=NULL,*ts;
       
   264 	char *start,*psection,*pname;
       
   265 	void *h = (void *)(conf->data);
       
   266 
       
   267 	if ((buff=BUF_MEM_new()) == NULL)
       
   268 		{
       
   269 		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
       
   270 		goto err;
       
   271 		}
       
   272 
       
   273 	section=(char *)OPENSSL_malloc(10);
       
   274 	if (section == NULL)
       
   275 		{
       
   276 		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
       
   277 		goto err;
       
   278 		}
       
   279 	BUF_strlcpy(section,"default",10);
       
   280 
       
   281 	if (_CONF_new_data(conf) == 0)
       
   282 		{
       
   283 		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
       
   284 		goto err;
       
   285 		}
       
   286 
       
   287 	sv=_CONF_new_section(conf,section);
       
   288 	if (sv == NULL)
       
   289 		{
       
   290 		CONFerr(CONF_F_DEF_LOAD_BIO,
       
   291 					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
       
   292 		goto err;
       
   293 		}
       
   294 	section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
       
   295 
       
   296 	bufnum=0;
       
   297 	again=0;
       
   298 	for (;;)
       
   299 		{
       
   300 		if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE))
       
   301 			{
       
   302 			CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
       
   303 			goto err;
       
   304 			}
       
   305 		p= &(buff->data[bufnum]);
       
   306 		*p='\0';
       
   307 		BIO_gets(in, p, CONFBUFSIZE-1);
       
   308 		p[CONFBUFSIZE-1]='\0';
       
   309 		ii=i=strlen(p);
       
   310 		if (i == 0 && !again) break;
       
   311 		again=0;
       
   312 		while (i > 0)
       
   313 			{
       
   314 			if ((p[i-1] != '\r') && (p[i-1] != '\n'))
       
   315 				break;
       
   316 			else
       
   317 				i--;
       
   318 			}
       
   319 		/* we removed some trailing stuff so there is a new
       
   320 		 * line on the end. */
       
   321 		if (ii && i == ii)
       
   322 			again=1; /* long line */
       
   323 		else
       
   324 			{
       
   325 			p[i]='\0';
       
   326 			eline++; /* another input line */
       
   327 			}
       
   328 
       
   329 		/* we now have a line with trailing \r\n removed */
       
   330 
       
   331 		/* i is the number of bytes */
       
   332 		bufnum+=i;
       
   333 
       
   334 		v=NULL;
       
   335 		/* check for line continuation */
       
   336 		if (bufnum >= 1)
       
   337 			{
       
   338 			/* If we have bytes and the last char '\\' and
       
   339 			 * second last char is not '\\' */
       
   340 			p= &(buff->data[bufnum-1]);
       
   341 			if (IS_ESC(conf,p[0]) &&
       
   342 				((bufnum <= 1) || !IS_ESC(conf,p[-1])))
       
   343 				{
       
   344 				bufnum--;
       
   345 				again=1;
       
   346 				}
       
   347 			}
       
   348 		if (again) continue;
       
   349 		bufnum=0;
       
   350 		buf=buff->data;
       
   351 
       
   352 		clear_comments(conf, buf);
       
   353 		n=strlen(buf);
       
   354 		s=eat_ws(conf, buf);
       
   355 		if (IS_EOF(conf,*s)) continue; /* blank line */
       
   356 		if (*s == '[')
       
   357 			{
       
   358 			char *ss;
       
   359 
       
   360 			s++;
       
   361 			start=eat_ws(conf, s);
       
   362 			ss=start;
       
   363 again:
       
   364 			end=eat_alpha_numeric(conf, ss);
       
   365 			p=eat_ws(conf, end);
       
   366 			if (*p != ']')
       
   367 				{
       
   368 				if (*p != '\0')
       
   369 					{
       
   370 					ss=p;
       
   371 					goto again;
       
   372 					}
       
   373 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   374 					CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
       
   375 				goto err;
       
   376 				}
       
   377 			*end='\0';
       
   378 			if (!str_copy(conf,NULL,&section,start)) goto err;
       
   379 			if ((sv=_CONF_get_section(conf,section)) == NULL)
       
   380 				sv=_CONF_new_section(conf,section);
       
   381 			if (sv == NULL)
       
   382 				{
       
   383 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   384 					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
       
   385 				goto err;
       
   386 				}
       
   387 			section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
       
   388 			continue;
       
   389 			}
       
   390 		else
       
   391 			{
       
   392 			pname=s;
       
   393 			psection=NULL;
       
   394 			end=eat_alpha_numeric(conf, s);
       
   395 			if ((end[0] == ':') && (end[1] == ':'))
       
   396 				{
       
   397 				*end='\0';
       
   398 				end+=2;
       
   399 				psection=pname;
       
   400 				pname=end;
       
   401 				end=eat_alpha_numeric(conf, end);
       
   402 				}
       
   403 			p=eat_ws(conf, end);
       
   404 			if (*p != '=')
       
   405 				{
       
   406 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   407 						CONF_R_MISSING_EQUAL_SIGN);
       
   408 				goto err;
       
   409 				}
       
   410 			*end='\0';
       
   411 			p++;
       
   412 			start=eat_ws(conf, p);
       
   413 			while (!IS_EOF(conf,*p))
       
   414 				p++;
       
   415 			p--;
       
   416 			while ((p != start) && (IS_WS(conf,*p)))
       
   417 				p--;
       
   418 			p++;
       
   419 			*p='\0';
       
   420 
       
   421 			if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
       
   422 				{
       
   423 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   424 							ERR_R_MALLOC_FAILURE);
       
   425 				goto err;
       
   426 				}
       
   427 			if (psection == NULL) psection=section;
       
   428 			v->name=(char *)OPENSSL_malloc(strlen(pname)+1);
       
   429 			v->value=NULL;
       
   430 			if (v->name == NULL)
       
   431 				{
       
   432 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   433 							ERR_R_MALLOC_FAILURE);
       
   434 				goto err;
       
   435 				}
       
   436 			BUF_strlcpy(v->name,pname,strlen(pname)+1);
       
   437 			if (!str_copy(conf,psection,&(v->value),start)) goto err;
       
   438 
       
   439 			if (strcmp(psection,section) != 0)
       
   440 				{
       
   441 				if ((tv=_CONF_get_section(conf,psection))
       
   442 					== NULL)
       
   443 					tv=_CONF_new_section(conf,psection);
       
   444 				if (tv == NULL)
       
   445 					{
       
   446 					CONFerr(CONF_F_DEF_LOAD_BIO,
       
   447 					   CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
       
   448 					goto err;
       
   449 					}
       
   450 				ts=(STACK_OF(CONF_VALUE) *)tv->value;
       
   451 				}
       
   452 			else
       
   453 				{
       
   454 				tv=sv;
       
   455 				ts=section_sk;
       
   456 				}
       
   457 #if 1
       
   458 			if (_CONF_add_string(conf, tv, v) == 0)
       
   459 				{
       
   460 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   461 							ERR_R_MALLOC_FAILURE);
       
   462 				goto err;
       
   463 				}
       
   464 #else
       
   465 			v->section=tv->section;	
       
   466 			if (!sk_CONF_VALUE_push(ts,v))
       
   467 				{
       
   468 				CONFerr(CONF_F_DEF_LOAD_BIO,
       
   469 							ERR_R_MALLOC_FAILURE);
       
   470 				goto err;
       
   471 				}
       
   472 			vv=(CONF_VALUE *)lh_insert(conf->data,v);
       
   473 			if (vv != NULL)
       
   474 				{
       
   475 				sk_CONF_VALUE_delete_ptr(ts,vv);
       
   476 				OPENSSL_free(vv->name);
       
   477 				OPENSSL_free(vv->value);
       
   478 				OPENSSL_free(vv);
       
   479 				}
       
   480 #endif
       
   481 			v=NULL;
       
   482 			}
       
   483 		}
       
   484 	if (buff != NULL) BUF_MEM_free(buff);
       
   485 	if (section != NULL) OPENSSL_free(section);
       
   486 	return(1);
       
   487 err:
       
   488 	if (buff != NULL) BUF_MEM_free(buff);
       
   489 	if (section != NULL) OPENSSL_free(section);
       
   490 	if (line != NULL) *line=eline;
       
   491 	BIO_snprintf(btmp,sizeof btmp,"%ld",eline);
       
   492 	ERR_add_error_data(2,"line ",btmp);
       
   493 	if ((h != conf->data) && (conf->data != NULL))
       
   494 		{
       
   495 		CONF_free(conf->data);
       
   496 		conf->data=NULL;
       
   497 		}
       
   498 	if (v != NULL)
       
   499 		{
       
   500 		if (v->name != NULL) OPENSSL_free(v->name);
       
   501 		if (v->value != NULL) OPENSSL_free(v->value);
       
   502 		if (v != NULL) OPENSSL_free(v);
       
   503 		}
       
   504 	return(0);
       
   505 	}
       
   506 
       
   507 static void clear_comments(CONF *conf, char *p)
       
   508 	{
       
   509 	char *to;
       
   510 
       
   511 	to=p;
       
   512 	for (;;)
       
   513 		{
       
   514 		if (IS_FCOMMENT(conf,*p))
       
   515 			{
       
   516 			*p='\0';
       
   517 			return;
       
   518 			}
       
   519 		if (!IS_WS(conf,*p))
       
   520 			{
       
   521 			break;
       
   522 			}
       
   523 		p++;
       
   524 		}
       
   525 
       
   526 	for (;;)
       
   527 		{
       
   528 		if (IS_COMMENT(conf,*p))
       
   529 			{
       
   530 			*p='\0';
       
   531 			return;
       
   532 			}
       
   533 		if (IS_DQUOTE(conf,*p))
       
   534 			{
       
   535 			p=scan_dquote(conf, p);
       
   536 			continue;
       
   537 			}
       
   538 		if (IS_QUOTE(conf,*p))
       
   539 			{
       
   540 			p=scan_quote(conf, p);
       
   541 			continue;
       
   542 			}
       
   543 		if (IS_ESC(conf,*p))
       
   544 			{
       
   545 			p=scan_esc(conf,p);
       
   546 			continue;
       
   547 			}
       
   548 		if (IS_EOF(conf,*p))
       
   549 			return;
       
   550 		else
       
   551 			p++;
       
   552 		}
       
   553 	}
       
   554 
       
   555 static int str_copy(CONF *conf, char *section, char **pto, char *from)
       
   556 	{
       
   557 	int q,r,rr=0,to=0,len=0;
       
   558 	char *s,*e,*rp,*p,*rrp,*np,*cp,v;
       
   559 	BUF_MEM *buf;
       
   560 
       
   561 	if ((buf=BUF_MEM_new()) == NULL) return(0);
       
   562 
       
   563 	len=strlen(from)+1;
       
   564 	if (!BUF_MEM_grow(buf,len)) goto err;
       
   565 
       
   566 	for (;;)
       
   567 		{
       
   568 		if (IS_QUOTE(conf,*from))
       
   569 			{
       
   570 			q= *from;
       
   571 			from++;
       
   572 			while (!IS_EOF(conf,*from) && (*from != q))
       
   573 				{
       
   574 				if (IS_ESC(conf,*from))
       
   575 					{
       
   576 					from++;
       
   577 					if (IS_EOF(conf,*from)) break;
       
   578 					}
       
   579 				buf->data[to++]= *(from++);
       
   580 				}
       
   581 			if (*from == q) from++;
       
   582 			}
       
   583 		else if (IS_DQUOTE(conf,*from))
       
   584 			{
       
   585 			q= *from;
       
   586 			from++;
       
   587 			while (!IS_EOF(conf,*from))
       
   588 				{
       
   589 				if (*from == q)
       
   590 					{
       
   591 					if (*(from+1) == q)
       
   592 						{
       
   593 						from++;
       
   594 						}
       
   595 					else
       
   596 						{
       
   597 						break;
       
   598 						}
       
   599 					}
       
   600 				buf->data[to++]= *(from++);
       
   601 				}
       
   602 			if (*from == q) from++;
       
   603 			}
       
   604 		else if (IS_ESC(conf,*from))
       
   605 			{
       
   606 			from++;
       
   607 			v= *(from++);
       
   608 			if (IS_EOF(conf,v)) break;
       
   609 			else if (v == 'r') v='\r';
       
   610 			else if (v == 'n') v='\n';
       
   611 			else if (v == 'b') v='\b';
       
   612 			else if (v == 't') v='\t';
       
   613 			buf->data[to++]= v;
       
   614 			}
       
   615 		else if (IS_EOF(conf,*from))
       
   616 			break;
       
   617 		else if (*from == '$')
       
   618 			{
       
   619 			/* try to expand it */
       
   620 			rrp=NULL;
       
   621 			s= &(from[1]);
       
   622 			if (*s == '{')
       
   623 				q='}';
       
   624 			else if (*s == '(')
       
   625 				q=')';
       
   626 			else q=0;
       
   627 
       
   628 			if (q) s++;
       
   629 			cp=section;
       
   630 			e=np=s;
       
   631 			while (IS_ALPHA_NUMERIC(conf,*e))
       
   632 				e++;
       
   633 			if ((e[0] == ':') && (e[1] == ':'))
       
   634 				{
       
   635 				cp=np;
       
   636 				rrp=e;
       
   637 				rr= *e;
       
   638 				*rrp='\0';
       
   639 				e+=2;
       
   640 				np=e;
       
   641 				while (IS_ALPHA_NUMERIC(conf,*e))
       
   642 					e++;
       
   643 				}
       
   644 			r= *e;
       
   645 			*e='\0';
       
   646 			rp=e;
       
   647 			if (q)
       
   648 				{
       
   649 				if (r != q)
       
   650 					{
       
   651 					CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE);
       
   652 					goto err;
       
   653 					}
       
   654 				e++;
       
   655 				}
       
   656 			/* So at this point we have
       
   657 			 * np which is the start of the name string which is
       
   658 			 *   '\0' terminated. 
       
   659 			 * cp which is the start of the section string which is
       
   660 			 *   '\0' terminated.
       
   661 			 * e is the 'next point after'.
       
   662 			 * r and rr are the chars replaced by the '\0'
       
   663 			 * rp and rrp is where 'r' and 'rr' came from.
       
   664 			 */
       
   665 			p=_CONF_get_string(conf,cp,np);
       
   666 			if (rrp != NULL) *rrp=rr;
       
   667 			*rp=r;
       
   668 			if (p == NULL)
       
   669 				{
       
   670 				CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE);
       
   671 				goto err;
       
   672 				}
       
   673 			BUF_MEM_grow_clean(buf,(strlen(p)+buf->length-(e-from)));
       
   674 			while (*p)
       
   675 				buf->data[to++]= *(p++);
       
   676 
       
   677 			/* Since we change the pointer 'from', we also have
       
   678 			   to change the perceived length of the string it
       
   679 			   points at.  /RL */
       
   680 			len -= e-from;
       
   681 			from=e;
       
   682 
       
   683 			/* In case there were no braces or parenthesis around
       
   684 			   the variable reference, we have to put back the
       
   685 			   character that was replaced with a '\0'.  /RL */
       
   686 			*rp = r;
       
   687 			}
       
   688 		else
       
   689 			buf->data[to++]= *(from++);
       
   690 		}
       
   691 	buf->data[to]='\0';
       
   692 	if (*pto != NULL) OPENSSL_free(*pto);
       
   693 	*pto=buf->data;
       
   694 	OPENSSL_free(buf);
       
   695 	return(1);
       
   696 err:
       
   697 	if (buf != NULL) BUF_MEM_free(buf);
       
   698 	return(0);
       
   699 	}
       
   700 
       
   701 static char *eat_ws(CONF *conf, char *p)
       
   702 	{
       
   703 	while (IS_WS(conf,*p) && (!IS_EOF(conf,*p)))
       
   704 		p++;
       
   705 	return(p);
       
   706 	}
       
   707 
       
   708 static char *eat_alpha_numeric(CONF *conf, char *p)
       
   709 	{
       
   710 	for (;;)
       
   711 		{
       
   712 		if (IS_ESC(conf,*p))
       
   713 			{
       
   714 			p=scan_esc(conf,p);
       
   715 			continue;
       
   716 			}
       
   717 		if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p))
       
   718 			return(p);
       
   719 		p++;
       
   720 		}
       
   721 	}
       
   722 
       
   723 static char *scan_quote(CONF *conf, char *p)
       
   724 	{
       
   725 	int q= *p;
       
   726 
       
   727 	p++;
       
   728 	while (!(IS_EOF(conf,*p)) && (*p != q))
       
   729 		{
       
   730 		if (IS_ESC(conf,*p))
       
   731 			{
       
   732 			p++;
       
   733 			if (IS_EOF(conf,*p)) return(p);
       
   734 			}
       
   735 		p++;
       
   736 		}
       
   737 	if (*p == q) p++;
       
   738 	return(p);
       
   739 	}
       
   740 
       
   741 
       
   742 static char *scan_dquote(CONF *conf, char *p)
       
   743 	{
       
   744 	int q= *p;
       
   745 
       
   746 	p++;
       
   747 	while (!(IS_EOF(conf,*p)))
       
   748 		{
       
   749 		if (*p == q)
       
   750 			{
       
   751 			if (*(p+1) == q)
       
   752 				{
       
   753 				p++;
       
   754 				}
       
   755 			else
       
   756 				{
       
   757 				break;
       
   758 				}
       
   759 			}
       
   760 		p++;
       
   761 		}
       
   762 	if (*p == q) p++;
       
   763 	return(p);
       
   764 	}
       
   765 
       
   766 static void dump_value(CONF_VALUE *a, BIO *out)
       
   767 	{
       
   768 	if (a->name)
       
   769 		BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
       
   770 	else
       
   771 		BIO_printf(out, "[[%s]]\n", a->section);
       
   772 	}
       
   773 
       
   774 static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE *, BIO *)
       
   775 
       
   776 static int def_dump(const CONF *conf, BIO *out)
       
   777 	{
       
   778 	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), out);
       
   779 	return 1;
       
   780 	}
       
   781 
       
   782 static int def_is_number(const CONF *conf, char c)
       
   783 	{
       
   784 	return IS_NUMBER(conf,c);
       
   785 	}
       
   786 
       
   787 static int def_to_int(const CONF *conf, char c)
       
   788 	{
       
   789 	return c - '0';
       
   790 	}
       
   791