1193323Sed/* crypto/conf/conf.c */ 2193323Sed/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * This package is an SSL implementation written 6193323Sed * by Eric Young (eay@cryptsoft.com). 7193323Sed * The implementation was written so as to conform with Netscapes SSL. 8193323Sed * 9193323Sed * This library is free for commercial and non-commercial use as long as 10193323Sed * the following conditions are aheared to. The following conditions 11193323Sed * apply to all code found in this distribution, be it the RC4, RSA, 12193323Sed * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13193323Sed * included with this distribution is covered by the same copyright terms 14193323Sed * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15193323Sed * 16193323Sed * Copyright remains Eric Young's, and as such any Copyright notices in 17193323Sed * the code are not to be removed. 18193323Sed * If this package is used in a product, Eric Young should be given attribution 19249423Sdim * as the author of the parts of the library used. 20193323Sed * This can be in the form of a textual message at program startup or 21193323Sed * in documentation (online or textual) provided with the package. 22249423Sdim * 23249423Sdim * Redistribution and use in source and binary forms, with or without 24193323Sed * modification, are permitted provided that the following conditions 25193323Sed * are met: 26193323Sed * 1. Redistributions of source code must retain the copyright 27193323Sed * notice, this list of conditions and the following disclaimer. 28193323Sed * 2. Redistributions in binary form must reproduce the above copyright 29193323Sed * notice, this list of conditions and the following disclaimer in the 30193323Sed * documentation and/or other materials provided with the distribution. 31193323Sed * 3. All advertising materials mentioning features or use of this software 32208599Srdivacky * must display the following acknowledgement: 33249423Sdim * "This product includes cryptographic software written by 34218893Sdim * Eric Young (eay@cryptsoft.com)" 35193323Sed * The word 'cryptographic' can be left out if the rouines from the library 36193323Sed * being used are not cryptographic related :-). 37193323Sed * 4. If you include any Windows specific code (or a derivative thereof) from 38249423Sdim * the apps directory (application code) you must include an acknowledgement: 39249423Sdim * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40234353Sdim * 41193323Sed * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42234353Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43234353Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44226633Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45193323Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46239462Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47239462Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49249423Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50226633Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51193323Sed * SUCH DAMAGE. 52193323Sed * 53226633Sdim * The licence and distribution terms for any publically available version or 54193323Sed * derivative of this code cannot be changed. i.e. this code cannot simply be 55193323Sed * copied and put under another distribution licence 56193323Sed * [including the GNU Public Licence.] 57226633Sdim */ 58193323Sed 59193323Sed/* Part of the code in here was originally in conf.c, which is now removed */ 60193323Sed 61226633Sdim#include <stdio.h> 62226633Sdim#include <string.h> 63193323Sed#include "cryptlib.h" 64193323Sed#include <openssl/stack.h> 65193323Sed#include <openssl/lhash.h> 66226633Sdim#include <openssl/conf.h> 67193323Sed#include <openssl/conf_api.h> 68193323Sed#include "conf_def.h" 69193323Sed#include <openssl/buffer.h> 70193323Sed#include <openssl/err.h> 71226633Sdim 72193323Sedstatic char *eat_ws(CONF *conf, char *p); 73193323Sedstatic char *eat_alpha_numeric(CONF *conf, char *p); 74193323Sedstatic void clear_comments(CONF *conf, char *p); 75207618Srdivackystatic int str_copy(CONF *conf,char *section,char **to, char *from); 76193323Sedstatic char *scan_quote(CONF *conf, char *p); 77226633Sdimstatic char *scan_dquote(CONF *conf, char *p); 78193323Sed#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) 79193323Sed 80210299Sedstatic CONF *def_create(CONF_METHOD *meth); 81210299Sedstatic int def_init_default(CONF *conf); 82226633Sdimstatic int def_init_WIN32(CONF *conf); 83210299Sedstatic int def_destroy(CONF *conf); 84210299Sedstatic int def_destroy_data(CONF *conf); 85226633Sdimstatic int def_load(CONF *conf, const char *name, long *eline); 86226633Sdimstatic int def_load_bio(CONF *conf, BIO *bp, long *eline); 87226633Sdimstatic int def_dump(const CONF *conf, BIO *bp); 88226633Sdimstatic int def_is_number(const CONF *conf, char c); 89226633Sdimstatic int def_to_int(const CONF *conf, char c); 90226633Sdim 91226633Sdimconst char CONF_def_version[]="CONF_def" OPENSSL_VERSION_PTEXT; 92226633Sdim 93226633Sdimstatic CONF_METHOD default_method = { 94226633Sdim "OpenSSL default", 95226633Sdim def_create, 96226633Sdim def_init_default, 97226633Sdim def_destroy, 98226633Sdim def_destroy_data, 99226633Sdim def_load_bio, 100226633Sdim def_dump, 101226633Sdim def_is_number, 102193323Sed def_to_int, 103193323Sed def_load 104198090Srdivacky }; 105218893Sdim 106234353Sdimstatic CONF_METHOD WIN32_method = { 107193323Sed "WIN32", 108193323Sed def_create, 109193323Sed def_init_WIN32, 110198090Srdivacky def_destroy, 111193323Sed def_destroy_data, 112193323Sed def_load_bio, 113193323Sed def_dump, 114193323Sed def_is_number, 115193323Sed def_to_int, 116193323Sed def_load 117193323Sed }; 118193323Sed 119218893SdimCONF_METHOD *NCONF_default() 120193323Sed { 121193323Sed return &default_method; 122193323Sed } 123203954SrdivackyCONF_METHOD *NCONF_WIN32() 124226633Sdim { 125226633Sdim return &WIN32_method; 126226633Sdim } 127193323Sed 128193323Sedstatic CONF *def_create(CONF_METHOD *meth) 129226633Sdim { 130223017Sdim CONF *ret; 131223017Sdim 132226633Sdim ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); 133226633Sdim if (ret) 134223017Sdim if (meth->init(ret) == 0) 135223017Sdim { 136193323Sed OPENSSL_free(ret); 137226633Sdim ret = NULL; 138226633Sdim } 139226633Sdim return ret; 140193323Sed } 141193323Sed 142226633Sdimstatic int def_init_default(CONF *conf) 143223017Sdim { 144223017Sdim if (conf == NULL) 145226633Sdim return 0; 146223017Sdim 147223017Sdim conf->meth = &default_method; 148226633Sdim conf->meth_data = CONF_type_default; 149226633Sdim conf->data = NULL; 150226633Sdim 151234353Sdim return 1; 152226633Sdim } 153193323Sed 154198090Srdivackystatic int def_init_WIN32(CONF *conf) 155239462Sdim { 156239462Sdim if (conf == NULL) 157239462Sdim return 0; 158239462Sdim 159239462Sdim conf->meth = &WIN32_method; 160239462Sdim conf->meth_data = (void *)CONF_type_win32; 161239462Sdim conf->data = NULL; 162239462Sdim 163239462Sdim return 1; 164239462Sdim } 165239462Sdim 166239462Sdimstatic int def_destroy(CONF *conf) 167226633Sdim { 168226633Sdim if (def_destroy_data(conf)) 169226633Sdim { 170226633Sdim OPENSSL_free(conf); 171226633Sdim return 1; 172193323Sed } 173193323Sed return 0; 174193323Sed } 175193323Sed 176193323Sedstatic int def_destroy_data(CONF *conf) 177193323Sed { 178193323Sed if (conf == NULL) 179198090Srdivacky return 0; 180224145Sdim _CONF_free_data(conf); 181224145Sdim return 1; 182224145Sdim } 183224145Sdim 184224145Sdimstatic int def_load(CONF *conf, const char *name, long *line) 185224145Sdim { 186224145Sdim int ret; 187193323Sed BIO *in=NULL; 188224145Sdim 189224145Sdim#ifdef OPENSSL_SYS_VMS 190224145Sdim in=BIO_new_file(name, "r"); 191193323Sed#else 192224145Sdim in=BIO_new_file(name, "rb"); 193218893Sdim#endif 194249423Sdim if (in == NULL) 195234353Sdim { 196193323Sed if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) 197193323Sed CONFerr(CONF_F_DEF_LOAD,CONF_R_NO_SUCH_FILE); 198193323Sed else 199224145Sdim CONFerr(CONF_F_DEF_LOAD,ERR_R_SYS_LIB); 200224145Sdim return 0; 201224145Sdim } 202224145Sdim 203224145Sdim ret = def_load_bio(conf, in, line); 204224145Sdim BIO_free(in); 205193323Sed 206234353Sdim return ret; 207234353Sdim } 208234353Sdim 209234982Sdimstatic int def_load_bio(CONF *conf, BIO *in, long *line) 210234353Sdim { 211234353Sdim/* The macro BUFSIZE conflicts with a system macro in VxWorks */ 212234353Sdim#define CONFBUFSIZE 512 213193323Sed int bufnum=0,i,ii; 214193323Sed BUF_MEM *buff=NULL; 215193323Sed char *s,*p,*end; 216193323Sed int again; 217193323Sed long eline=0; 218193323Sed char btmp[DECIMAL_SIZE(eline)+1]; 219224145Sdim CONF_VALUE *v=NULL,*tv; 220193323Sed CONF_VALUE *sv=NULL; 221193323Sed char *section=NULL,*buf; 222193323Sed char *start,*psection,*pname; 223224145Sdim void *h = (void *)(conf->data); 224208599Srdivacky 225243830Sdim if ((buff=BUF_MEM_new()) == NULL) 226243830Sdim { 227243830Sdim CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB); 228193323Sed goto err; 229193323Sed } 230193323Sed 231224145Sdim section=(char *)OPENSSL_malloc(10); 232193323Sed if (section == NULL) 233193323Sed { 234243830Sdim CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE); 235243830Sdim goto err; 236193323Sed } 237193323Sed BUF_strlcpy(section,"default",10); 238193323Sed 239218893Sdim if (_CONF_new_data(conf) == 0) 240218893Sdim { 241218893Sdim CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE); 242218893Sdim goto err; 243218893Sdim } 244218893Sdim 245218893Sdim sv=_CONF_new_section(conf,section); 246218893Sdim if (sv == NULL) 247218893Sdim { 248218893Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 249193323Sed CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 250218893Sdim goto err; 251218893Sdim } 252218893Sdim 253218893Sdim bufnum=0; 254218893Sdim again=0; 255218893Sdim for (;;) 256218893Sdim { 257218893Sdim if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE)) 258218893Sdim { 259218893Sdim CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB); 260218893Sdim goto err; 261193323Sed } 262218893Sdim p= &(buff->data[bufnum]); 263218893Sdim *p='\0'; 264218893Sdim BIO_gets(in, p, CONFBUFSIZE-1); 265218893Sdim p[CONFBUFSIZE-1]='\0'; 266218893Sdim ii=i=strlen(p); 267218893Sdim if (i == 0 && !again) break; 268218893Sdim again=0; 269218893Sdim while (i > 0) 270218893Sdim { 271218893Sdim if ((p[i-1] != '\r') && (p[i-1] != '\n')) 272218893Sdim break; 273218893Sdim else 274218893Sdim i--; 275218893Sdim } 276193323Sed /* we removed some trailing stuff so there is a new 277193323Sed * line on the end. */ 278193323Sed if (ii && i == ii) 279218893Sdim again=1; /* long line */ 280218893Sdim else 281193323Sed { 282193323Sed p[i]='\0'; 283193323Sed eline++; /* another input line */ 284193323Sed } 285193323Sed 286218893Sdim /* we now have a line with trailing \r\n removed */ 287218893Sdim 288193323Sed /* i is the number of bytes */ 289193323Sed bufnum+=i; 290218893Sdim 291218893Sdim v=NULL; 292218893Sdim /* check for line continuation */ 293218893Sdim if (bufnum >= 1) 294223017Sdim { 295218893Sdim /* If we have bytes and the last char '\\' and 296218893Sdim * second last char is not '\\' */ 297218893Sdim p= &(buff->data[bufnum-1]); 298218893Sdim if (IS_ESC(conf,p[0]) && 299218893Sdim ((bufnum <= 1) || !IS_ESC(conf,p[-1]))) 300223017Sdim { 301218893Sdim bufnum--; 302218893Sdim again=1; 303210299Sed } 304210299Sed } 305210299Sed if (again) continue; 306210299Sed bufnum=0; 307210299Sed buf=buff->data; 308193323Sed 309239462Sdim clear_comments(conf, buf); 310239462Sdim s=eat_ws(conf, buf); 311239462Sdim if (IS_EOF(conf,*s)) continue; /* blank line */ 312239462Sdim if (*s == '[') 313239462Sdim { 314193323Sed char *ss; 315193323Sed 316193323Sed s++; 317198090Srdivacky start=eat_ws(conf, s); 318193323Sed ss=start; 319193323Sedagain: 320221345Sdim end=eat_alpha_numeric(conf, ss); 321221345Sdim p=eat_ws(conf, end); 322221345Sdim if (*p != ']') 323224145Sdim { 324221345Sdim if (*p != '\0' && ss != p) 325221345Sdim { 326224145Sdim ss=p; 327224145Sdim goto again; 328224145Sdim } 329224145Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 330193323Sed CONF_R_MISSING_CLOSE_SQUARE_BRACKET); 331193323Sed goto err; 332208599Srdivacky } 333208599Srdivacky *end='\0'; 334208599Srdivacky if (!str_copy(conf,NULL,§ion,start)) goto err; 335243830Sdim if ((sv=_CONF_get_section(conf,section)) == NULL) 336243830Sdim sv=_CONF_new_section(conf,section); 337208599Srdivacky if (sv == NULL) 338208599Srdivacky { 339208599Srdivacky CONFerr(CONF_F_DEF_LOAD_BIO, 340243830Sdim CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 341243830Sdim goto err; 342243830Sdim } 343243830Sdim continue; 344243830Sdim } 345243830Sdim else 346243830Sdim { 347243830Sdim pname=s; 348243830Sdim psection=NULL; 349243830Sdim end=eat_alpha_numeric(conf, s); 350243830Sdim if ((end[0] == ':') && (end[1] == ':')) 351243830Sdim { 352243830Sdim *end='\0'; 353243830Sdim end+=2; 354243830Sdim psection=pname; 355243830Sdim pname=end; 356243830Sdim end=eat_alpha_numeric(conf, end); 357243830Sdim } 358243830Sdim p=eat_ws(conf, end); 359243830Sdim if (*p != '=') 360243830Sdim { 361243830Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 362243830Sdim CONF_R_MISSING_EQUAL_SIGN); 363243830Sdim goto err; 364243830Sdim } 365198090Srdivacky *end='\0'; 366198090Srdivacky p++; 367198090Srdivacky start=eat_ws(conf, p); 368224145Sdim while (!IS_EOF(conf,*p)) 369198090Srdivacky p++; 370198090Srdivacky p--; 371239462Sdim while ((p != start) && (IS_WS(conf,*p))) 372239462Sdim p--; 373239462Sdim p++; 374239462Sdim *p='\0'; 375239462Sdim 376239462Sdim if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) 377239462Sdim { 378239462Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 379239462Sdim ERR_R_MALLOC_FAILURE); 380193323Sed goto err; 381193323Sed } 382193323Sed if (psection == NULL) psection=section; 383239462Sdim v->name=(char *)OPENSSL_malloc(strlen(pname)+1); 384239462Sdim v->value=NULL; 385239462Sdim if (v->name == NULL) 386239462Sdim { 387239462Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 388239462Sdim ERR_R_MALLOC_FAILURE); 389239462Sdim goto err; 390239462Sdim } 391193323Sed BUF_strlcpy(v->name,pname,strlen(pname)+1); 392193323Sed if (!str_copy(conf,psection,&(v->value),start)) goto err; 393193323Sed 394234353Sdim if (strcmp(psection,section) != 0) 395234353Sdim { 396249423Sdim if ((tv=_CONF_get_section(conf,psection)) 397193323Sed == NULL) 398193323Sed tv=_CONF_new_section(conf,psection); 399234353Sdim if (tv == NULL) 400234353Sdim { 401234353Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 402234353Sdim CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 403234353Sdim goto err; 404234353Sdim } 405234353Sdim } 406234353Sdim else 407234353Sdim tv=sv; 408234353Sdim#if 1 409234353Sdim if (_CONF_add_string(conf, tv, v) == 0) 410234353Sdim { 411234353Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 412234353Sdim ERR_R_MALLOC_FAILURE); 413234353Sdim goto err; 414234353Sdim } 415234353Sdim#else 416234353Sdim v->section=tv->section; 417234353Sdim if (!sk_CONF_VALUE_push(ts,v)) 418234353Sdim { 419234353Sdim CONFerr(CONF_F_DEF_LOAD_BIO, 420234353Sdim ERR_R_MALLOC_FAILURE); 421193323Sed goto err; 422193323Sed } 423193323Sed vv=(CONF_VALUE *)lh_insert(conf->data,v); 424193323Sed if (vv != NULL) 425193323Sed { 426193323Sed sk_CONF_VALUE_delete_ptr(ts,vv); 427193323Sed OPENSSL_free(vv->name); 428193323Sed OPENSSL_free(vv->value); 429193323Sed OPENSSL_free(vv); 430198090Srdivacky } 431193323Sed#endif 432234353Sdim v=NULL; 433193323Sed } 434193323Sed } 435198090Srdivacky if (buff != NULL) BUF_MEM_free(buff); 436198090Srdivacky if (section != NULL) OPENSSL_free(section); 437198090Srdivacky return(1); 438234353Sdimerr: 439234353Sdim if (buff != NULL) BUF_MEM_free(buff); 440198090Srdivacky if (section != NULL) OPENSSL_free(section); 441198090Srdivacky if (line != NULL) *line=eline; 442239462Sdim BIO_snprintf(btmp,sizeof btmp,"%ld",eline); 443198090Srdivacky ERR_add_error_data(2,"line ",btmp); 444226633Sdim if ((h != conf->data) && (conf->data != NULL)) 445226633Sdim { 446226633Sdim CONF_free(conf->data); 447226633Sdim conf->data=NULL; 448226633Sdim } 449226633Sdim if (v != NULL) 450226633Sdim { 451226633Sdim if (v->name != NULL) OPENSSL_free(v->name); 452226633Sdim if (v->value != NULL) OPENSSL_free(v->value); 453226633Sdim if (v != NULL) OPENSSL_free(v); 454226633Sdim } 455234353Sdim return(0); 456226633Sdim } 457239462Sdim 458239462Sdimstatic void clear_comments(CONF *conf, char *p) 459239462Sdim { 460239462Sdim for (;;) 461226633Sdim { 462210299Sed if (IS_FCOMMENT(conf,*p)) 463210299Sed { 464210299Sed *p='\0'; 465243830Sdim return; 466243830Sdim } 467210299Sed if (!IS_WS(conf,*p)) 468210299Sed { 469210299Sed break; 470210299Sed } 471210299Sed p++; 472210299Sed } 473210299Sed 474210299Sed for (;;) 475210299Sed { 476243830Sdim if (IS_COMMENT(conf,*p)) 477243830Sdim { 478243830Sdim *p='\0'; 479243830Sdim return; 480210299Sed } 481210299Sed if (IS_DQUOTE(conf,*p)) 482243830Sdim { 483243830Sdim p=scan_dquote(conf, p); 484243830Sdim continue; 485243830Sdim } 486243830Sdim if (IS_QUOTE(conf,*p)) 487243830Sdim { 488243830Sdim p=scan_quote(conf, p); 489239462Sdim continue; 490239462Sdim } 491239462Sdim if (IS_ESC(conf,*p)) 492239462Sdim { 493239462Sdim p=scan_esc(conf,p); 494239462Sdim continue; 495239462Sdim } 496239462Sdim if (IS_EOF(conf,*p)) 497239462Sdim return; 498239462Sdim else 499239462Sdim p++; 500239462Sdim } 501239462Sdim } 502239462Sdim 503239462Sdimstatic int str_copy(CONF *conf, char *section, char **pto, char *from) 504239462Sdim { 505239462Sdim int q,r,rr=0,to=0,len=0; 506239462Sdim char *s,*e,*rp,*p,*rrp,*np,*cp,v; 507239462Sdim BUF_MEM *buf; 508239462Sdim 509239462Sdim if ((buf=BUF_MEM_new()) == NULL) return(0); 510239462Sdim 511239462Sdim len=strlen(from)+1; 512239462Sdim if (!BUF_MEM_grow(buf,len)) goto err; 513239462Sdim 514239462Sdim for (;;) 515239462Sdim { 516239462Sdim if (IS_QUOTE(conf,*from)) 517193323Sed { 518193323Sed q= *from; 519193323Sed from++; 520193323Sed while (!IS_EOF(conf,*from) && (*from != q)) 521193323Sed { 522193323Sed if (IS_ESC(conf,*from)) 523193323Sed { 524193323Sed from++; 525193323Sed if (IS_EOF(conf,*from)) break; 526193323Sed } 527193323Sed buf->data[to++]= *(from++); 528193323Sed } 529198090Srdivacky if (*from == q) from++; 530193323Sed } 531224145Sdim else if (IS_DQUOTE(conf,*from)) 532193323Sed { 533210299Sed q= *from; 534210299Sed from++; 535193323Sed while (!IS_EOF(conf,*from)) 536193323Sed { 537226633Sdim if (*from == q) 538226633Sdim { 539226633Sdim if (*(from+1) == q) 540226633Sdim { 541226633Sdim from++; 542226633Sdim } 543193323Sed else 544198090Srdivacky { 545198090Srdivacky break; 546239462Sdim } 547239462Sdim } 548234353Sdim buf->data[to++]= *(from++); 549193323Sed } 550193323Sed if (*from == q) from++; 551193323Sed } 552221345Sdim else if (IS_ESC(conf,*from)) 553221345Sdim { 554221345Sdim from++; 555221345Sdim v= *(from++); 556193323Sed if (IS_EOF(conf,v)) break; 557193323Sed else if (v == 'r') v='\r'; 558221345Sdim else if (v == 'n') v='\n'; 559193323Sed else if (v == 'b') v='\b'; 560193323Sed else if (v == 't') v='\t'; 561221345Sdim buf->data[to++]= v; 562221345Sdim } 563221345Sdim else if (IS_EOF(conf,*from)) 564221345Sdim break; 565221345Sdim else if (*from == '$') 566221345Sdim { 567221345Sdim /* try to expand it */ 568221345Sdim rrp=NULL; 569221345Sdim s= &(from[1]); 570221345Sdim if (*s == '{') 571221345Sdim q='}'; 572221345Sdim else if (*s == '(') 573221345Sdim q=')'; 574221345Sdim else q=0; 575234353Sdim 576234353Sdim if (q) s++; 577234353Sdim cp=section; 578221345Sdim e=np=s; 579221345Sdim while (IS_ALPHA_NUMERIC(conf,*e)) 580221345Sdim e++; 581221345Sdim if ((e[0] == ':') && (e[1] == ':')) 582221345Sdim { 583249423Sdim cp=np; 584234353Sdim rrp=e; 585234353Sdim rr= *e; 586234353Sdim *rrp='\0'; 587249423Sdim e+=2; 588249423Sdim np=e; 589249423Sdim while (IS_ALPHA_NUMERIC(conf,*e)) 590234353Sdim e++; 591234353Sdim } 592234353Sdim r= *e; 593239462Sdim *e='\0'; 594239462Sdim rp=e; 595239462Sdim if (q) 596234353Sdim { 597234353Sdim if (r != q) 598234353Sdim { 599234353Sdim CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE); 600234353Sdim goto err; 601234353Sdim } 602234353Sdim e++; 603234353Sdim } 604234353Sdim /* So at this point we have 605249423Sdim * np which is the start of the name string which is 606249423Sdim * '\0' terminated. 607249423Sdim * cp which is the start of the section string which is 608249423Sdim * '\0' terminated. 609249423Sdim * e is the 'next point after'. 610249423Sdim * r and rr are the chars replaced by the '\0' 611249423Sdim * rp and rrp is where 'r' and 'rr' came from. 612249423Sdim */ 613224145Sdim p=_CONF_get_string(conf,cp,np); 614249423Sdim if (rrp != NULL) *rrp=rr; 615249423Sdim *rp=r; 616249423Sdim if (p == NULL) 617249423Sdim { 618249423Sdim CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE); 619249423Sdim goto err; 620249423Sdim } 621249423Sdim len = strlen(p)+len-(e-from); 622249423Sdim BUF_MEM_grow_clean(buf, len); 623249423Sdim while (*p) 624249423Sdim buf->data[to++]= *(p++); 625249423Sdim 626249423Sdim /* Since we change the pointer 'from', we also have 627249423Sdim to change the perceived length of the string it 628194612Sed points at. /RL */ 629221345Sdim len -= e-from; 630221345Sdim from=e; 631221345Sdim 632221345Sdim /* In case there were no braces or parenthesis around 633221345Sdim the variable reference, we have to put back the 634221345Sdim character that was replaced with a '\0'. /RL */ 635221345Sdim *rp = r; 636221345Sdim } 637194612Sed else 638194612Sed buf->data[to++]= *(from++); 639194612Sed } 640194612Sed buf->data[to]='\0'; 641194612Sed if (*pto != NULL) OPENSSL_free(*pto); 642194612Sed *pto=buf->data; 643194612Sed OPENSSL_free(buf); 644194612Sed return(1); 645194612Sederr: 646194612Sed if (buf != NULL) BUF_MEM_free(buf); 647194612Sed return(0); 648193323Sed } 649193323Sed 650193323Sedstatic char *eat_ws(CONF *conf, char *p) 651193323Sed { 652193323Sed while (IS_WS(conf,*p) && (!IS_EOF(conf,*p))) 653198090Srdivacky p++; 654221345Sdim return(p); 655221345Sdim } 656221345Sdim 657221345Sdimstatic char *eat_alpha_numeric(CONF *conf, char *p) 658221345Sdim { 659221345Sdim for (;;) 660221345Sdim { 661198090Srdivacky if (IS_ESC(conf,*p)) 662198090Srdivacky { 663198090Srdivacky p=scan_esc(conf,p); 664198090Srdivacky continue; 665198090Srdivacky } 666198090Srdivacky if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p)) 667212904Sdim return(p); 668212904Sdim p++; 669212904Sdim } 670212904Sdim } 671212904Sdim 672212904Sdimstatic char *scan_quote(CONF *conf, char *p) 673212904Sdim { 674198090Srdivacky int q= *p; 675198090Srdivacky 676198090Srdivacky p++; 677198090Srdivacky while (!(IS_EOF(conf,*p)) && (*p != q)) 678198090Srdivacky { 679198090Srdivacky if (IS_ESC(conf,*p)) 680212904Sdim { 681198090Srdivacky p++; 682198090Srdivacky if (IS_EOF(conf,*p)) return(p); 683198090Srdivacky } 684198090Srdivacky p++; 685239462Sdim } 686239462Sdim if (*p == q) p++; 687239462Sdim return(p); 688239462Sdim } 689239462Sdim 690239462Sdim 691198090Srdivackystatic char *scan_dquote(CONF *conf, char *p) 692198090Srdivacky { 693198090Srdivacky int q= *p; 694193323Sed 695193323Sed p++; 696193323Sed while (!(IS_EOF(conf,*p))) 697193323Sed { 698212904Sdim if (*p == q) 699218893Sdim { 700212904Sdim if (*(p+1) == q) 701212904Sdim { 702212904Sdim p++; 703212904Sdim } 704212904Sdim else 705212904Sdim { 706212904Sdim break; 707212904Sdim } 708212904Sdim } 709212904Sdim p++; 710212904Sdim } 711212904Sdim if (*p == q) p++; 712212904Sdim return(p); 713212904Sdim } 714212904Sdim 715218893Sdimstatic void dump_value_doall_arg(CONF_VALUE *a, BIO *out) 716212904Sdim { 717212904Sdim if (a->name) 718234353Sdim BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); 719234353Sdim else 720212904Sdim BIO_printf(out, "[[%s]]\n", a->section); 721212904Sdim } 722212904Sdim 723212904Sdimstatic IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) 724212904Sdim 725212904Sdimstatic int def_dump(const CONF *conf, BIO *out) 726234353Sdim { 727212904Sdim lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), 728212904Sdim BIO, out); 729212904Sdim return 1; 730212904Sdim } 731212904Sdim 732212904Sdimstatic int def_is_number(const CONF *conf, char c) 733234353Sdim { 734212904Sdim return IS_NUMBER(conf,c); 735212904Sdim } 736193323Sed 737198396Srdivackystatic int def_to_int(const CONF *conf, char c) 738198396Srdivacky { 739198396Srdivacky return c - '0'; 740198090Srdivacky } 741198090Srdivacky 742198090Srdivacky