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