1*cca6fc52SDaniel Fojt /* $OpenBSD: conf_def.c,v 1.33 2020/02/17 12:51:48 inoguchi Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino * All rights reserved.
4f5b1c8a1SJohn Marino *
5f5b1c8a1SJohn Marino * This package is an SSL implementation written
6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino *
9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions
11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino *
16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino * the code are not to be removed.
18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino *
23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino * are met:
26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino * must display the following acknowledgement:
33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino * being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino *
41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino * SUCH DAMAGE.
52f5b1c8a1SJohn Marino *
53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be
55f5b1c8a1SJohn Marino * copied and put under another distribution licence
56f5b1c8a1SJohn Marino * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino */
58f5b1c8a1SJohn Marino
59f5b1c8a1SJohn Marino /* Part of the code in here was originally in conf.c, which is now removed */
60f5b1c8a1SJohn Marino
61f5b1c8a1SJohn Marino #include <stdio.h>
62f5b1c8a1SJohn Marino #include <string.h>
63f5b1c8a1SJohn Marino
64f5b1c8a1SJohn Marino #include <openssl/buffer.h>
65f5b1c8a1SJohn Marino #include <openssl/conf.h>
66f5b1c8a1SJohn Marino #include <openssl/conf_api.h>
67f5b1c8a1SJohn Marino #include <openssl/err.h>
68f5b1c8a1SJohn Marino #include <openssl/lhash.h>
69f5b1c8a1SJohn Marino #include <openssl/stack.h>
70f5b1c8a1SJohn Marino
71f5b1c8a1SJohn Marino #include "conf_def.h"
72f5b1c8a1SJohn Marino
73*cca6fc52SDaniel Fojt #define MAX_CONF_VALUE_LENGTH 65536
74*cca6fc52SDaniel Fojt
75f5b1c8a1SJohn Marino static char *eat_ws(CONF *conf, char *p);
76f5b1c8a1SJohn Marino static char *eat_alpha_numeric(CONF *conf, char *p);
77f5b1c8a1SJohn Marino static void clear_comments(CONF *conf, char *p);
78f5b1c8a1SJohn Marino static int str_copy(CONF *conf, char *section, char **to, char *from);
79f5b1c8a1SJohn Marino static char *scan_quote(CONF *conf, char *p);
80f5b1c8a1SJohn Marino static char *scan_dquote(CONF *conf, char *p);
81f5b1c8a1SJohn Marino #define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
82f5b1c8a1SJohn Marino
83f5b1c8a1SJohn Marino static CONF *def_create(CONF_METHOD *meth);
84f5b1c8a1SJohn Marino static int def_init_default(CONF *conf);
85f5b1c8a1SJohn Marino static int def_init_WIN32(CONF *conf);
86f5b1c8a1SJohn Marino static int def_destroy(CONF *conf);
87f5b1c8a1SJohn Marino static int def_destroy_data(CONF *conf);
88f5b1c8a1SJohn Marino static int def_load(CONF *conf, const char *name, long *eline);
89f5b1c8a1SJohn Marino static int def_load_bio(CONF *conf, BIO *bp, long *eline);
90f5b1c8a1SJohn Marino static int def_dump(const CONF *conf, BIO *bp);
91f5b1c8a1SJohn Marino static int def_is_number(const CONF *conf, char c);
92f5b1c8a1SJohn Marino static int def_to_int(const CONF *conf, char c);
93f5b1c8a1SJohn Marino
94f5b1c8a1SJohn Marino static CONF_METHOD default_method = {
95f5b1c8a1SJohn Marino .name = "OpenSSL default",
96f5b1c8a1SJohn Marino .create = def_create,
97f5b1c8a1SJohn Marino .init = def_init_default,
98f5b1c8a1SJohn Marino .destroy = def_destroy,
99f5b1c8a1SJohn Marino .destroy_data = def_destroy_data,
100f5b1c8a1SJohn Marino .load_bio = def_load_bio,
101f5b1c8a1SJohn Marino .dump = def_dump,
102f5b1c8a1SJohn Marino .is_number = def_is_number,
103f5b1c8a1SJohn Marino .to_int = def_to_int,
104f5b1c8a1SJohn Marino .load = def_load
105f5b1c8a1SJohn Marino };
106f5b1c8a1SJohn Marino
107f5b1c8a1SJohn Marino static CONF_METHOD WIN32_method = {
108f5b1c8a1SJohn Marino "WIN32",
109f5b1c8a1SJohn Marino def_create,
110f5b1c8a1SJohn Marino def_init_WIN32,
111f5b1c8a1SJohn Marino def_destroy,
112f5b1c8a1SJohn Marino def_destroy_data,
113f5b1c8a1SJohn Marino def_load_bio,
114f5b1c8a1SJohn Marino def_dump,
115f5b1c8a1SJohn Marino def_is_number,
116f5b1c8a1SJohn Marino def_to_int,
117f5b1c8a1SJohn Marino def_load
118f5b1c8a1SJohn Marino };
119f5b1c8a1SJohn Marino
120f5b1c8a1SJohn Marino CONF_METHOD *
NCONF_default(void)121f5b1c8a1SJohn Marino NCONF_default(void)
122f5b1c8a1SJohn Marino {
123f5b1c8a1SJohn Marino return &default_method;
124f5b1c8a1SJohn Marino }
125f5b1c8a1SJohn Marino
126f5b1c8a1SJohn Marino CONF_METHOD *
NCONF_WIN32(void)127f5b1c8a1SJohn Marino NCONF_WIN32(void)
128f5b1c8a1SJohn Marino {
129f5b1c8a1SJohn Marino return &WIN32_method;
130f5b1c8a1SJohn Marino }
131f5b1c8a1SJohn Marino
132f5b1c8a1SJohn Marino static CONF *
def_create(CONF_METHOD * meth)133f5b1c8a1SJohn Marino def_create(CONF_METHOD *meth)
134f5b1c8a1SJohn Marino {
135f5b1c8a1SJohn Marino CONF *ret;
136f5b1c8a1SJohn Marino
137f5b1c8a1SJohn Marino ret = malloc(sizeof(CONF) + sizeof(unsigned short *));
138f5b1c8a1SJohn Marino if (ret)
139f5b1c8a1SJohn Marino if (meth->init(ret) == 0) {
140f5b1c8a1SJohn Marino free(ret);
141f5b1c8a1SJohn Marino ret = NULL;
142f5b1c8a1SJohn Marino }
143f5b1c8a1SJohn Marino return ret;
144f5b1c8a1SJohn Marino }
145f5b1c8a1SJohn Marino
146f5b1c8a1SJohn Marino static int
def_init_default(CONF * conf)147f5b1c8a1SJohn Marino def_init_default(CONF *conf)
148f5b1c8a1SJohn Marino {
149f5b1c8a1SJohn Marino if (conf == NULL)
150f5b1c8a1SJohn Marino return 0;
151f5b1c8a1SJohn Marino
152f5b1c8a1SJohn Marino conf->meth = &default_method;
153f5b1c8a1SJohn Marino conf->meth_data = CONF_type_default;
154f5b1c8a1SJohn Marino conf->data = NULL;
155f5b1c8a1SJohn Marino
156f5b1c8a1SJohn Marino return 1;
157f5b1c8a1SJohn Marino }
158f5b1c8a1SJohn Marino
159f5b1c8a1SJohn Marino static int
def_init_WIN32(CONF * conf)160f5b1c8a1SJohn Marino def_init_WIN32(CONF *conf)
161f5b1c8a1SJohn Marino {
162f5b1c8a1SJohn Marino if (conf == NULL)
163f5b1c8a1SJohn Marino return 0;
164f5b1c8a1SJohn Marino
165f5b1c8a1SJohn Marino conf->meth = &WIN32_method;
166f5b1c8a1SJohn Marino conf->meth_data = (void *)CONF_type_win32;
167f5b1c8a1SJohn Marino conf->data = NULL;
168f5b1c8a1SJohn Marino
169f5b1c8a1SJohn Marino return 1;
170f5b1c8a1SJohn Marino }
171f5b1c8a1SJohn Marino
172f5b1c8a1SJohn Marino static int
def_destroy(CONF * conf)173f5b1c8a1SJohn Marino def_destroy(CONF *conf)
174f5b1c8a1SJohn Marino {
175f5b1c8a1SJohn Marino if (def_destroy_data(conf)) {
176f5b1c8a1SJohn Marino free(conf);
177f5b1c8a1SJohn Marino return 1;
178f5b1c8a1SJohn Marino }
179f5b1c8a1SJohn Marino return 0;
180f5b1c8a1SJohn Marino }
181f5b1c8a1SJohn Marino
182f5b1c8a1SJohn Marino static int
def_destroy_data(CONF * conf)183f5b1c8a1SJohn Marino def_destroy_data(CONF *conf)
184f5b1c8a1SJohn Marino {
185f5b1c8a1SJohn Marino if (conf == NULL)
186f5b1c8a1SJohn Marino return 0;
187f5b1c8a1SJohn Marino _CONF_free_data(conf);
188f5b1c8a1SJohn Marino return 1;
189f5b1c8a1SJohn Marino }
190f5b1c8a1SJohn Marino
191f5b1c8a1SJohn Marino static int
def_load(CONF * conf,const char * name,long * line)192f5b1c8a1SJohn Marino def_load(CONF *conf, const char *name, long *line)
193f5b1c8a1SJohn Marino {
194f5b1c8a1SJohn Marino int ret;
195f5b1c8a1SJohn Marino BIO *in = NULL;
196f5b1c8a1SJohn Marino
197f5b1c8a1SJohn Marino in = BIO_new_file(name, "rb");
198f5b1c8a1SJohn Marino if (in == NULL) {
199f5b1c8a1SJohn Marino if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
20072c33676SMaxim Ag CONFerror(CONF_R_NO_SUCH_FILE);
201f5b1c8a1SJohn Marino else
20272c33676SMaxim Ag CONFerror(ERR_R_SYS_LIB);
203f5b1c8a1SJohn Marino return 0;
204f5b1c8a1SJohn Marino }
205f5b1c8a1SJohn Marino
206f5b1c8a1SJohn Marino ret = def_load_bio(conf, in, line);
207f5b1c8a1SJohn Marino BIO_free(in);
208f5b1c8a1SJohn Marino
209f5b1c8a1SJohn Marino return ret;
210f5b1c8a1SJohn Marino }
211f5b1c8a1SJohn Marino
212f5b1c8a1SJohn Marino static int
def_load_bio(CONF * conf,BIO * in,long * line)213f5b1c8a1SJohn Marino def_load_bio(CONF *conf, BIO *in, long *line)
214f5b1c8a1SJohn Marino {
215f5b1c8a1SJohn Marino /* The macro BUFSIZE conflicts with a system macro in VxWorks */
216f5b1c8a1SJohn Marino #define CONFBUFSIZE 512
217f5b1c8a1SJohn Marino int bufnum = 0, i, ii;
218f5b1c8a1SJohn Marino BUF_MEM *buff = NULL;
219f5b1c8a1SJohn Marino char *s, *p, *end;
220f5b1c8a1SJohn Marino int again;
221f5b1c8a1SJohn Marino long eline = 0;
222f5b1c8a1SJohn Marino CONF_VALUE *v = NULL, *tv;
223f5b1c8a1SJohn Marino CONF_VALUE *sv = NULL;
224f5b1c8a1SJohn Marino char *section = NULL, *buf;
225f5b1c8a1SJohn Marino char *start, *psection, *pname;
226f5b1c8a1SJohn Marino void *h = (void *)(conf->data);
227f5b1c8a1SJohn Marino
228f5b1c8a1SJohn Marino if ((buff = BUF_MEM_new()) == NULL) {
22972c33676SMaxim Ag CONFerror(ERR_R_BUF_LIB);
230f5b1c8a1SJohn Marino goto err;
231f5b1c8a1SJohn Marino }
232f5b1c8a1SJohn Marino
233f5b1c8a1SJohn Marino section = strdup("default");
234f5b1c8a1SJohn Marino if (section == NULL) {
23572c33676SMaxim Ag CONFerror(ERR_R_MALLOC_FAILURE);
236f5b1c8a1SJohn Marino goto err;
237f5b1c8a1SJohn Marino }
238f5b1c8a1SJohn Marino
239f5b1c8a1SJohn Marino if (_CONF_new_data(conf) == 0) {
24072c33676SMaxim Ag CONFerror(ERR_R_MALLOC_FAILURE);
241f5b1c8a1SJohn Marino goto err;
242f5b1c8a1SJohn Marino }
243f5b1c8a1SJohn Marino
244f5b1c8a1SJohn Marino sv = _CONF_new_section(conf, section);
245f5b1c8a1SJohn Marino if (sv == NULL) {
24672c33676SMaxim Ag CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
247f5b1c8a1SJohn Marino goto err;
248f5b1c8a1SJohn Marino }
249f5b1c8a1SJohn Marino
250f5b1c8a1SJohn Marino bufnum = 0;
251f5b1c8a1SJohn Marino again = 0;
252f5b1c8a1SJohn Marino for (;;) {
253f5b1c8a1SJohn Marino if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
25472c33676SMaxim Ag CONFerror(ERR_R_BUF_LIB);
255f5b1c8a1SJohn Marino goto err;
256f5b1c8a1SJohn Marino }
257f5b1c8a1SJohn Marino p = &(buff->data[bufnum]);
258f5b1c8a1SJohn Marino *p = '\0';
259f5b1c8a1SJohn Marino BIO_gets(in, p, CONFBUFSIZE - 1);
260f5b1c8a1SJohn Marino p[CONFBUFSIZE - 1] = '\0';
261f5b1c8a1SJohn Marino ii = i = strlen(p);
262f5b1c8a1SJohn Marino if (i == 0 && !again)
263f5b1c8a1SJohn Marino break;
264f5b1c8a1SJohn Marino again = 0;
265f5b1c8a1SJohn Marino while (i > 0) {
266f5b1c8a1SJohn Marino if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
267f5b1c8a1SJohn Marino break;
268f5b1c8a1SJohn Marino else
269f5b1c8a1SJohn Marino i--;
270f5b1c8a1SJohn Marino }
271f5b1c8a1SJohn Marino /* we removed some trailing stuff so there is a new
272f5b1c8a1SJohn Marino * line on the end. */
273f5b1c8a1SJohn Marino if (ii && i == ii)
274f5b1c8a1SJohn Marino again = 1; /* long line */
275f5b1c8a1SJohn Marino else {
276f5b1c8a1SJohn Marino p[i] = '\0';
277f5b1c8a1SJohn Marino eline++; /* another input line */
278f5b1c8a1SJohn Marino }
279f5b1c8a1SJohn Marino
280f5b1c8a1SJohn Marino /* we now have a line with trailing \r\n removed */
281f5b1c8a1SJohn Marino
282f5b1c8a1SJohn Marino /* i is the number of bytes */
283f5b1c8a1SJohn Marino bufnum += i;
284f5b1c8a1SJohn Marino
285f5b1c8a1SJohn Marino v = NULL;
286f5b1c8a1SJohn Marino /* check for line continuation */
287f5b1c8a1SJohn Marino if (bufnum >= 1) {
288f5b1c8a1SJohn Marino /* If we have bytes and the last char '\\' and
289f5b1c8a1SJohn Marino * second last char is not '\\' */
290f5b1c8a1SJohn Marino p = &(buff->data[bufnum - 1]);
291f5b1c8a1SJohn Marino if (IS_ESC(conf, p[0]) &&
292f5b1c8a1SJohn Marino ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
293f5b1c8a1SJohn Marino bufnum--;
294f5b1c8a1SJohn Marino again = 1;
295f5b1c8a1SJohn Marino }
296f5b1c8a1SJohn Marino }
297f5b1c8a1SJohn Marino if (again)
298f5b1c8a1SJohn Marino continue;
299f5b1c8a1SJohn Marino bufnum = 0;
300f5b1c8a1SJohn Marino buf = buff->data;
301f5b1c8a1SJohn Marino
302f5b1c8a1SJohn Marino clear_comments(conf, buf);
303f5b1c8a1SJohn Marino s = eat_ws(conf, buf);
304f5b1c8a1SJohn Marino if (IS_EOF(conf, *s))
305f5b1c8a1SJohn Marino continue; /* blank line */
306f5b1c8a1SJohn Marino if (*s == '[') {
307f5b1c8a1SJohn Marino char *ss;
308f5b1c8a1SJohn Marino
309f5b1c8a1SJohn Marino s++;
310f5b1c8a1SJohn Marino start = eat_ws(conf, s);
311f5b1c8a1SJohn Marino ss = start;
312f5b1c8a1SJohn Marino again:
313f5b1c8a1SJohn Marino end = eat_alpha_numeric(conf, ss);
314f5b1c8a1SJohn Marino p = eat_ws(conf, end);
315f5b1c8a1SJohn Marino if (*p != ']') {
316f5b1c8a1SJohn Marino if (*p != '\0' && ss != p) {
317f5b1c8a1SJohn Marino ss = p;
318f5b1c8a1SJohn Marino goto again;
319f5b1c8a1SJohn Marino }
32072c33676SMaxim Ag CONFerror(CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
321f5b1c8a1SJohn Marino goto err;
322f5b1c8a1SJohn Marino }
323f5b1c8a1SJohn Marino *end = '\0';
324f5b1c8a1SJohn Marino if (!str_copy(conf, NULL, §ion, start))
325f5b1c8a1SJohn Marino goto err;
326f5b1c8a1SJohn Marino if ((sv = _CONF_get_section(conf, section)) == NULL)
327f5b1c8a1SJohn Marino sv = _CONF_new_section(conf, section);
328f5b1c8a1SJohn Marino if (sv == NULL) {
32972c33676SMaxim Ag CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
330f5b1c8a1SJohn Marino goto err;
331f5b1c8a1SJohn Marino }
332f5b1c8a1SJohn Marino continue;
333f5b1c8a1SJohn Marino } else {
334f5b1c8a1SJohn Marino pname = s;
335f5b1c8a1SJohn Marino psection = NULL;
336f5b1c8a1SJohn Marino end = eat_alpha_numeric(conf, s);
337f5b1c8a1SJohn Marino if ((end[0] == ':') && (end[1] == ':')) {
338f5b1c8a1SJohn Marino *end = '\0';
339f5b1c8a1SJohn Marino end += 2;
340f5b1c8a1SJohn Marino psection = pname;
341f5b1c8a1SJohn Marino pname = end;
342f5b1c8a1SJohn Marino end = eat_alpha_numeric(conf, end);
343f5b1c8a1SJohn Marino }
344f5b1c8a1SJohn Marino p = eat_ws(conf, end);
345f5b1c8a1SJohn Marino if (*p != '=') {
34672c33676SMaxim Ag CONFerror(CONF_R_MISSING_EQUAL_SIGN);
347f5b1c8a1SJohn Marino goto err;
348f5b1c8a1SJohn Marino }
349f5b1c8a1SJohn Marino *end = '\0';
350f5b1c8a1SJohn Marino p++;
351f5b1c8a1SJohn Marino start = eat_ws(conf, p);
352f5b1c8a1SJohn Marino while (!IS_EOF(conf, *p))
353f5b1c8a1SJohn Marino p++;
354f5b1c8a1SJohn Marino p--;
355f5b1c8a1SJohn Marino while ((p != start) && (IS_WS(conf, *p)))
356f5b1c8a1SJohn Marino p--;
357f5b1c8a1SJohn Marino p++;
358f5b1c8a1SJohn Marino *p = '\0';
359f5b1c8a1SJohn Marino
360f5b1c8a1SJohn Marino if (!(v = malloc(sizeof(CONF_VALUE)))) {
36172c33676SMaxim Ag CONFerror(ERR_R_MALLOC_FAILURE);
362f5b1c8a1SJohn Marino goto err;
363f5b1c8a1SJohn Marino }
364f5b1c8a1SJohn Marino if (psection == NULL)
365f5b1c8a1SJohn Marino psection = section;
366f5b1c8a1SJohn Marino v->name = strdup(pname);
367f5b1c8a1SJohn Marino v->value = NULL;
368f5b1c8a1SJohn Marino if (v->name == NULL) {
36972c33676SMaxim Ag CONFerror(ERR_R_MALLOC_FAILURE);
370f5b1c8a1SJohn Marino goto err;
371f5b1c8a1SJohn Marino }
372f5b1c8a1SJohn Marino if (!str_copy(conf, psection, &(v->value), start))
373f5b1c8a1SJohn Marino goto err;
374f5b1c8a1SJohn Marino
375f5b1c8a1SJohn Marino if (strcmp(psection, section) != 0) {
376f5b1c8a1SJohn Marino if ((tv = _CONF_get_section(conf, psection))
377f5b1c8a1SJohn Marino == NULL)
378f5b1c8a1SJohn Marino tv = _CONF_new_section(conf, psection);
379f5b1c8a1SJohn Marino if (tv == NULL) {
38072c33676SMaxim Ag CONFerror(CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
381f5b1c8a1SJohn Marino goto err;
382f5b1c8a1SJohn Marino }
383f5b1c8a1SJohn Marino } else
384f5b1c8a1SJohn Marino tv = sv;
385f5b1c8a1SJohn Marino
386f5b1c8a1SJohn Marino if (_CONF_add_string(conf, tv, v) == 0) {
38772c33676SMaxim Ag CONFerror(ERR_R_MALLOC_FAILURE);
388f5b1c8a1SJohn Marino goto err;
389f5b1c8a1SJohn Marino }
390f5b1c8a1SJohn Marino v = NULL;
391f5b1c8a1SJohn Marino }
392f5b1c8a1SJohn Marino }
393f5b1c8a1SJohn Marino if (buff != NULL)
394f5b1c8a1SJohn Marino BUF_MEM_free(buff);
395f5b1c8a1SJohn Marino free(section);
396f5b1c8a1SJohn Marino return (1);
397f5b1c8a1SJohn Marino
398f5b1c8a1SJohn Marino err:
399f5b1c8a1SJohn Marino if (buff != NULL)
400f5b1c8a1SJohn Marino BUF_MEM_free(buff);
401f5b1c8a1SJohn Marino free(section);
402f5b1c8a1SJohn Marino if (line != NULL)
403f5b1c8a1SJohn Marino *line = eline;
404f5b1c8a1SJohn Marino ERR_asprintf_error_data("line %ld", eline);
405f5b1c8a1SJohn Marino if ((h != conf->data) && (conf->data != NULL)) {
406f5b1c8a1SJohn Marino CONF_free(conf->data);
407f5b1c8a1SJohn Marino conf->data = NULL;
408f5b1c8a1SJohn Marino }
409f5b1c8a1SJohn Marino if (v != NULL) {
410f5b1c8a1SJohn Marino free(v->name);
411f5b1c8a1SJohn Marino free(v->value);
412f5b1c8a1SJohn Marino free(v);
413f5b1c8a1SJohn Marino }
414f5b1c8a1SJohn Marino return (0);
415f5b1c8a1SJohn Marino }
416f5b1c8a1SJohn Marino
417f5b1c8a1SJohn Marino static void
clear_comments(CONF * conf,char * p)418f5b1c8a1SJohn Marino clear_comments(CONF *conf, char *p)
419f5b1c8a1SJohn Marino {
420f5b1c8a1SJohn Marino for (;;) {
421f5b1c8a1SJohn Marino if (IS_FCOMMENT(conf, *p)) {
422f5b1c8a1SJohn Marino *p = '\0';
423f5b1c8a1SJohn Marino return;
424f5b1c8a1SJohn Marino }
425f5b1c8a1SJohn Marino if (!IS_WS(conf, *p)) {
426f5b1c8a1SJohn Marino break;
427f5b1c8a1SJohn Marino }
428f5b1c8a1SJohn Marino p++;
429f5b1c8a1SJohn Marino }
430f5b1c8a1SJohn Marino
431f5b1c8a1SJohn Marino for (;;) {
432f5b1c8a1SJohn Marino if (IS_COMMENT(conf, *p)) {
433f5b1c8a1SJohn Marino *p = '\0';
434f5b1c8a1SJohn Marino return;
435f5b1c8a1SJohn Marino }
436f5b1c8a1SJohn Marino if (IS_DQUOTE(conf, *p)) {
437f5b1c8a1SJohn Marino p = scan_dquote(conf, p);
438f5b1c8a1SJohn Marino continue;
439f5b1c8a1SJohn Marino }
440f5b1c8a1SJohn Marino if (IS_QUOTE(conf, *p)) {
441f5b1c8a1SJohn Marino p = scan_quote(conf, p);
442f5b1c8a1SJohn Marino continue;
443f5b1c8a1SJohn Marino }
444f5b1c8a1SJohn Marino if (IS_ESC(conf, *p)) {
445f5b1c8a1SJohn Marino p = scan_esc(conf, p);
446f5b1c8a1SJohn Marino continue;
447f5b1c8a1SJohn Marino }
448f5b1c8a1SJohn Marino if (IS_EOF(conf, *p))
449f5b1c8a1SJohn Marino return;
450f5b1c8a1SJohn Marino else
451f5b1c8a1SJohn Marino p++;
452f5b1c8a1SJohn Marino }
453f5b1c8a1SJohn Marino }
454f5b1c8a1SJohn Marino
455f5b1c8a1SJohn Marino static int
str_copy(CONF * conf,char * section,char ** pto,char * from)456f5b1c8a1SJohn Marino str_copy(CONF *conf, char *section, char **pto, char *from)
457f5b1c8a1SJohn Marino {
458f5b1c8a1SJohn Marino int q, r,rr = 0, to = 0, len = 0;
459f5b1c8a1SJohn Marino char *s, *e, *rp, *p, *rrp, *np, *cp, v;
460*cca6fc52SDaniel Fojt size_t newsize;
461f5b1c8a1SJohn Marino BUF_MEM *buf;
462f5b1c8a1SJohn Marino
463f5b1c8a1SJohn Marino if ((buf = BUF_MEM_new()) == NULL)
464f5b1c8a1SJohn Marino return (0);
465f5b1c8a1SJohn Marino
466f5b1c8a1SJohn Marino len = strlen(from) + 1;
467f5b1c8a1SJohn Marino if (!BUF_MEM_grow(buf, len))
468f5b1c8a1SJohn Marino goto err;
469f5b1c8a1SJohn Marino
470f5b1c8a1SJohn Marino for (;;) {
471f5b1c8a1SJohn Marino if (IS_QUOTE(conf, *from)) {
472f5b1c8a1SJohn Marino q = *from;
473f5b1c8a1SJohn Marino from++;
474f5b1c8a1SJohn Marino while (!IS_EOF(conf, *from) && (*from != q)) {
475f5b1c8a1SJohn Marino if (IS_ESC(conf, *from)) {
476f5b1c8a1SJohn Marino from++;
477f5b1c8a1SJohn Marino if (IS_EOF(conf, *from))
478f5b1c8a1SJohn Marino break;
479f5b1c8a1SJohn Marino }
480f5b1c8a1SJohn Marino buf->data[to++] = *(from++);
481f5b1c8a1SJohn Marino }
482f5b1c8a1SJohn Marino if (*from == q)
483f5b1c8a1SJohn Marino from++;
484f5b1c8a1SJohn Marino } else if (IS_DQUOTE(conf, *from)) {
485f5b1c8a1SJohn Marino q = *from;
486f5b1c8a1SJohn Marino from++;
487f5b1c8a1SJohn Marino while (!IS_EOF(conf, *from)) {
488f5b1c8a1SJohn Marino if (*from == q) {
489f5b1c8a1SJohn Marino if (*(from + 1) == q) {
490f5b1c8a1SJohn Marino from++;
491f5b1c8a1SJohn Marino } else {
492f5b1c8a1SJohn Marino break;
493f5b1c8a1SJohn Marino }
494f5b1c8a1SJohn Marino }
495f5b1c8a1SJohn Marino buf->data[to++] = *(from++);
496f5b1c8a1SJohn Marino }
497f5b1c8a1SJohn Marino if (*from == q)
498f5b1c8a1SJohn Marino from++;
499f5b1c8a1SJohn Marino } else if (IS_ESC(conf, *from)) {
500f5b1c8a1SJohn Marino from++;
501f5b1c8a1SJohn Marino v = *(from++);
502f5b1c8a1SJohn Marino if (IS_EOF(conf, v))
503f5b1c8a1SJohn Marino break;
504f5b1c8a1SJohn Marino else if (v == 'r')
505f5b1c8a1SJohn Marino v = '\r';
506f5b1c8a1SJohn Marino else if (v == 'n')
507f5b1c8a1SJohn Marino v = '\n';
508f5b1c8a1SJohn Marino else if (v == 'b')
509f5b1c8a1SJohn Marino v = '\b';
510f5b1c8a1SJohn Marino else if (v == 't')
511f5b1c8a1SJohn Marino v = '\t';
512f5b1c8a1SJohn Marino buf->data[to++] = v;
513f5b1c8a1SJohn Marino } else if (IS_EOF(conf, *from))
514f5b1c8a1SJohn Marino break;
515f5b1c8a1SJohn Marino else if (*from == '$') {
516f5b1c8a1SJohn Marino /* try to expand it */
517f5b1c8a1SJohn Marino rrp = NULL;
518f5b1c8a1SJohn Marino s = &(from[1]);
519f5b1c8a1SJohn Marino if (*s == '{')
520f5b1c8a1SJohn Marino q = '}';
521f5b1c8a1SJohn Marino else if (*s == '(')
522f5b1c8a1SJohn Marino q = ')';
523f5b1c8a1SJohn Marino else
524f5b1c8a1SJohn Marino q = 0;
525f5b1c8a1SJohn Marino
526f5b1c8a1SJohn Marino if (q)
527f5b1c8a1SJohn Marino s++;
528f5b1c8a1SJohn Marino cp = section;
529f5b1c8a1SJohn Marino e = np = s;
530f5b1c8a1SJohn Marino while (IS_ALPHA_NUMERIC(conf, *e))
531f5b1c8a1SJohn Marino e++;
532f5b1c8a1SJohn Marino if ((e[0] == ':') && (e[1] == ':')) {
533f5b1c8a1SJohn Marino cp = np;
534f5b1c8a1SJohn Marino rrp = e;
535f5b1c8a1SJohn Marino rr = *e;
536f5b1c8a1SJohn Marino *rrp = '\0';
537f5b1c8a1SJohn Marino e += 2;
538f5b1c8a1SJohn Marino np = e;
539f5b1c8a1SJohn Marino while (IS_ALPHA_NUMERIC(conf, *e))
540f5b1c8a1SJohn Marino e++;
541f5b1c8a1SJohn Marino }
542f5b1c8a1SJohn Marino r = *e;
543f5b1c8a1SJohn Marino *e = '\0';
544f5b1c8a1SJohn Marino rp = e;
545f5b1c8a1SJohn Marino if (q) {
546f5b1c8a1SJohn Marino if (r != q) {
54772c33676SMaxim Ag CONFerror(CONF_R_NO_CLOSE_BRACE);
548f5b1c8a1SJohn Marino goto err;
549f5b1c8a1SJohn Marino }
550f5b1c8a1SJohn Marino e++;
551f5b1c8a1SJohn Marino }
552f5b1c8a1SJohn Marino /* So at this point we have
553f5b1c8a1SJohn Marino * np which is the start of the name string which is
554f5b1c8a1SJohn Marino * '\0' terminated.
555f5b1c8a1SJohn Marino * cp which is the start of the section string which is
556f5b1c8a1SJohn Marino * '\0' terminated.
557f5b1c8a1SJohn Marino * e is the 'next point after'.
558f5b1c8a1SJohn Marino * r and rr are the chars replaced by the '\0'
559f5b1c8a1SJohn Marino * rp and rrp is where 'r' and 'rr' came from.
560f5b1c8a1SJohn Marino */
561f5b1c8a1SJohn Marino p = _CONF_get_string(conf, cp, np);
562f5b1c8a1SJohn Marino if (rrp != NULL)
563f5b1c8a1SJohn Marino *rrp = rr;
564f5b1c8a1SJohn Marino *rp = r;
565f5b1c8a1SJohn Marino if (p == NULL) {
56672c33676SMaxim Ag CONFerror(CONF_R_VARIABLE_HAS_NO_VALUE);
567f5b1c8a1SJohn Marino goto err;
568f5b1c8a1SJohn Marino }
569*cca6fc52SDaniel Fojt newsize = strlen(p) + buf->length - (e - from);
570*cca6fc52SDaniel Fojt if (newsize > MAX_CONF_VALUE_LENGTH) {
571*cca6fc52SDaniel Fojt CONFerror(CONF_R_VARIABLE_EXPANSION_TOO_LONG);
572*cca6fc52SDaniel Fojt goto err;
573*cca6fc52SDaniel Fojt }
574*cca6fc52SDaniel Fojt if (!BUF_MEM_grow_clean(buf, newsize)) {
57572c33676SMaxim Ag CONFerror(CONF_R_MODULE_INITIALIZATION_ERROR);
576f5b1c8a1SJohn Marino goto err;
577f5b1c8a1SJohn Marino }
578f5b1c8a1SJohn Marino while (*p)
579f5b1c8a1SJohn Marino buf->data[to++] = *(p++);
580f5b1c8a1SJohn Marino
581f5b1c8a1SJohn Marino /* Since we change the pointer 'from', we also have
582f5b1c8a1SJohn Marino to change the perceived length of the string it
583f5b1c8a1SJohn Marino points at. /RL */
584f5b1c8a1SJohn Marino len -= e - from;
585f5b1c8a1SJohn Marino from = e;
586f5b1c8a1SJohn Marino
587f5b1c8a1SJohn Marino /* In case there were no braces or parenthesis around
588f5b1c8a1SJohn Marino the variable reference, we have to put back the
589f5b1c8a1SJohn Marino character that was replaced with a '\0'. /RL */
590f5b1c8a1SJohn Marino *rp = r;
591f5b1c8a1SJohn Marino } else
592f5b1c8a1SJohn Marino buf->data[to++] = *(from++);
593f5b1c8a1SJohn Marino }
594f5b1c8a1SJohn Marino buf->data[to]='\0';
595f5b1c8a1SJohn Marino free(*pto);
596f5b1c8a1SJohn Marino *pto = buf->data;
597f5b1c8a1SJohn Marino free(buf);
598f5b1c8a1SJohn Marino return (1);
599f5b1c8a1SJohn Marino
600f5b1c8a1SJohn Marino err:
601f5b1c8a1SJohn Marino if (buf != NULL)
602f5b1c8a1SJohn Marino BUF_MEM_free(buf);
603f5b1c8a1SJohn Marino return (0);
604f5b1c8a1SJohn Marino }
605f5b1c8a1SJohn Marino
606f5b1c8a1SJohn Marino static char *
eat_ws(CONF * conf,char * p)607f5b1c8a1SJohn Marino eat_ws(CONF *conf, char *p)
608f5b1c8a1SJohn Marino {
609f5b1c8a1SJohn Marino while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
610f5b1c8a1SJohn Marino p++;
611f5b1c8a1SJohn Marino return (p);
612f5b1c8a1SJohn Marino }
613f5b1c8a1SJohn Marino
614f5b1c8a1SJohn Marino static char *
eat_alpha_numeric(CONF * conf,char * p)615f5b1c8a1SJohn Marino eat_alpha_numeric(CONF *conf, char *p)
616f5b1c8a1SJohn Marino {
617f5b1c8a1SJohn Marino for (;;) {
618f5b1c8a1SJohn Marino if (IS_ESC(conf, *p)) {
619f5b1c8a1SJohn Marino p = scan_esc(conf, p);
620f5b1c8a1SJohn Marino continue;
621f5b1c8a1SJohn Marino }
622f5b1c8a1SJohn Marino if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
623f5b1c8a1SJohn Marino return (p);
624f5b1c8a1SJohn Marino p++;
625f5b1c8a1SJohn Marino }
626f5b1c8a1SJohn Marino }
627f5b1c8a1SJohn Marino
628f5b1c8a1SJohn Marino static char *
scan_quote(CONF * conf,char * p)629f5b1c8a1SJohn Marino scan_quote(CONF *conf, char *p)
630f5b1c8a1SJohn Marino {
631f5b1c8a1SJohn Marino int q = *p;
632f5b1c8a1SJohn Marino
633f5b1c8a1SJohn Marino p++;
634f5b1c8a1SJohn Marino while (!(IS_EOF(conf, *p)) && (*p != q)) {
635f5b1c8a1SJohn Marino if (IS_ESC(conf, *p)) {
636f5b1c8a1SJohn Marino p++;
637f5b1c8a1SJohn Marino if (IS_EOF(conf, *p))
638f5b1c8a1SJohn Marino return (p);
639f5b1c8a1SJohn Marino }
640f5b1c8a1SJohn Marino p++;
641f5b1c8a1SJohn Marino }
642f5b1c8a1SJohn Marino if (*p == q)
643f5b1c8a1SJohn Marino p++;
644f5b1c8a1SJohn Marino return (p);
645f5b1c8a1SJohn Marino }
646f5b1c8a1SJohn Marino
647f5b1c8a1SJohn Marino
648f5b1c8a1SJohn Marino static char *
scan_dquote(CONF * conf,char * p)649f5b1c8a1SJohn Marino scan_dquote(CONF *conf, char *p)
650f5b1c8a1SJohn Marino {
651f5b1c8a1SJohn Marino int q = *p;
652f5b1c8a1SJohn Marino
653f5b1c8a1SJohn Marino p++;
654f5b1c8a1SJohn Marino while (!(IS_EOF(conf, *p))) {
655f5b1c8a1SJohn Marino if (*p == q) {
656f5b1c8a1SJohn Marino if (*(p + 1) == q) {
657f5b1c8a1SJohn Marino p++;
658f5b1c8a1SJohn Marino } else {
659f5b1c8a1SJohn Marino break;
660f5b1c8a1SJohn Marino }
661f5b1c8a1SJohn Marino }
662f5b1c8a1SJohn Marino p++;
663f5b1c8a1SJohn Marino }
664f5b1c8a1SJohn Marino if (*p == q)
665f5b1c8a1SJohn Marino p++;
666f5b1c8a1SJohn Marino return (p);
667f5b1c8a1SJohn Marino }
668f5b1c8a1SJohn Marino
669f5b1c8a1SJohn Marino static void
dump_value_doall_arg(CONF_VALUE * a,BIO * out)670f5b1c8a1SJohn Marino dump_value_doall_arg(CONF_VALUE *a, BIO *out)
671f5b1c8a1SJohn Marino {
672f5b1c8a1SJohn Marino if (a->name)
673f5b1c8a1SJohn Marino BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
674f5b1c8a1SJohn Marino else
675f5b1c8a1SJohn Marino BIO_printf(out, "[[%s]]\n", a->section);
676f5b1c8a1SJohn Marino }
677f5b1c8a1SJohn Marino
IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value,CONF_VALUE,BIO)678f5b1c8a1SJohn Marino static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
679f5b1c8a1SJohn Marino
680f5b1c8a1SJohn Marino static int
681f5b1c8a1SJohn Marino def_dump(const CONF *conf, BIO *out)
682f5b1c8a1SJohn Marino {
683f5b1c8a1SJohn Marino lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
684f5b1c8a1SJohn Marino BIO, out);
685f5b1c8a1SJohn Marino return 1;
686f5b1c8a1SJohn Marino }
687f5b1c8a1SJohn Marino
688f5b1c8a1SJohn Marino static int
def_is_number(const CONF * conf,char c)689f5b1c8a1SJohn Marino def_is_number(const CONF *conf, char c)
690f5b1c8a1SJohn Marino {
691f5b1c8a1SJohn Marino return IS_NUMBER(conf, c);
692f5b1c8a1SJohn Marino }
693f5b1c8a1SJohn Marino
694f5b1c8a1SJohn Marino static int
def_to_int(const CONF * conf,char c)695f5b1c8a1SJohn Marino def_to_int(const CONF *conf, char c)
696f5b1c8a1SJohn Marino {
697f5b1c8a1SJohn Marino return c - '0';
698f5b1c8a1SJohn Marino }
699