168651Skris/* crypto/conf/conf.c */ 268651Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 368651Skris * All rights reserved. 468651Skris * 568651Skris * This package is an SSL implementation written 668651Skris * by Eric Young (eay@cryptsoft.com). 768651Skris * The implementation was written so as to conform with Netscapes SSL. 8280297Sjkim * 968651Skris * This library is free for commercial and non-commercial use as long as 1068651Skris * the following conditions are aheared to. The following conditions 1168651Skris * apply to all code found in this distribution, be it the RC4, RSA, 1268651Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1368651Skris * included with this distribution is covered by the same copyright terms 1468651Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280297Sjkim * 1668651Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1768651Skris * the code are not to be removed. 1868651Skris * If this package is used in a product, Eric Young should be given attribution 1968651Skris * as the author of the parts of the library used. 2068651Skris * This can be in the form of a textual message at program startup or 2168651Skris * in documentation (online or textual) provided with the package. 22280297Sjkim * 2368651Skris * Redistribution and use in source and binary forms, with or without 2468651Skris * modification, are permitted provided that the following conditions 2568651Skris * are met: 2668651Skris * 1. Redistributions of source code must retain the copyright 2768651Skris * notice, this list of conditions and the following disclaimer. 2868651Skris * 2. Redistributions in binary form must reproduce the above copyright 2968651Skris * notice, this list of conditions and the following disclaimer in the 3068651Skris * documentation and/or other materials provided with the distribution. 3168651Skris * 3. All advertising materials mentioning features or use of this software 3268651Skris * must display the following acknowledgement: 3368651Skris * "This product includes cryptographic software written by 3468651Skris * Eric Young (eay@cryptsoft.com)" 3568651Skris * The word 'cryptographic' can be left out if the rouines from the library 3668651Skris * being used are not cryptographic related :-). 37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3868651Skris * the apps directory (application code) you must include an acknowledgement: 3968651Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280297Sjkim * 4168651Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4268651Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4368651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4468651Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4568651Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4668651Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4768651Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4968651Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5068651Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5168651Skris * SUCH DAMAGE. 52280297Sjkim * 5368651Skris * The licence and distribution terms for any publically available version or 5468651Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5568651Skris * copied and put under another distribution licence 5668651Skris * [including the GNU Public Licence.] 5768651Skris */ 5868651Skris 5968651Skris/* Part of the code in here was originally in conf.c, which is now removed */ 6068651Skris 6168651Skris#include <stdio.h> 6268651Skris#include <string.h> 63160814Ssimon#include "cryptlib.h" 6468651Skris#include <openssl/stack.h> 6568651Skris#include <openssl/lhash.h> 6668651Skris#include <openssl/conf.h> 6768651Skris#include <openssl/conf_api.h> 6868651Skris#include "conf_def.h" 6968651Skris#include <openssl/buffer.h> 7068651Skris#include <openssl/err.h> 7168651Skris 72325335Sjkim/* 73325335Sjkim * The maximum length we can grow a value to after variable expansion. 64k 74325335Sjkim * should be more than enough for all reasonable uses. 75325335Sjkim */ 76325335Sjkim#define MAX_CONF_VALUE_LENGTH 65536 77325335Sjkim 7868651Skrisstatic char *eat_ws(CONF *conf, char *p); 7968651Skrisstatic char *eat_alpha_numeric(CONF *conf, char *p); 8068651Skrisstatic void clear_comments(CONF *conf, char *p); 81280297Sjkimstatic int str_copy(CONF *conf, char *section, char **to, char *from); 8268651Skrisstatic char *scan_quote(CONF *conf, char *p); 8368651Skrisstatic char *scan_dquote(CONF *conf, char *p); 84280297Sjkim#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) 8568651Skris 8668651Skrisstatic CONF *def_create(CONF_METHOD *meth); 8768651Skrisstatic int def_init_default(CONF *conf); 8868651Skrisstatic int def_init_WIN32(CONF *conf); 8968651Skrisstatic int def_destroy(CONF *conf); 9068651Skrisstatic int def_destroy_data(CONF *conf); 91109998Smarkmstatic int def_load(CONF *conf, const char *name, long *eline); 92109998Smarkmstatic int def_load_bio(CONF *conf, BIO *bp, long *eline); 93109998Smarkmstatic int def_dump(const CONF *conf, BIO *bp); 94109998Smarkmstatic int def_is_number(const CONF *conf, char c); 95109998Smarkmstatic int def_to_int(const CONF *conf, char c); 9668651Skris 97280297Sjkimconst char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT; 9868651Skris 9968651Skrisstatic CONF_METHOD default_method = { 100280297Sjkim "OpenSSL default", 101280297Sjkim def_create, 102280297Sjkim def_init_default, 103280297Sjkim def_destroy, 104280297Sjkim def_destroy_data, 105280297Sjkim def_load_bio, 106280297Sjkim def_dump, 107280297Sjkim def_is_number, 108280297Sjkim def_to_int, 109280297Sjkim def_load 110280297Sjkim}; 11168651Skris 11268651Skrisstatic CONF_METHOD WIN32_method = { 113280297Sjkim "WIN32", 114280297Sjkim def_create, 115280297Sjkim def_init_WIN32, 116280297Sjkim def_destroy, 117280297Sjkim def_destroy_data, 118280297Sjkim def_load_bio, 119280297Sjkim def_dump, 120280297Sjkim def_is_number, 121280297Sjkim def_to_int, 122280297Sjkim def_load 123280297Sjkim}; 12468651Skris 12568651SkrisCONF_METHOD *NCONF_default() 126280297Sjkim{ 127280297Sjkim return &default_method; 128280297Sjkim} 129280297Sjkim 13068651SkrisCONF_METHOD *NCONF_WIN32() 131280297Sjkim{ 132280297Sjkim return &WIN32_method; 133280297Sjkim} 13468651Skris 13568651Skrisstatic CONF *def_create(CONF_METHOD *meth) 136280297Sjkim{ 137280297Sjkim CONF *ret; 13868651Skris 139280297Sjkim ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); 140280297Sjkim if (ret) 141280297Sjkim if (meth->init(ret) == 0) { 142280297Sjkim OPENSSL_free(ret); 143280297Sjkim ret = NULL; 144280297Sjkim } 145280297Sjkim return ret; 146280297Sjkim} 147280297Sjkim 14868651Skrisstatic int def_init_default(CONF *conf) 149280297Sjkim{ 150280297Sjkim if (conf == NULL) 151280297Sjkim return 0; 15268651Skris 153280297Sjkim conf->meth = &default_method; 154280297Sjkim conf->meth_data = CONF_type_default; 155280297Sjkim conf->data = NULL; 15668651Skris 157280297Sjkim return 1; 158280297Sjkim} 15968651Skris 16068651Skrisstatic int def_init_WIN32(CONF *conf) 161280297Sjkim{ 162280297Sjkim if (conf == NULL) 163280297Sjkim return 0; 16468651Skris 165280297Sjkim conf->meth = &WIN32_method; 166280297Sjkim conf->meth_data = (void *)CONF_type_win32; 167280297Sjkim conf->data = NULL; 16868651Skris 169280297Sjkim return 1; 170280297Sjkim} 17168651Skris 17268651Skrisstatic int def_destroy(CONF *conf) 173280297Sjkim{ 174280297Sjkim if (def_destroy_data(conf)) { 175280297Sjkim OPENSSL_free(conf); 176280297Sjkim return 1; 177280297Sjkim } 178280297Sjkim return 0; 179280297Sjkim} 18068651Skris 18168651Skrisstatic int def_destroy_data(CONF *conf) 182280297Sjkim{ 183280297Sjkim if (conf == NULL) 184280297Sjkim return 0; 185280297Sjkim _CONF_free_data(conf); 186280297Sjkim return 1; 187280297Sjkim} 18868651Skris 189109998Smarkmstatic int def_load(CONF *conf, const char *name, long *line) 190280297Sjkim{ 191280297Sjkim int ret; 192280297Sjkim BIO *in = NULL; 193109998Smarkm 194109998Smarkm#ifdef OPENSSL_SYS_VMS 195280297Sjkim in = BIO_new_file(name, "r"); 196109998Smarkm#else 197280297Sjkim in = BIO_new_file(name, "rb"); 198109998Smarkm#endif 199280297Sjkim if (in == NULL) { 200280297Sjkim if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) 201280297Sjkim CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); 202280297Sjkim else 203280297Sjkim CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); 204280297Sjkim return 0; 205280297Sjkim } 206109998Smarkm 207280297Sjkim ret = def_load_bio(conf, in, line); 208280297Sjkim BIO_free(in); 209109998Smarkm 210280297Sjkim return ret; 211280297Sjkim} 212109998Smarkm 213109998Smarkmstatic int def_load_bio(CONF *conf, BIO *in, long *line) 214280297Sjkim{ 215109998Smarkm/* The macro BUFSIZE conflicts with a system macro in VxWorks */ 216280297Sjkim#define CONFBUFSIZE 512 217280297Sjkim int bufnum = 0, i, ii; 218280297Sjkim BUF_MEM *buff = NULL; 219280297Sjkim char *s, *p, *end; 220280297Sjkim int again; 221280297Sjkim long eline = 0; 222280297Sjkim char btmp[DECIMAL_SIZE(eline) + 1]; 223280297Sjkim CONF_VALUE *v = NULL, *tv; 224280297Sjkim CONF_VALUE *sv = NULL; 225280297Sjkim char *section = NULL, *buf; 226280297Sjkim char *start, *psection, *pname; 227280297Sjkim void *h = (void *)(conf->data); 22868651Skris 229280297Sjkim if ((buff = BUF_MEM_new()) == NULL) { 230280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); 231280297Sjkim goto err; 232280297Sjkim } 23368651Skris 234291719Sjkim section = BUF_strdup("default"); 235280297Sjkim if (section == NULL) { 236280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 237280297Sjkim goto err; 238280297Sjkim } 23968651Skris 240280297Sjkim if (_CONF_new_data(conf) == 0) { 241280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 242280297Sjkim goto err; 243280297Sjkim } 24468651Skris 245280297Sjkim sv = _CONF_new_section(conf, section); 246280297Sjkim if (sv == NULL) { 247280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 248280297Sjkim goto err; 249280297Sjkim } 25068651Skris 251280297Sjkim bufnum = 0; 252280297Sjkim again = 0; 253280297Sjkim for (;;) { 254280297Sjkim if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { 255280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); 256280297Sjkim goto err; 257280297Sjkim } 258280297Sjkim p = &(buff->data[bufnum]); 259280297Sjkim *p = '\0'; 260280297Sjkim BIO_gets(in, p, CONFBUFSIZE - 1); 261280297Sjkim p[CONFBUFSIZE - 1] = '\0'; 262280297Sjkim ii = i = strlen(p); 263280297Sjkim if (i == 0 && !again) 264280297Sjkim break; 265280297Sjkim again = 0; 266280297Sjkim while (i > 0) { 267280297Sjkim if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) 268280297Sjkim break; 269280297Sjkim else 270280297Sjkim i--; 271280297Sjkim } 272280297Sjkim /* 273280297Sjkim * we removed some trailing stuff so there is a new line on the end. 274280297Sjkim */ 275280297Sjkim if (ii && i == ii) 276280297Sjkim again = 1; /* long line */ 277280297Sjkim else { 278280297Sjkim p[i] = '\0'; 279280297Sjkim eline++; /* another input line */ 280280297Sjkim } 28168651Skris 282280297Sjkim /* we now have a line with trailing \r\n removed */ 28368651Skris 284280297Sjkim /* i is the number of bytes */ 285280297Sjkim bufnum += i; 28668651Skris 287280297Sjkim v = NULL; 288280297Sjkim /* check for line continuation */ 289280297Sjkim if (bufnum >= 1) { 290280297Sjkim /* 291280297Sjkim * If we have bytes and the last char '\\' and second last char 292280297Sjkim * is not '\\' 293280297Sjkim */ 294280297Sjkim p = &(buff->data[bufnum - 1]); 295280297Sjkim if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { 296280297Sjkim bufnum--; 297280297Sjkim again = 1; 298280297Sjkim } 299280297Sjkim } 300280297Sjkim if (again) 301280297Sjkim continue; 302280297Sjkim bufnum = 0; 303280297Sjkim buf = buff->data; 30468651Skris 305280297Sjkim clear_comments(conf, buf); 306280297Sjkim s = eat_ws(conf, buf); 307280297Sjkim if (IS_EOF(conf, *s)) 308280297Sjkim continue; /* blank line */ 309280297Sjkim if (*s == '[') { 310280297Sjkim char *ss; 31168651Skris 312280297Sjkim s++; 313280297Sjkim start = eat_ws(conf, s); 314280297Sjkim ss = start; 315280297Sjkim again: 316280297Sjkim end = eat_alpha_numeric(conf, ss); 317280297Sjkim p = eat_ws(conf, end); 318280297Sjkim if (*p != ']') { 319280297Sjkim if (*p != '\0' && ss != p) { 320280297Sjkim ss = p; 321280297Sjkim goto again; 322280297Sjkim } 323280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, 324280297Sjkim CONF_R_MISSING_CLOSE_SQUARE_BRACKET); 325280297Sjkim goto err; 326280297Sjkim } 327280297Sjkim *end = '\0'; 328280297Sjkim if (!str_copy(conf, NULL, §ion, start)) 329280297Sjkim goto err; 330280297Sjkim if ((sv = _CONF_get_section(conf, section)) == NULL) 331280297Sjkim sv = _CONF_new_section(conf, section); 332280297Sjkim if (sv == NULL) { 333280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, 334280297Sjkim CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 335280297Sjkim goto err; 336280297Sjkim } 337280297Sjkim continue; 338280297Sjkim } else { 339280297Sjkim pname = s; 340280297Sjkim psection = NULL; 341280297Sjkim end = eat_alpha_numeric(conf, s); 342280297Sjkim if ((end[0] == ':') && (end[1] == ':')) { 343280297Sjkim *end = '\0'; 344280297Sjkim end += 2; 345280297Sjkim psection = pname; 346280297Sjkim pname = end; 347280297Sjkim end = eat_alpha_numeric(conf, end); 348280297Sjkim } 349280297Sjkim p = eat_ws(conf, end); 350280297Sjkim if (*p != '=') { 351280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); 352280297Sjkim goto err; 353280297Sjkim } 354280297Sjkim *end = '\0'; 355280297Sjkim p++; 356280297Sjkim start = eat_ws(conf, p); 357280297Sjkim while (!IS_EOF(conf, *p)) 358280297Sjkim p++; 359280297Sjkim p--; 360280297Sjkim while ((p != start) && (IS_WS(conf, *p))) 361280297Sjkim p--; 362280297Sjkim p++; 363280297Sjkim *p = '\0'; 36468651Skris 365280297Sjkim if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { 366280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 367280297Sjkim goto err; 368280297Sjkim } 369280297Sjkim if (psection == NULL) 370280297Sjkim psection = section; 371280297Sjkim v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); 372280297Sjkim v->value = NULL; 373280297Sjkim if (v->name == NULL) { 374280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 375280297Sjkim goto err; 376280297Sjkim } 377280297Sjkim BUF_strlcpy(v->name, pname, strlen(pname) + 1); 378280297Sjkim if (!str_copy(conf, psection, &(v->value), start)) 379280297Sjkim goto err; 38068651Skris 381280297Sjkim if (strcmp(psection, section) != 0) { 382280297Sjkim if ((tv = _CONF_get_section(conf, psection)) 383280297Sjkim == NULL) 384280297Sjkim tv = _CONF_new_section(conf, psection); 385280297Sjkim if (tv == NULL) { 386280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, 387280297Sjkim CONF_R_UNABLE_TO_CREATE_NEW_SECTION); 388280297Sjkim goto err; 389280297Sjkim } 390280297Sjkim } else 391280297Sjkim tv = sv; 39268651Skris#if 1 393280297Sjkim if (_CONF_add_string(conf, tv, v) == 0) { 394280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 395280297Sjkim goto err; 396280297Sjkim } 39768651Skris#else 398280297Sjkim v->section = tv->section; 399280297Sjkim if (!sk_CONF_VALUE_push(ts, v)) { 400280297Sjkim CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); 401280297Sjkim goto err; 402280297Sjkim } 403280297Sjkim vv = (CONF_VALUE *)lh_insert(conf->data, v); 404280297Sjkim if (vv != NULL) { 405280297Sjkim sk_CONF_VALUE_delete_ptr(ts, vv); 406280297Sjkim OPENSSL_free(vv->name); 407280297Sjkim OPENSSL_free(vv->value); 408280297Sjkim OPENSSL_free(vv); 409280297Sjkim } 41068651Skris#endif 411280297Sjkim v = NULL; 412280297Sjkim } 413280297Sjkim } 414280297Sjkim if (buff != NULL) 415280297Sjkim BUF_MEM_free(buff); 416280297Sjkim if (section != NULL) 417280297Sjkim OPENSSL_free(section); 418280297Sjkim return (1); 419280297Sjkim err: 420280297Sjkim if (buff != NULL) 421280297Sjkim BUF_MEM_free(buff); 422280297Sjkim if (section != NULL) 423280297Sjkim OPENSSL_free(section); 424280297Sjkim if (line != NULL) 425280297Sjkim *line = eline; 426331638Sjkim BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); 427280297Sjkim ERR_add_error_data(2, "line ", btmp); 428280297Sjkim if ((h != conf->data) && (conf->data != NULL)) { 429280297Sjkim CONF_free(conf->data); 430280297Sjkim conf->data = NULL; 431280297Sjkim } 432280297Sjkim if (v != NULL) { 433280297Sjkim if (v->name != NULL) 434280297Sjkim OPENSSL_free(v->name); 435280297Sjkim if (v->value != NULL) 436280297Sjkim OPENSSL_free(v->value); 437280297Sjkim if (v != NULL) 438280297Sjkim OPENSSL_free(v); 439280297Sjkim } 440280297Sjkim return (0); 441280297Sjkim} 44268651Skris 44368651Skrisstatic void clear_comments(CONF *conf, char *p) 444280297Sjkim{ 445280297Sjkim for (;;) { 446280297Sjkim if (IS_FCOMMENT(conf, *p)) { 447280297Sjkim *p = '\0'; 448280297Sjkim return; 449280297Sjkim } 450280297Sjkim if (!IS_WS(conf, *p)) { 451280297Sjkim break; 452280297Sjkim } 453280297Sjkim p++; 454280297Sjkim } 45568651Skris 456280297Sjkim for (;;) { 457280297Sjkim if (IS_COMMENT(conf, *p)) { 458280297Sjkim *p = '\0'; 459280297Sjkim return; 460280297Sjkim } 461280297Sjkim if (IS_DQUOTE(conf, *p)) { 462280297Sjkim p = scan_dquote(conf, p); 463280297Sjkim continue; 464280297Sjkim } 465280297Sjkim if (IS_QUOTE(conf, *p)) { 466280297Sjkim p = scan_quote(conf, p); 467280297Sjkim continue; 468280297Sjkim } 469280297Sjkim if (IS_ESC(conf, *p)) { 470280297Sjkim p = scan_esc(conf, p); 471280297Sjkim continue; 472280297Sjkim } 473280297Sjkim if (IS_EOF(conf, *p)) 474280297Sjkim return; 475280297Sjkim else 476280297Sjkim p++; 477280297Sjkim } 478280297Sjkim} 47968651Skris 48068651Skrisstatic int str_copy(CONF *conf, char *section, char **pto, char *from) 481280297Sjkim{ 482280297Sjkim int q, r, rr = 0, to = 0, len = 0; 483280297Sjkim char *s, *e, *rp, *p, *rrp, *np, *cp, v; 484280297Sjkim BUF_MEM *buf; 48568651Skris 486280297Sjkim if ((buf = BUF_MEM_new()) == NULL) 487280297Sjkim return (0); 48868651Skris 489280297Sjkim len = strlen(from) + 1; 490280297Sjkim if (!BUF_MEM_grow(buf, len)) 491280297Sjkim goto err; 49268651Skris 493280297Sjkim for (;;) { 494280297Sjkim if (IS_QUOTE(conf, *from)) { 495280297Sjkim q = *from; 496280297Sjkim from++; 497280297Sjkim while (!IS_EOF(conf, *from) && (*from != q)) { 498280297Sjkim if (IS_ESC(conf, *from)) { 499280297Sjkim from++; 500280297Sjkim if (IS_EOF(conf, *from)) 501280297Sjkim break; 502280297Sjkim } 503280297Sjkim buf->data[to++] = *(from++); 504280297Sjkim } 505280297Sjkim if (*from == q) 506280297Sjkim from++; 507280297Sjkim } else if (IS_DQUOTE(conf, *from)) { 508280297Sjkim q = *from; 509280297Sjkim from++; 510280297Sjkim while (!IS_EOF(conf, *from)) { 511280297Sjkim if (*from == q) { 512280297Sjkim if (*(from + 1) == q) { 513280297Sjkim from++; 514280297Sjkim } else { 515280297Sjkim break; 516280297Sjkim } 517280297Sjkim } 518280297Sjkim buf->data[to++] = *(from++); 519280297Sjkim } 520280297Sjkim if (*from == q) 521280297Sjkim from++; 522280297Sjkim } else if (IS_ESC(conf, *from)) { 523280297Sjkim from++; 524280297Sjkim v = *(from++); 525280297Sjkim if (IS_EOF(conf, v)) 526280297Sjkim break; 527280297Sjkim else if (v == 'r') 528280297Sjkim v = '\r'; 529280297Sjkim else if (v == 'n') 530280297Sjkim v = '\n'; 531280297Sjkim else if (v == 'b') 532280297Sjkim v = '\b'; 533280297Sjkim else if (v == 't') 534280297Sjkim v = '\t'; 535280297Sjkim buf->data[to++] = v; 536280297Sjkim } else if (IS_EOF(conf, *from)) 537280297Sjkim break; 538280297Sjkim else if (*from == '$') { 539325335Sjkim size_t newsize; 540325335Sjkim 541280297Sjkim /* try to expand it */ 542280297Sjkim rrp = NULL; 543280297Sjkim s = &(from[1]); 544280297Sjkim if (*s == '{') 545280297Sjkim q = '}'; 546280297Sjkim else if (*s == '(') 547280297Sjkim q = ')'; 548280297Sjkim else 549280297Sjkim q = 0; 55068651Skris 551280297Sjkim if (q) 552280297Sjkim s++; 553280297Sjkim cp = section; 554280297Sjkim e = np = s; 555280297Sjkim while (IS_ALPHA_NUMERIC(conf, *e)) 556280297Sjkim e++; 557280297Sjkim if ((e[0] == ':') && (e[1] == ':')) { 558280297Sjkim cp = np; 559280297Sjkim rrp = e; 560280297Sjkim rr = *e; 561280297Sjkim *rrp = '\0'; 562280297Sjkim e += 2; 563280297Sjkim np = e; 564280297Sjkim while (IS_ALPHA_NUMERIC(conf, *e)) 565280297Sjkim e++; 566280297Sjkim } 567280297Sjkim r = *e; 568280297Sjkim *e = '\0'; 569280297Sjkim rp = e; 570280297Sjkim if (q) { 571280297Sjkim if (r != q) { 572280297Sjkim CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); 573280297Sjkim goto err; 574280297Sjkim } 575280297Sjkim e++; 576280297Sjkim } 577280297Sjkim /*- 578280297Sjkim * So at this point we have 579280297Sjkim * np which is the start of the name string which is 580280297Sjkim * '\0' terminated. 581280297Sjkim * cp which is the start of the section string which is 582280297Sjkim * '\0' terminated. 583280297Sjkim * e is the 'next point after'. 584280297Sjkim * r and rr are the chars replaced by the '\0' 585280297Sjkim * rp and rrp is where 'r' and 'rr' came from. 586280297Sjkim */ 587280297Sjkim p = _CONF_get_string(conf, cp, np); 588280297Sjkim if (rrp != NULL) 589280297Sjkim *rrp = rr; 590280297Sjkim *rp = r; 591280297Sjkim if (p == NULL) { 592280297Sjkim CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); 593280297Sjkim goto err; 594280297Sjkim } 595325335Sjkim newsize = strlen(p) + buf->length - (e - from); 596325335Sjkim if (newsize > MAX_CONF_VALUE_LENGTH) { 597325335Sjkim CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); 598325335Sjkim goto err; 599325335Sjkim } 600325335Sjkim if (!BUF_MEM_grow_clean(buf, newsize)) { 601280297Sjkim CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); 602280297Sjkim goto err; 603280297Sjkim } 604280297Sjkim while (*p) 605280297Sjkim buf->data[to++] = *(p++); 606142425Snectar 607280297Sjkim /* 608280297Sjkim * Since we change the pointer 'from', we also have to change the 609280297Sjkim * perceived length of the string it points at. /RL 610280297Sjkim */ 611280297Sjkim len -= e - from; 612280297Sjkim from = e; 613160814Ssimon 614280297Sjkim /* 615280297Sjkim * In case there were no braces or parenthesis around the 616280297Sjkim * variable reference, we have to put back the character that was 617280297Sjkim * replaced with a '\0'. /RL 618280297Sjkim */ 619280297Sjkim *rp = r; 620280297Sjkim } else 621280297Sjkim buf->data[to++] = *(from++); 622280297Sjkim } 623280297Sjkim buf->data[to] = '\0'; 624280297Sjkim if (*pto != NULL) 625280297Sjkim OPENSSL_free(*pto); 626280297Sjkim *pto = buf->data; 627280297Sjkim OPENSSL_free(buf); 628280297Sjkim return (1); 629280297Sjkim err: 630280297Sjkim if (buf != NULL) 631280297Sjkim BUF_MEM_free(buf); 632280297Sjkim return (0); 633280297Sjkim} 63468651Skris 63568651Skrisstatic char *eat_ws(CONF *conf, char *p) 636280297Sjkim{ 637280297Sjkim while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) 638280297Sjkim p++; 639280297Sjkim return (p); 640280297Sjkim} 64168651Skris 64268651Skrisstatic char *eat_alpha_numeric(CONF *conf, char *p) 643280297Sjkim{ 644280297Sjkim for (;;) { 645280297Sjkim if (IS_ESC(conf, *p)) { 646280297Sjkim p = scan_esc(conf, p); 647280297Sjkim continue; 648280297Sjkim } 649280297Sjkim if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) 650280297Sjkim return (p); 651280297Sjkim p++; 652280297Sjkim } 653280297Sjkim} 65468651Skris 65568651Skrisstatic char *scan_quote(CONF *conf, char *p) 656280297Sjkim{ 657280297Sjkim int q = *p; 65868651Skris 659280297Sjkim p++; 660280297Sjkim while (!(IS_EOF(conf, *p)) && (*p != q)) { 661280297Sjkim if (IS_ESC(conf, *p)) { 662280297Sjkim p++; 663280297Sjkim if (IS_EOF(conf, *p)) 664280297Sjkim return (p); 665280297Sjkim } 666280297Sjkim p++; 667280297Sjkim } 668280297Sjkim if (*p == q) 669280297Sjkim p++; 670280297Sjkim return (p); 671280297Sjkim} 67268651Skris 67368651Skrisstatic char *scan_dquote(CONF *conf, char *p) 674280297Sjkim{ 675280297Sjkim int q = *p; 67668651Skris 677280297Sjkim p++; 678280297Sjkim while (!(IS_EOF(conf, *p))) { 679280297Sjkim if (*p == q) { 680280297Sjkim if (*(p + 1) == q) { 681280297Sjkim p++; 682280297Sjkim } else { 683280297Sjkim break; 684280297Sjkim } 685280297Sjkim } 686280297Sjkim p++; 687280297Sjkim } 688280297Sjkim if (*p == q) 689280297Sjkim p++; 690280297Sjkim return (p); 691280297Sjkim} 69268651Skris 693238405Sjkimstatic void dump_value_doall_arg(CONF_VALUE *a, BIO *out) 694280297Sjkim{ 695280297Sjkim if (a->name) 696280297Sjkim BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); 697280297Sjkim else 698280297Sjkim BIO_printf(out, "[[%s]]\n", a->section); 699280297Sjkim} 70068651Skris 701238405Sjkimstatic IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) 702109998Smarkm 703109998Smarkmstatic int def_dump(const CONF *conf, BIO *out) 704280297Sjkim{ 705280297Sjkim lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), 706280297Sjkim BIO, out); 707280297Sjkim return 1; 708280297Sjkim} 70968651Skris 710109998Smarkmstatic int def_is_number(const CONF *conf, char c) 711280297Sjkim{ 712280297Sjkim return IS_NUMBER(conf, c); 713280297Sjkim} 71468651Skris 715109998Smarkmstatic int def_to_int(const CONF *conf, char c) 716280297Sjkim{ 717280297Sjkim return c - '0'; 718280297Sjkim} 719