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