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.
8280304Sjkim *
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).
15280304Sjkim *
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.
22280304Sjkim *
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 :-).
37280304Sjkim * 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)"
40280304Sjkim *
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.
52280304Sjkim *
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
7268651Skrisstatic char *eat_ws(CONF *conf, char *p);
7368651Skrisstatic char *eat_alpha_numeric(CONF *conf, char *p);
7468651Skrisstatic void clear_comments(CONF *conf, char *p);
75280304Sjkimstatic int str_copy(CONF *conf, char *section, char **to, char *from);
7668651Skrisstatic char *scan_quote(CONF *conf, char *p);
7768651Skrisstatic char *scan_dquote(CONF *conf, char *p);
78280304Sjkim#define scan_esc(conf,p)        (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
7968651Skris
8068651Skrisstatic CONF *def_create(CONF_METHOD *meth);
8168651Skrisstatic int def_init_default(CONF *conf);
8268651Skrisstatic int def_init_WIN32(CONF *conf);
8368651Skrisstatic int def_destroy(CONF *conf);
8468651Skrisstatic int def_destroy_data(CONF *conf);
85109998Smarkmstatic int def_load(CONF *conf, const char *name, long *eline);
86109998Smarkmstatic int def_load_bio(CONF *conf, BIO *bp, long *eline);
87109998Smarkmstatic int def_dump(const CONF *conf, BIO *bp);
88109998Smarkmstatic int def_is_number(const CONF *conf, char c);
89109998Smarkmstatic int def_to_int(const CONF *conf, char c);
9068651Skris
91280304Sjkimconst char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT;
9268651Skris
9368651Skrisstatic CONF_METHOD default_method = {
94280304Sjkim    "OpenSSL default",
95280304Sjkim    def_create,
96280304Sjkim    def_init_default,
97280304Sjkim    def_destroy,
98280304Sjkim    def_destroy_data,
99280304Sjkim    def_load_bio,
100280304Sjkim    def_dump,
101280304Sjkim    def_is_number,
102280304Sjkim    def_to_int,
103280304Sjkim    def_load
104280304Sjkim};
10568651Skris
10668651Skrisstatic CONF_METHOD WIN32_method = {
107280304Sjkim    "WIN32",
108280304Sjkim    def_create,
109280304Sjkim    def_init_WIN32,
110280304Sjkim    def_destroy,
111280304Sjkim    def_destroy_data,
112280304Sjkim    def_load_bio,
113280304Sjkim    def_dump,
114280304Sjkim    def_is_number,
115280304Sjkim    def_to_int,
116280304Sjkim    def_load
117280304Sjkim};
11868651Skris
11968651SkrisCONF_METHOD *NCONF_default()
120280304Sjkim{
121280304Sjkim    return &default_method;
122280304Sjkim}
123280304Sjkim
12468651SkrisCONF_METHOD *NCONF_WIN32()
125280304Sjkim{
126280304Sjkim    return &WIN32_method;
127280304Sjkim}
12868651Skris
12968651Skrisstatic CONF *def_create(CONF_METHOD *meth)
130280304Sjkim{
131280304Sjkim    CONF *ret;
13268651Skris
133280304Sjkim    ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
134280304Sjkim    if (ret)
135280304Sjkim        if (meth->init(ret) == 0) {
136280304Sjkim            OPENSSL_free(ret);
137280304Sjkim            ret = NULL;
138280304Sjkim        }
139280304Sjkim    return ret;
140280304Sjkim}
141280304Sjkim
14268651Skrisstatic int def_init_default(CONF *conf)
143280304Sjkim{
144280304Sjkim    if (conf == NULL)
145280304Sjkim        return 0;
14668651Skris
147280304Sjkim    conf->meth = &default_method;
148280304Sjkim    conf->meth_data = CONF_type_default;
149280304Sjkim    conf->data = NULL;
15068651Skris
151280304Sjkim    return 1;
152280304Sjkim}
15368651Skris
15468651Skrisstatic int def_init_WIN32(CONF *conf)
155280304Sjkim{
156280304Sjkim    if (conf == NULL)
157280304Sjkim        return 0;
15868651Skris
159280304Sjkim    conf->meth = &WIN32_method;
160280304Sjkim    conf->meth_data = (void *)CONF_type_win32;
161280304Sjkim    conf->data = NULL;
16268651Skris
163280304Sjkim    return 1;
164280304Sjkim}
16568651Skris
16668651Skrisstatic int def_destroy(CONF *conf)
167280304Sjkim{
168280304Sjkim    if (def_destroy_data(conf)) {
169280304Sjkim        OPENSSL_free(conf);
170280304Sjkim        return 1;
171280304Sjkim    }
172280304Sjkim    return 0;
173280304Sjkim}
17468651Skris
17568651Skrisstatic int def_destroy_data(CONF *conf)
176280304Sjkim{
177280304Sjkim    if (conf == NULL)
178280304Sjkim        return 0;
179280304Sjkim    _CONF_free_data(conf);
180280304Sjkim    return 1;
181280304Sjkim}
18268651Skris
183109998Smarkmstatic int def_load(CONF *conf, const char *name, long *line)
184280304Sjkim{
185280304Sjkim    int ret;
186280304Sjkim    BIO *in = NULL;
187109998Smarkm
188109998Smarkm#ifdef OPENSSL_SYS_VMS
189280304Sjkim    in = BIO_new_file(name, "r");
190109998Smarkm#else
191280304Sjkim    in = BIO_new_file(name, "rb");
192109998Smarkm#endif
193280304Sjkim    if (in == NULL) {
194280304Sjkim        if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
195280304Sjkim            CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
196280304Sjkim        else
197280304Sjkim            CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
198280304Sjkim        return 0;
199280304Sjkim    }
200109998Smarkm
201280304Sjkim    ret = def_load_bio(conf, in, line);
202280304Sjkim    BIO_free(in);
203109998Smarkm
204280304Sjkim    return ret;
205280304Sjkim}
206109998Smarkm
207109998Smarkmstatic int def_load_bio(CONF *conf, BIO *in, long *line)
208280304Sjkim{
209109998Smarkm/* The macro BUFSIZE conflicts with a system macro in VxWorks */
210280304Sjkim#define CONFBUFSIZE     512
211280304Sjkim    int bufnum = 0, i, ii;
212280304Sjkim    BUF_MEM *buff = NULL;
213280304Sjkim    char *s, *p, *end;
214280304Sjkim    int again;
215280304Sjkim    long eline = 0;
216280304Sjkim    char btmp[DECIMAL_SIZE(eline) + 1];
217280304Sjkim    CONF_VALUE *v = NULL, *tv;
218280304Sjkim    CONF_VALUE *sv = NULL;
219280304Sjkim    char *section = NULL, *buf;
220280304Sjkim    char *start, *psection, *pname;
221280304Sjkim    void *h = (void *)(conf->data);
22268651Skris
223280304Sjkim    if ((buff = BUF_MEM_new()) == NULL) {
224280304Sjkim        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
225280304Sjkim        goto err;
226280304Sjkim    }
22768651Skris
228291721Sjkim    section = BUF_strdup("default");
229280304Sjkim    if (section == NULL) {
230280304Sjkim        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
231280304Sjkim        goto err;
232280304Sjkim    }
23368651Skris
234280304Sjkim    if (_CONF_new_data(conf) == 0) {
235280304Sjkim        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
236280304Sjkim        goto err;
237280304Sjkim    }
23868651Skris
239280304Sjkim    sv = _CONF_new_section(conf, section);
240280304Sjkim    if (sv == NULL) {
241280304Sjkim        CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
242280304Sjkim        goto err;
243280304Sjkim    }
24468651Skris
245280304Sjkim    bufnum = 0;
246280304Sjkim    again = 0;
247280304Sjkim    for (;;) {
248280304Sjkim        if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
249280304Sjkim            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
250280304Sjkim            goto err;
251280304Sjkim        }
252280304Sjkim        p = &(buff->data[bufnum]);
253280304Sjkim        *p = '\0';
254280304Sjkim        BIO_gets(in, p, CONFBUFSIZE - 1);
255280304Sjkim        p[CONFBUFSIZE - 1] = '\0';
256280304Sjkim        ii = i = strlen(p);
257280304Sjkim        if (i == 0 && !again)
258280304Sjkim            break;
259280304Sjkim        again = 0;
260280304Sjkim        while (i > 0) {
261280304Sjkim            if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
262280304Sjkim                break;
263280304Sjkim            else
264280304Sjkim                i--;
265280304Sjkim        }
266280304Sjkim        /*
267280304Sjkim         * we removed some trailing stuff so there is a new line on the end.
268280304Sjkim         */
269280304Sjkim        if (ii && i == ii)
270280304Sjkim            again = 1;          /* long line */
271280304Sjkim        else {
272280304Sjkim            p[i] = '\0';
273280304Sjkim            eline++;            /* another input line */
274280304Sjkim        }
27568651Skris
276280304Sjkim        /* we now have a line with trailing \r\n removed */
27768651Skris
278280304Sjkim        /* i is the number of bytes */
279280304Sjkim        bufnum += i;
28068651Skris
281280304Sjkim        v = NULL;
282280304Sjkim        /* check for line continuation */
283280304Sjkim        if (bufnum >= 1) {
284280304Sjkim            /*
285280304Sjkim             * If we have bytes and the last char '\\' and second last char
286280304Sjkim             * is not '\\'
287280304Sjkim             */
288280304Sjkim            p = &(buff->data[bufnum - 1]);
289280304Sjkim            if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
290280304Sjkim                bufnum--;
291280304Sjkim                again = 1;
292280304Sjkim            }
293280304Sjkim        }
294280304Sjkim        if (again)
295280304Sjkim            continue;
296280304Sjkim        bufnum = 0;
297280304Sjkim        buf = buff->data;
29868651Skris
299280304Sjkim        clear_comments(conf, buf);
300280304Sjkim        s = eat_ws(conf, buf);
301280304Sjkim        if (IS_EOF(conf, *s))
302280304Sjkim            continue;           /* blank line */
303280304Sjkim        if (*s == '[') {
304280304Sjkim            char *ss;
30568651Skris
306280304Sjkim            s++;
307280304Sjkim            start = eat_ws(conf, s);
308280304Sjkim            ss = start;
309280304Sjkim again:
310280304Sjkim            end = eat_alpha_numeric(conf, ss);
311280304Sjkim            p = eat_ws(conf, end);
312280304Sjkim            if (*p != ']') {
313280304Sjkim                if (*p != '\0' && ss != p) {
314280304Sjkim                    ss = p;
315280304Sjkim                    goto again;
316280304Sjkim                }
317280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO,
318280304Sjkim                        CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
319280304Sjkim                goto err;
320280304Sjkim            }
321280304Sjkim            *end = '\0';
322280304Sjkim            if (!str_copy(conf, NULL, &section, start))
323280304Sjkim                goto err;
324280304Sjkim            if ((sv = _CONF_get_section(conf, section)) == NULL)
325280304Sjkim                sv = _CONF_new_section(conf, section);
326280304Sjkim            if (sv == NULL) {
327280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO,
328280304Sjkim                        CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
329280304Sjkim                goto err;
330280304Sjkim            }
331280304Sjkim            continue;
332280304Sjkim        } else {
333280304Sjkim            pname = s;
334280304Sjkim            psection = NULL;
335280304Sjkim            end = eat_alpha_numeric(conf, s);
336280304Sjkim            if ((end[0] == ':') && (end[1] == ':')) {
337280304Sjkim                *end = '\0';
338280304Sjkim                end += 2;
339280304Sjkim                psection = pname;
340280304Sjkim                pname = end;
341280304Sjkim                end = eat_alpha_numeric(conf, end);
342280304Sjkim            }
343280304Sjkim            p = eat_ws(conf, end);
344280304Sjkim            if (*p != '=') {
345280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
346280304Sjkim                goto err;
347280304Sjkim            }
348280304Sjkim            *end = '\0';
349280304Sjkim            p++;
350280304Sjkim            start = eat_ws(conf, p);
351280304Sjkim            while (!IS_EOF(conf, *p))
352280304Sjkim                p++;
353280304Sjkim            p--;
354280304Sjkim            while ((p != start) && (IS_WS(conf, *p)))
355280304Sjkim                p--;
356280304Sjkim            p++;
357280304Sjkim            *p = '\0';
35868651Skris
359280304Sjkim            if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
360280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
361280304Sjkim                goto err;
362280304Sjkim            }
363280304Sjkim            if (psection == NULL)
364280304Sjkim                psection = section;
365280304Sjkim            v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
366280304Sjkim            v->value = NULL;
367280304Sjkim            if (v->name == NULL) {
368280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
369280304Sjkim                goto err;
370280304Sjkim            }
371280304Sjkim            BUF_strlcpy(v->name, pname, strlen(pname) + 1);
372280304Sjkim            if (!str_copy(conf, psection, &(v->value), start))
373280304Sjkim                goto err;
37468651Skris
375280304Sjkim            if (strcmp(psection, section) != 0) {
376280304Sjkim                if ((tv = _CONF_get_section(conf, psection))
377280304Sjkim                    == NULL)
378280304Sjkim                    tv = _CONF_new_section(conf, psection);
379280304Sjkim                if (tv == NULL) {
380280304Sjkim                    CONFerr(CONF_F_DEF_LOAD_BIO,
381280304Sjkim                            CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
382280304Sjkim                    goto err;
383280304Sjkim                }
384280304Sjkim            } else
385280304Sjkim                tv = sv;
38668651Skris#if 1
387280304Sjkim            if (_CONF_add_string(conf, tv, v) == 0) {
388280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
389280304Sjkim                goto err;
390280304Sjkim            }
39168651Skris#else
392280304Sjkim            v->section = tv->section;
393280304Sjkim            if (!sk_CONF_VALUE_push(ts, v)) {
394280304Sjkim                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
395280304Sjkim                goto err;
396280304Sjkim            }
397280304Sjkim            vv = (CONF_VALUE *)lh_insert(conf->data, v);
398280304Sjkim            if (vv != NULL) {
399280304Sjkim                sk_CONF_VALUE_delete_ptr(ts, vv);
400280304Sjkim                OPENSSL_free(vv->name);
401280304Sjkim                OPENSSL_free(vv->value);
402280304Sjkim                OPENSSL_free(vv);
403280304Sjkim            }
40468651Skris#endif
405280304Sjkim            v = NULL;
406280304Sjkim        }
407280304Sjkim    }
408280304Sjkim    if (buff != NULL)
409280304Sjkim        BUF_MEM_free(buff);
410280304Sjkim    if (section != NULL)
411280304Sjkim        OPENSSL_free(section);
412280304Sjkim    return (1);
413280304Sjkim err:
414280304Sjkim    if (buff != NULL)
415280304Sjkim        BUF_MEM_free(buff);
416280304Sjkim    if (section != NULL)
417280304Sjkim        OPENSSL_free(section);
418280304Sjkim    if (line != NULL)
419280304Sjkim        *line = eline;
420280304Sjkim    BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
421280304Sjkim    ERR_add_error_data(2, "line ", btmp);
422280304Sjkim    if ((h != conf->data) && (conf->data != NULL)) {
423280304Sjkim        CONF_free(conf->data);
424280304Sjkim        conf->data = NULL;
425280304Sjkim    }
426280304Sjkim    if (v != NULL) {
427280304Sjkim        if (v->name != NULL)
428280304Sjkim            OPENSSL_free(v->name);
429280304Sjkim        if (v->value != NULL)
430280304Sjkim            OPENSSL_free(v->value);
431280304Sjkim        if (v != NULL)
432280304Sjkim            OPENSSL_free(v);
433280304Sjkim    }
434280304Sjkim    return (0);
435280304Sjkim}
43668651Skris
43768651Skrisstatic void clear_comments(CONF *conf, char *p)
438280304Sjkim{
439280304Sjkim    for (;;) {
440280304Sjkim        if (IS_FCOMMENT(conf, *p)) {
441280304Sjkim            *p = '\0';
442280304Sjkim            return;
443280304Sjkim        }
444280304Sjkim        if (!IS_WS(conf, *p)) {
445280304Sjkim            break;
446280304Sjkim        }
447280304Sjkim        p++;
448280304Sjkim    }
44968651Skris
450280304Sjkim    for (;;) {
451280304Sjkim        if (IS_COMMENT(conf, *p)) {
452280304Sjkim            *p = '\0';
453280304Sjkim            return;
454280304Sjkim        }
455280304Sjkim        if (IS_DQUOTE(conf, *p)) {
456280304Sjkim            p = scan_dquote(conf, p);
457280304Sjkim            continue;
458280304Sjkim        }
459280304Sjkim        if (IS_QUOTE(conf, *p)) {
460280304Sjkim            p = scan_quote(conf, p);
461280304Sjkim            continue;
462280304Sjkim        }
463280304Sjkim        if (IS_ESC(conf, *p)) {
464280304Sjkim            p = scan_esc(conf, p);
465280304Sjkim            continue;
466280304Sjkim        }
467280304Sjkim        if (IS_EOF(conf, *p))
468280304Sjkim            return;
469280304Sjkim        else
470280304Sjkim            p++;
471280304Sjkim    }
472280304Sjkim}
47368651Skris
47468651Skrisstatic int str_copy(CONF *conf, char *section, char **pto, char *from)
475280304Sjkim{
476280304Sjkim    int q, r, rr = 0, to = 0, len = 0;
477280304Sjkim    char *s, *e, *rp, *p, *rrp, *np, *cp, v;
478280304Sjkim    BUF_MEM *buf;
47968651Skris
480280304Sjkim    if ((buf = BUF_MEM_new()) == NULL)
481280304Sjkim        return (0);
48268651Skris
483280304Sjkim    len = strlen(from) + 1;
484280304Sjkim    if (!BUF_MEM_grow(buf, len))
485280304Sjkim        goto err;
48668651Skris
487280304Sjkim    for (;;) {
488280304Sjkim        if (IS_QUOTE(conf, *from)) {
489280304Sjkim            q = *from;
490280304Sjkim            from++;
491280304Sjkim            while (!IS_EOF(conf, *from) && (*from != q)) {
492280304Sjkim                if (IS_ESC(conf, *from)) {
493280304Sjkim                    from++;
494280304Sjkim                    if (IS_EOF(conf, *from))
495280304Sjkim                        break;
496280304Sjkim                }
497280304Sjkim                buf->data[to++] = *(from++);
498280304Sjkim            }
499280304Sjkim            if (*from == q)
500280304Sjkim                from++;
501280304Sjkim        } else if (IS_DQUOTE(conf, *from)) {
502280304Sjkim            q = *from;
503280304Sjkim            from++;
504280304Sjkim            while (!IS_EOF(conf, *from)) {
505280304Sjkim                if (*from == q) {
506280304Sjkim                    if (*(from + 1) == q) {
507280304Sjkim                        from++;
508280304Sjkim                    } else {
509280304Sjkim                        break;
510280304Sjkim                    }
511280304Sjkim                }
512280304Sjkim                buf->data[to++] = *(from++);
513280304Sjkim            }
514280304Sjkim            if (*from == q)
515280304Sjkim                from++;
516280304Sjkim        } else if (IS_ESC(conf, *from)) {
517280304Sjkim            from++;
518280304Sjkim            v = *(from++);
519280304Sjkim            if (IS_EOF(conf, v))
520280304Sjkim                break;
521280304Sjkim            else if (v == 'r')
522280304Sjkim                v = '\r';
523280304Sjkim            else if (v == 'n')
524280304Sjkim                v = '\n';
525280304Sjkim            else if (v == 'b')
526280304Sjkim                v = '\b';
527280304Sjkim            else if (v == 't')
528280304Sjkim                v = '\t';
529280304Sjkim            buf->data[to++] = v;
530280304Sjkim        } else if (IS_EOF(conf, *from))
531280304Sjkim            break;
532280304Sjkim        else if (*from == '$') {
533280304Sjkim            /* try to expand it */
534280304Sjkim            rrp = NULL;
535280304Sjkim            s = &(from[1]);
536280304Sjkim            if (*s == '{')
537280304Sjkim                q = '}';
538280304Sjkim            else if (*s == '(')
539280304Sjkim                q = ')';
540280304Sjkim            else
541280304Sjkim                q = 0;
54268651Skris
543280304Sjkim            if (q)
544280304Sjkim                s++;
545280304Sjkim            cp = section;
546280304Sjkim            e = np = s;
547280304Sjkim            while (IS_ALPHA_NUMERIC(conf, *e))
548280304Sjkim                e++;
549280304Sjkim            if ((e[0] == ':') && (e[1] == ':')) {
550280304Sjkim                cp = np;
551280304Sjkim                rrp = e;
552280304Sjkim                rr = *e;
553280304Sjkim                *rrp = '\0';
554280304Sjkim                e += 2;
555280304Sjkim                np = e;
556280304Sjkim                while (IS_ALPHA_NUMERIC(conf, *e))
557280304Sjkim                    e++;
558280304Sjkim            }
559280304Sjkim            r = *e;
560280304Sjkim            *e = '\0';
561280304Sjkim            rp = e;
562280304Sjkim            if (q) {
563280304Sjkim                if (r != q) {
564280304Sjkim                    CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
565280304Sjkim                    goto err;
566280304Sjkim                }
567280304Sjkim                e++;
568280304Sjkim            }
569280304Sjkim            /*-
570280304Sjkim             * So at this point we have
571280304Sjkim             * np which is the start of the name string which is
572280304Sjkim             *   '\0' terminated.
573280304Sjkim             * cp which is the start of the section string which is
574280304Sjkim             *   '\0' terminated.
575280304Sjkim             * e is the 'next point after'.
576280304Sjkim             * r and rr are the chars replaced by the '\0'
577280304Sjkim             * rp and rrp is where 'r' and 'rr' came from.
578280304Sjkim             */
579280304Sjkim            p = _CONF_get_string(conf, cp, np);
580280304Sjkim            if (rrp != NULL)
581280304Sjkim                *rrp = rr;
582280304Sjkim            *rp = r;
583280304Sjkim            if (p == NULL) {
584280304Sjkim                CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
585280304Sjkim                goto err;
586280304Sjkim            }
587280304Sjkim            if (!BUF_MEM_grow_clean(buf,
588280304Sjkim                        (strlen(p) + buf->length - (e - from)))) {
589280304Sjkim                CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
590280304Sjkim                goto err;
591280304Sjkim            }
592280304Sjkim            while (*p)
593280304Sjkim                buf->data[to++] = *(p++);
594142425Snectar
595280304Sjkim            /*
596280304Sjkim             * Since we change the pointer 'from', we also have to change the
597280304Sjkim             * perceived length of the string it points at.  /RL
598280304Sjkim             */
599280304Sjkim            len -= e - from;
600280304Sjkim            from = e;
601160814Ssimon
602280304Sjkim            /*
603280304Sjkim             * In case there were no braces or parenthesis around the
604280304Sjkim             * variable reference, we have to put back the character that was
605280304Sjkim             * replaced with a '\0'.  /RL
606280304Sjkim             */
607280304Sjkim            *rp = r;
608280304Sjkim        } else
609280304Sjkim            buf->data[to++] = *(from++);
610280304Sjkim    }
611280304Sjkim    buf->data[to] = '\0';
612280304Sjkim    if (*pto != NULL)
613280304Sjkim        OPENSSL_free(*pto);
614280304Sjkim    *pto = buf->data;
615280304Sjkim    OPENSSL_free(buf);
616280304Sjkim    return (1);
617280304Sjkim err:
618280304Sjkim    if (buf != NULL)
619280304Sjkim        BUF_MEM_free(buf);
620280304Sjkim    return (0);
621280304Sjkim}
62268651Skris
62368651Skrisstatic char *eat_ws(CONF *conf, char *p)
624280304Sjkim{
625280304Sjkim    while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
626280304Sjkim        p++;
627280304Sjkim    return (p);
628280304Sjkim}
62968651Skris
63068651Skrisstatic char *eat_alpha_numeric(CONF *conf, char *p)
631280304Sjkim{
632280304Sjkim    for (;;) {
633280304Sjkim        if (IS_ESC(conf, *p)) {
634280304Sjkim            p = scan_esc(conf, p);
635280304Sjkim            continue;
636280304Sjkim        }
637280304Sjkim        if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
638280304Sjkim            return (p);
639280304Sjkim        p++;
640280304Sjkim    }
641280304Sjkim}
64268651Skris
64368651Skrisstatic char *scan_quote(CONF *conf, char *p)
644280304Sjkim{
645280304Sjkim    int q = *p;
64668651Skris
647280304Sjkim    p++;
648280304Sjkim    while (!(IS_EOF(conf, *p)) && (*p != q)) {
649280304Sjkim        if (IS_ESC(conf, *p)) {
650280304Sjkim            p++;
651280304Sjkim            if (IS_EOF(conf, *p))
652280304Sjkim                return (p);
653280304Sjkim        }
654280304Sjkim        p++;
655280304Sjkim    }
656280304Sjkim    if (*p == q)
657280304Sjkim        p++;
658280304Sjkim    return (p);
659280304Sjkim}
66068651Skris
66168651Skrisstatic char *scan_dquote(CONF *conf, char *p)
662280304Sjkim{
663280304Sjkim    int q = *p;
66468651Skris
665280304Sjkim    p++;
666280304Sjkim    while (!(IS_EOF(conf, *p))) {
667280304Sjkim        if (*p == q) {
668280304Sjkim            if (*(p + 1) == q) {
669280304Sjkim                p++;
670280304Sjkim            } else {
671280304Sjkim                break;
672280304Sjkim            }
673280304Sjkim        }
674280304Sjkim        p++;
675280304Sjkim    }
676280304Sjkim    if (*p == q)
677280304Sjkim        p++;
678280304Sjkim    return (p);
679280304Sjkim}
68068651Skris
681238405Sjkimstatic void dump_value_doall_arg(CONF_VALUE *a, BIO *out)
682280304Sjkim{
683280304Sjkim    if (a->name)
684280304Sjkim        BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
685280304Sjkim    else
686280304Sjkim        BIO_printf(out, "[[%s]]\n", a->section);
687280304Sjkim}
68868651Skris
689238405Sjkimstatic IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
690109998Smarkm
691109998Smarkmstatic int def_dump(const CONF *conf, BIO *out)
692280304Sjkim{
693280304Sjkim    lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
694280304Sjkim                            BIO, out);
695280304Sjkim    return 1;
696280304Sjkim}
69768651Skris
698109998Smarkmstatic int def_is_number(const CONF *conf, char c)
699280304Sjkim{
700280304Sjkim    return IS_NUMBER(conf, c);
701280304Sjkim}
70268651Skris
703109998Smarkmstatic int def_to_int(const CONF *conf, char c)
704280304Sjkim{
705280304Sjkim    return c - '0';
706280304Sjkim}
707