]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/conf/conf_def.c
Corrected missing definitions from NonStop SPT build.
[thirdparty/openssl.git] / crypto / conf / conf_def.c
CommitLineData
62867571 1/*
4333b89f 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
2044d382 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
d86b6915
RL
10/* Part of the code in here was originally in conf.c, which is now removed */
11
d02b48c6 12#include <stdio.h>
9887c71c 13#include <string.h>
08073700
RB
14#ifdef __TANDEM
15# include <strings.h> /* strcasecmp */
650c6687
RB
16# include <sys/types.h> /* needed for stat.h */
17# include <sys/stat.h> /* struct stat */
08073700 18#endif
b39fc560 19#include "internal/cryptlib.h"
b524b808 20#include "internal/o_dir.h"
ec577822
BM
21#include <openssl/lhash.h>
22#include <openssl/conf.h>
d86b6915
RL
23#include <openssl/conf_api.h>
24#include "conf_def.h"
ec577822
BM
25#include <openssl/buffer.h>
26#include <openssl/err.h>
b524b808
TM
27#ifndef OPENSSL_NO_POSIX_IO
28# include <sys/stat.h>
29# ifdef _WIN32
30# define stat _stat
31# define strcasecmp _stricmp
32# endif
33#endif
d02b48c6 34
f20aa69e
AP
35#ifndef S_ISDIR
36# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
37#endif
38
8a585601
MC
39/*
40 * The maximum length we can grow a value to after variable expansion. 64k
41 * should be more than enough for all reasonable uses.
42 */
43#define MAX_CONF_VALUE_LENGTH 65536
44
a9b7a06e 45static int is_keytype(const CONF *conf, char c, unsigned short type);
d86b6915 46static char *eat_ws(CONF *conf, char *p);
b524b808 47static void trim_ws(CONF *conf, char *start);
d86b6915
RL
48static char *eat_alpha_numeric(CONF *conf, char *p);
49static void clear_comments(CONF *conf, char *p);
0f113f3e 50static int str_copy(CONF *conf, char *section, char **to, char *from);
d86b6915
RL
51static char *scan_quote(CONF *conf, char *p);
52static char *scan_dquote(CONF *conf, char *p);
0f113f3e 53#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
b524b808
TM
54#ifndef OPENSSL_NO_POSIX_IO
55static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
56 char **dirpath);
57static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx);
58#endif
d86b6915
RL
59
60static CONF *def_create(CONF_METHOD *meth);
61static int def_init_default(CONF *conf);
936c2b9e 62#ifndef OPENSSL_NO_DEPRECATED_3_0
d86b6915 63static int def_init_WIN32(CONF *conf);
7cfc0a55 64#endif
d86b6915
RL
65static int def_destroy(CONF *conf);
66static int def_destroy_data(CONF *conf);
befb3e7a
RL
67static int def_load(CONF *conf, const char *name, long *eline);
68static int def_load_bio(CONF *conf, BIO *bp, long *eline);
9dd5ae65
BL
69static int def_dump(const CONF *conf, BIO *bp);
70static int def_is_number(const CONF *conf, char c);
71static int def_to_int(const CONF *conf, char c);
d86b6915 72
d86b6915 73static CONF_METHOD default_method = {
0f113f3e
MC
74 "OpenSSL default",
75 def_create,
76 def_init_default,
77 def_destroy,
78 def_destroy_data,
79 def_load_bio,
80 def_dump,
81 def_is_number,
82 def_to_int,
83 def_load
84};
d86b6915 85
7cfc0a55
RS
86CONF_METHOD *NCONF_default(void)
87{
88 return &default_method;
89}
90
936c2b9e 91#ifndef OPENSSL_NO_DEPRECATED_3_0
d86b6915 92static CONF_METHOD WIN32_method = {
0f113f3e
MC
93 "WIN32",
94 def_create,
95 def_init_WIN32,
96 def_destroy,
97 def_destroy_data,
98 def_load_bio,
99 def_dump,
100 def_is_number,
101 def_to_int,
102 def_load
103};
d86b6915 104
3cb7c5cf 105CONF_METHOD *NCONF_WIN32(void)
0f113f3e
MC
106{
107 return &WIN32_method;
108}
7cfc0a55 109#endif
d02b48c6 110
d86b6915 111static CONF *def_create(CONF_METHOD *meth)
0f113f3e
MC
112{
113 CONF *ret;
114
b4faea50 115 ret = OPENSSL_malloc(sizeof(*ret));
90945fa3 116 if (ret != NULL)
0f113f3e
MC
117 if (meth->init(ret) == 0) {
118 OPENSSL_free(ret);
119 ret = NULL;
120 }
121 return ret;
122}
123
d86b6915 124static int def_init_default(CONF *conf)
0f113f3e
MC
125{
126 if (conf == NULL)
127 return 0;
d86b6915 128
c15faa8d 129 memset(conf, 0, sizeof(*conf));
0f113f3e
MC
130 conf->meth = &default_method;
131 conf->meth_data = (void *)CONF_type_default;
d02b48c6 132
0f113f3e
MC
133 return 1;
134}
8623f693 135
936c2b9e 136#ifndef OPENSSL_NO_DEPRECATED_3_0
d86b6915 137static int def_init_WIN32(CONF *conf)
0f113f3e
MC
138{
139 if (conf == NULL)
140 return 0;
8623f693 141
c15faa8d 142 memset(conf, 0, sizeof(*conf));
0f113f3e
MC
143 conf->meth = &WIN32_method;
144 conf->meth_data = (void *)CONF_type_win32;
d86b6915 145
0f113f3e
MC
146 return 1;
147}
7cfc0a55 148#endif
d86b6915
RL
149
150static int def_destroy(CONF *conf)
0f113f3e
MC
151{
152 if (def_destroy_data(conf)) {
153 OPENSSL_free(conf);
154 return 1;
155 }
156 return 0;
157}
8623f693 158
d86b6915 159static int def_destroy_data(CONF *conf)
0f113f3e
MC
160{
161 if (conf == NULL)
162 return 0;
163 _CONF_free_data(conf);
164 return 1;
165}
8623f693 166
befb3e7a 167static int def_load(CONF *conf, const char *name, long *line)
0f113f3e
MC
168{
169 int ret;
170 BIO *in = NULL;
befb3e7a 171
bc36ee62 172#ifdef OPENSSL_SYS_VMS
0f113f3e 173 in = BIO_new_file(name, "r");
befb3e7a 174#else
0f113f3e 175 in = BIO_new_file(name, "rb");
befb3e7a 176#endif
0f113f3e
MC
177 if (in == NULL) {
178 if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
9311d0c4 179 ERR_raise(ERR_LIB_CONF, CONF_R_NO_SUCH_FILE);
0f113f3e 180 else
9311d0c4 181 ERR_raise(ERR_LIB_CONF, ERR_R_SYS_LIB);
0f113f3e
MC
182 return 0;
183 }
befb3e7a 184
0f113f3e
MC
185 ret = def_load_bio(conf, in, line);
186 BIO_free(in);
befb3e7a 187
0f113f3e
MC
188 return ret;
189}
befb3e7a
RL
190
191static int def_load_bio(CONF *conf, BIO *in, long *line)
0f113f3e 192{
6a89a25c 193/* The macro BUFSIZE conflicts with a system macro in VxWorks */
0f113f3e
MC
194#define CONFBUFSIZE 512
195 int bufnum = 0, i, ii;
196 BUF_MEM *buff = NULL;
197 char *s, *p, *end;
198 int again;
4369a882 199 int first_call = 1;
0f113f3e
MC
200 long eline = 0;
201 char btmp[DECIMAL_SIZE(eline) + 1];
202 CONF_VALUE *v = NULL, *tv;
203 CONF_VALUE *sv = NULL;
204 char *section = NULL, *buf;
205 char *start, *psection, *pname;
206 void *h = (void *)(conf->data);
b524b808
TM
207 STACK_OF(BIO) *biosk = NULL;
208#ifndef OPENSSL_NO_POSIX_IO
209 char *dirpath = NULL;
210 OPENSSL_DIR_CTX *dirctx = NULL;
211#endif
0f113f3e
MC
212
213 if ((buff = BUF_MEM_new()) == NULL) {
9311d0c4 214 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB);
0f113f3e
MC
215 goto err;
216 }
217
7644a9ae 218 section = OPENSSL_strdup("default");
0f113f3e 219 if (section == NULL) {
9311d0c4 220 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
221 goto err;
222 }
0f113f3e
MC
223
224 if (_CONF_new_data(conf) == 0) {
9311d0c4 225 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
226 goto err;
227 }
228
229 sv = _CONF_new_section(conf, section);
230 if (sv == NULL) {
9311d0c4 231 ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
0f113f3e
MC
232 goto err;
233 }
234
235 bufnum = 0;
236 again = 0;
237 for (;;) {
238 if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
9311d0c4 239 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB);
0f113f3e
MC
240 goto err;
241 }
242 p = &(buff->data[bufnum]);
243 *p = '\0';
b524b808 244 read_retry:
15795943
DDO
245 if (in != NULL && BIO_gets(in, p, CONFBUFSIZE - 1) < 0)
246 goto err;
0f113f3e
MC
247 p[CONFBUFSIZE - 1] = '\0';
248 ii = i = strlen(p);
4369a882
DB
249 if (first_call) {
250 /* Other BOMs imply unsupported multibyte encoding,
251 * so don't strip them and let the error raise */
252 const unsigned char utf8_bom[3] = {0xEF, 0xBB, 0xBF};
253
254 if (i >= 3 && memcmp(p, utf8_bom, 3) == 0) {
255 memmove(p, p + 3, i - 3);
256 p[i - 3] = 0;
257 i -= 3;
258 ii -= 3;
259 }
260 first_call = 0;
261 }
b524b808 262 if (i == 0 && !again) {
15795943 263 /* the currently processed BIO is NULL or at EOF */
b524b808
TM
264 BIO *parent;
265
266#ifndef OPENSSL_NO_POSIX_IO
267 /* continue processing with the next file from directory */
268 if (dirctx != NULL) {
269 BIO *next;
270
271 if ((next = get_next_file(dirpath, &dirctx)) != NULL) {
272 BIO_vfree(in);
273 in = next;
274 goto read_retry;
275 } else {
276 OPENSSL_free(dirpath);
277 dirpath = NULL;
278 }
279 }
280#endif
281 /* no more files in directory, continue with processing parent */
282 if ((parent = sk_BIO_pop(biosk)) == NULL) {
283 /* everything processed get out of the loop */
284 break;
285 } else {
286 BIO_vfree(in);
287 in = parent;
288 goto read_retry;
289 }
290 }
0f113f3e
MC
291 again = 0;
292 while (i > 0) {
293 if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
294 break;
295 else
296 i--;
297 }
298 /*
299 * we removed some trailing stuff so there is a new line on the end.
300 */
301 if (ii && i == ii)
302 again = 1; /* long line */
303 else {
304 p[i] = '\0';
305 eline++; /* another input line */
306 }
307
308 /* we now have a line with trailing \r\n removed */
309
310 /* i is the number of bytes */
311 bufnum += i;
312
313 v = NULL;
314 /* check for line continuation */
315 if (bufnum >= 1) {
316 /*
317 * If we have bytes and the last char '\\' and second last char
318 * is not '\\'
319 */
320 p = &(buff->data[bufnum - 1]);
321 if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
322 bufnum--;
323 again = 1;
324 }
325 }
326 if (again)
327 continue;
328 bufnum = 0;
329 buf = buff->data;
330
331 clear_comments(conf, buf);
332 s = eat_ws(conf, buf);
333 if (IS_EOF(conf, *s))
334 continue; /* blank line */
335 if (*s == '[') {
336 char *ss;
337
338 s++;
339 start = eat_ws(conf, s);
340 ss = start;
341 again:
342 end = eat_alpha_numeric(conf, ss);
343 p = eat_ws(conf, end);
344 if (*p != ']') {
345 if (*p != '\0' && ss != p) {
346 ss = p;
347 goto again;
348 }
9311d0c4 349 ERR_raise(ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
0f113f3e
MC
350 goto err;
351 }
352 *end = '\0';
353 if (!str_copy(conf, NULL, &section, start))
354 goto err;
355 if ((sv = _CONF_get_section(conf, section)) == NULL)
356 sv = _CONF_new_section(conf, section);
357 if (sv == NULL) {
9311d0c4 358 ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
0f113f3e
MC
359 goto err;
360 }
361 continue;
362 } else {
363 pname = s;
0f113f3e
MC
364 end = eat_alpha_numeric(conf, s);
365 if ((end[0] == ':') && (end[1] == ':')) {
366 *end = '\0';
367 end += 2;
368 psection = pname;
369 pname = end;
370 end = eat_alpha_numeric(conf, end);
b524b808
TM
371 } else {
372 psection = section;
0f113f3e
MC
373 }
374 p = eat_ws(conf, end);
0255c174
RL
375 if (strncmp(pname, ".pragma", 7) == 0
376 && (p != pname + 7 || *p == '=')) {
377 char *pval;
378
379 if (*p == '=') {
380 p++;
381 p = eat_ws(conf, p);
382 }
383 trim_ws(conf, p);
384
385 /* Pragma values take the form keyword:value */
386 pval = strchr(p, ':');
387 if (pval == NULL || pval == p || pval[1] == '\0') {
9311d0c4 388 ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA);
0255c174
RL
389 goto err;
390 }
391
392 *pval++ = '\0';
393 trim_ws(conf, p);
394 pval = eat_ws(conf, pval);
395
396 /*
397 * Known pragmas:
398 *
399 * dollarid takes "on", "true or "off", "false"
400 */
401 if (strcmp(p, "dollarid") == 0) {
402 if (strcmp(pval, "on") == 0
403 || strcmp(pval, "true") == 0) {
404 conf->flag_dollarid = 1;
405 } else if (strcmp(pval, "off") == 0
406 || strcmp(pval, "false") == 0) {
407 conf->flag_dollarid = 0;
408 } else {
9311d0c4 409 ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA);
0255c174
RL
410 goto err;
411 }
412 }
413 /*
414 * We *ignore* any unknown pragma.
415 */
416 continue;
417 } else if (strncmp(pname, ".include", 8) == 0
9d556033 418 && (p != pname + 8 || *p == '=')) {
b524b808
TM
419 char *include = NULL;
420 BIO *next;
7bb82f92
SL
421 const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
422 char *include_path = NULL;
b524b808 423
9d556033
TM
424 if (*p == '=') {
425 p++;
426 p = eat_ws(conf, p);
427 }
b524b808
TM
428 trim_ws(conf, p);
429 if (!str_copy(conf, psection, &include, p))
430 goto err;
7bb82f92 431
d8701e25 432 if (include_dir != NULL && !ossl_is_absolute_path(include)) {
7bb82f92
SL
433 size_t newlen = strlen(include_dir) + strlen(include) + 2;
434
435 include_path = OPENSSL_malloc(newlen);
d8701e25 436 if (include_path == NULL) {
e19c5a10 437 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
d8701e25
TM
438 OPENSSL_free(include);
439 goto err;
440 }
441
7bb82f92 442 OPENSSL_strlcpy(include_path, include_dir, newlen);
d8701e25
TM
443 if (!ossl_ends_with_dirsep(include_path))
444 OPENSSL_strlcat(include_path, "/", newlen);
7bb82f92 445 OPENSSL_strlcat(include_path, include, newlen);
15dd075f 446 OPENSSL_free(include);
7bb82f92
SL
447 } else {
448 include_path = include;
449 }
450
b524b808
TM
451 /* get the BIO of the included file */
452#ifndef OPENSSL_NO_POSIX_IO
7bb82f92
SL
453 next = process_include(include_path, &dirctx, &dirpath);
454 if (include_path != dirpath) {
b524b808 455 /* dirpath will contain include in case of a directory */
15dd075f 456 OPENSSL_free(include_path);
b524b808
TM
457 }
458#else
7bb82f92 459 next = BIO_new_file(include_path, "r");
15dd075f 460 OPENSSL_free(include_path);
b524b808 461#endif
7bb82f92 462
b524b808
TM
463 if (next != NULL) {
464 /* push the currently processing BIO onto stack */
465 if (biosk == NULL) {
466 if ((biosk = sk_BIO_new_null()) == NULL) {
9311d0c4 467 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
4348995b 468 BIO_free(next);
b524b808
TM
469 goto err;
470 }
471 }
472 if (!sk_BIO_push(biosk, in)) {
9311d0c4 473 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
4348995b 474 BIO_free(next);
b524b808
TM
475 goto err;
476 }
477 /* continue with reading from the included BIO */
478 in = next;
479 }
480 continue;
481 } else if (*p != '=') {
a150f8e1
RL
482 ERR_raise_data(ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN,
483 "HERE-->%s", p);
0f113f3e
MC
484 goto err;
485 }
486 *end = '\0';
487 p++;
488 start = eat_ws(conf, p);
b524b808 489 trim_ws(conf, start);
0f113f3e 490
75ebbd9a 491 if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) {
9311d0c4 492 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
493 goto err;
494 }
a2371fa9 495 v->name = OPENSSL_strdup(pname);
0f113f3e
MC
496 v->value = NULL;
497 if (v->name == NULL) {
9311d0c4 498 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
499 goto err;
500 }
0f113f3e
MC
501 if (!str_copy(conf, psection, &(v->value), start))
502 goto err;
503
504 if (strcmp(psection, section) != 0) {
505 if ((tv = _CONF_get_section(conf, psection))
506 == NULL)
507 tv = _CONF_new_section(conf, psection);
508 if (tv == NULL) {
9311d0c4
RL
509 ERR_raise(ERR_LIB_CONF,
510 CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
0f113f3e
MC
511 goto err;
512 }
513 } else
514 tv = sv;
0f113f3e 515 if (_CONF_add_string(conf, tv, v) == 0) {
9311d0c4 516 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
517 goto err;
518 }
0f113f3e
MC
519 v = NULL;
520 }
521 }
25aaa98a 522 BUF_MEM_free(buff);
b548a1f1 523 OPENSSL_free(section);
85aebfcc
RL
524 /*
525 * No need to pop, since we only get here if the stack is empty.
526 * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE!
527 */
528 sk_BIO_free(biosk);
a2371fa9 529 return 1;
0f113f3e 530 err:
25aaa98a 531 BUF_MEM_free(buff);
b548a1f1 532 OPENSSL_free(section);
85aebfcc
RL
533 /*
534 * Since |in| is the first element of the stack and should NOT be freed
535 * here, we cannot use sk_BIO_pop_free(). Instead, we pop and free one
536 * BIO at a time, making sure that the last one popped isn't.
537 */
538 while (sk_BIO_num(biosk) > 0) {
539 BIO *popped = sk_BIO_pop(biosk);
540 BIO_vfree(in);
541 in = popped;
542 }
543 sk_BIO_free(biosk);
b524b808
TM
544#ifndef OPENSSL_NO_POSIX_IO
545 OPENSSL_free(dirpath);
546 if (dirctx != NULL)
547 OPENSSL_DIR_end(&dirctx);
548#endif
0f113f3e
MC
549 if (line != NULL)
550 *line = eline;
a2371fa9 551 BIO_snprintf(btmp, sizeof(btmp), "%ld", eline);
0f113f3e 552 ERR_add_error_data(2, "line ", btmp);
25aaa98a 553 if (h != conf->data) {
0f113f3e
MC
554 CONF_free(conf->data);
555 conf->data = NULL;
556 }
557 if (v != NULL) {
b548a1f1
RS
558 OPENSSL_free(v->name);
559 OPENSSL_free(v->value);
560 OPENSSL_free(v);
0f113f3e 561 }
a2371fa9 562 return 0;
0f113f3e 563}
8623f693 564
d86b6915 565static void clear_comments(CONF *conf, char *p)
0f113f3e
MC
566{
567 for (;;) {
568 if (IS_FCOMMENT(conf, *p)) {
569 *p = '\0';
570 return;
571 }
572 if (!IS_WS(conf, *p)) {
573 break;
574 }
575 p++;
576 }
577
578 for (;;) {
579 if (IS_COMMENT(conf, *p)) {
580 *p = '\0';
581 return;
582 }
583 if (IS_DQUOTE(conf, *p)) {
584 p = scan_dquote(conf, p);
585 continue;
586 }
587 if (IS_QUOTE(conf, *p)) {
588 p = scan_quote(conf, p);
589 continue;
590 }
591 if (IS_ESC(conf, *p)) {
592 p = scan_esc(conf, p);
593 continue;
594 }
595 if (IS_EOF(conf, *p))
596 return;
597 else
598 p++;
599 }
600}
d02b48c6 601
d86b6915 602static int str_copy(CONF *conf, char *section, char **pto, char *from)
0f113f3e
MC
603{
604 int q, r, rr = 0, to = 0, len = 0;
605 char *s, *e, *rp, *p, *rrp, *np, *cp, v;
606 BUF_MEM *buf;
607
608 if ((buf = BUF_MEM_new()) == NULL)
a2371fa9 609 return 0;
0f113f3e
MC
610
611 len = strlen(from) + 1;
612 if (!BUF_MEM_grow(buf, len))
613 goto err;
614
615 for (;;) {
616 if (IS_QUOTE(conf, *from)) {
617 q = *from;
618 from++;
619 while (!IS_EOF(conf, *from) && (*from != q)) {
620 if (IS_ESC(conf, *from)) {
621 from++;
622 if (IS_EOF(conf, *from))
623 break;
624 }
625 buf->data[to++] = *(from++);
626 }
627 if (*from == q)
628 from++;
629 } else if (IS_DQUOTE(conf, *from)) {
630 q = *from;
631 from++;
632 while (!IS_EOF(conf, *from)) {
633 if (*from == q) {
634 if (*(from + 1) == q) {
635 from++;
636 } else {
637 break;
638 }
639 }
640 buf->data[to++] = *(from++);
641 }
642 if (*from == q)
643 from++;
644 } else if (IS_ESC(conf, *from)) {
645 from++;
646 v = *(from++);
647 if (IS_EOF(conf, v))
648 break;
649 else if (v == 'r')
650 v = '\r';
651 else if (v == 'n')
652 v = '\n';
653 else if (v == 'b')
654 v = '\b';
655 else if (v == 't')
656 v = '\t';
657 buf->data[to++] = v;
658 } else if (IS_EOF(conf, *from))
659 break;
0255c174
RL
660 else if (*from == '$'
661 && (!conf->flag_dollarid
662 || from[1] == '{'
663 || from[1] == '(')) {
8a585601
MC
664 size_t newsize;
665
0f113f3e
MC
666 /* try to expand it */
667 rrp = NULL;
668 s = &(from[1]);
669 if (*s == '{')
670 q = '}';
671 else if (*s == '(')
672 q = ')';
673 else
674 q = 0;
675
676 if (q)
677 s++;
678 cp = section;
679 e = np = s;
0255c174
RL
680 while (IS_ALNUM(conf, *e)
681 || (conf->flag_dollarid && IS_DOLLAR(conf, *e)))
0f113f3e
MC
682 e++;
683 if ((e[0] == ':') && (e[1] == ':')) {
684 cp = np;
685 rrp = e;
686 rr = *e;
687 *rrp = '\0';
688 e += 2;
689 np = e;
0255c174
RL
690 while (IS_ALNUM(conf, *e)
691 || (conf->flag_dollarid && IS_DOLLAR(conf, *e)))
0f113f3e
MC
692 e++;
693 }
694 r = *e;
695 *e = '\0';
696 rp = e;
697 if (q) {
698 if (r != q) {
9311d0c4 699 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE);
0f113f3e
MC
700 goto err;
701 }
702 e++;
703 }
50e735f9
MC
704 /*-
705 * So at this point we have
706 * np which is the start of the name string which is
707 * '\0' terminated.
708 * cp which is the start of the section string which is
709 * '\0' terminated.
710 * e is the 'next point after'.
711 * r and rr are the chars replaced by the '\0'
712 * rp and rrp is where 'r' and 'rr' came from.
713 */
0f113f3e
MC
714 p = _CONF_get_string(conf, cp, np);
715 if (rrp != NULL)
716 *rrp = rr;
717 *rp = r;
718 if (p == NULL) {
9311d0c4 719 ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE);
0f113f3e
MC
720 goto err;
721 }
8a585601
MC
722 newsize = strlen(p) + buf->length - (e - from);
723 if (newsize > MAX_CONF_VALUE_LENGTH) {
9311d0c4 724 ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG);
8a585601
MC
725 goto err;
726 }
727 if (!BUF_MEM_grow_clean(buf, newsize)) {
9311d0c4 728 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
b0333e69
GP
729 goto err;
730 }
0f113f3e
MC
731 while (*p)
732 buf->data[to++] = *(p++);
733
734 /*
735 * Since we change the pointer 'from', we also have to change the
736 * perceived length of the string it points at. /RL
737 */
738 len -= e - from;
739 from = e;
740
741 /*
742 * In case there were no braces or parenthesis around the
743 * variable reference, we have to put back the character that was
744 * replaced with a '\0'. /RL
745 */
746 *rp = r;
747 } else
748 buf->data[to++] = *(from++);
749 }
750 buf->data[to] = '\0';
b548a1f1 751 OPENSSL_free(*pto);
0f113f3e
MC
752 *pto = buf->data;
753 OPENSSL_free(buf);
a2371fa9 754 return 1;
0f113f3e 755 err:
25aaa98a 756 BUF_MEM_free(buf);
a2371fa9 757 return 0;
0f113f3e 758}
d02b48c6 759
b524b808
TM
760#ifndef OPENSSL_NO_POSIX_IO
761/*
762 * Check whether included path is a directory.
763 * Returns next BIO to process and in case of a directory
764 * also an opened directory context and the include path.
765 */
766static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
767 char **dirpath)
768{
2661d716 769 struct stat st;
b524b808
TM
770 BIO *next;
771
772 if (stat(include, &st) < 0) {
9311d0c4 773 ERR_raise_data(ERR_LIB_SYS, errno, "calling stat(%s)", include);
b524b808
TM
774 /* missing include file is not fatal error */
775 return NULL;
776 }
777
f20aa69e 778 if (S_ISDIR(st.st_mode)) {
b524b808 779 if (*dirctx != NULL) {
a150f8e1
RL
780 ERR_raise_data(ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE,
781 "%s", include);
b524b808
TM
782 return NULL;
783 }
784 /* a directory, load its contents */
785 if ((next = get_next_file(include, dirctx)) != NULL)
786 *dirpath = include;
787 return next;
788 }
789
790 next = BIO_new_file(include, "r");
791 return next;
792}
793
794/*
795 * Get next file from the directory path.
796 * Returns BIO of the next file to read and updates dirctx.
797 */
798static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx)
799{
800 const char *filename;
d1c1fb2d 801 size_t pathlen;
b524b808 802
d1c1fb2d 803 pathlen = strlen(path);
b524b808
TM
804 while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) {
805 size_t namelen;
806
807 namelen = strlen(filename);
808
4f7c840a 809
b524b808
TM
810 if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0)
811 || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) {
812 size_t newlen;
813 char *newpath;
814 BIO *bio;
815
d1c1fb2d 816 newlen = pathlen + namelen + 2;
b524b808
TM
817 newpath = OPENSSL_zalloc(newlen);
818 if (newpath == NULL) {
9311d0c4 819 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
b524b808
TM
820 break;
821 }
4f7c840a
RL
822#ifdef OPENSSL_SYS_VMS
823 /*
824 * If the given path isn't clear VMS syntax,
825 * we treat it as on Unix.
826 */
d1c1fb2d 827 if (path[pathlen - 1] == ']'
828 || path[pathlen - 1] == '>'
829 || path[pathlen - 1] == ':') {
830 /* Clear VMS directory syntax, just copy as is */
831 OPENSSL_strlcpy(newpath, path, newlen);
4f7c840a 832 }
b524b808 833#endif
4f7c840a
RL
834 if (newpath[0] == '\0') {
835 OPENSSL_strlcpy(newpath, path, newlen);
836 OPENSSL_strlcat(newpath, "/", newlen);
837 }
b524b808
TM
838 OPENSSL_strlcat(newpath, filename, newlen);
839
840 bio = BIO_new_file(newpath, "r");
841 OPENSSL_free(newpath);
842 /* Errors when opening files are non-fatal. */
843 if (bio != NULL)
844 return bio;
845 }
846 }
847 OPENSSL_DIR_end(dirctx);
848 *dirctx = NULL;
849 return NULL;
850}
851#endif
852
a9b7a06e
DMSP
853static int is_keytype(const CONF *conf, char c, unsigned short type)
854{
855 const unsigned short * keytypes = (const unsigned short *) conf->meth_data;
856 unsigned char key = (unsigned char)c;
857
858#ifdef CHARSET_EBCDIC
859# if CHAR_BIT > 8
860 if (key > 255) {
861 /* key is out of range for os_toascii table */
862 return 0;
863 }
864# endif
865 /* convert key from ebcdic to ascii */
866 key = os_toascii[key];
867#endif
868
869 if (key > 127) {
870 /* key is not a seven bit ascii character */
871 return 0;
872 }
873
874 return (keytypes[key] & type) ? 1 : 0;
875}
876
d86b6915 877static char *eat_ws(CONF *conf, char *p)
0f113f3e
MC
878{
879 while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
880 p++;
a2371fa9 881 return p;
0f113f3e 882}
d02b48c6 883
b524b808
TM
884static void trim_ws(CONF *conf, char *start)
885{
886 char *p = start;
887
888 while (!IS_EOF(conf, *p))
889 p++;
890 p--;
891 while ((p >= start) && IS_WS(conf, *p))
892 p--;
893 p++;
894 *p = '\0';
895}
896
d86b6915 897static char *eat_alpha_numeric(CONF *conf, char *p)
0f113f3e
MC
898{
899 for (;;) {
900 if (IS_ESC(conf, *p)) {
901 p = scan_esc(conf, p);
902 continue;
903 }
0255c174
RL
904 if (!(IS_ALNUM_PUNCT(conf, *p)
905 || (conf->flag_dollarid && IS_DOLLAR(conf, *p))))
a2371fa9 906 return p;
0f113f3e
MC
907 p++;
908 }
909}
d02b48c6 910
d86b6915 911static char *scan_quote(CONF *conf, char *p)
0f113f3e
MC
912{
913 int q = *p;
914
915 p++;
916 while (!(IS_EOF(conf, *p)) && (*p != q)) {
917 if (IS_ESC(conf, *p)) {
918 p++;
919 if (IS_EOF(conf, *p))
a2371fa9 920 return p;
0f113f3e
MC
921 }
922 p++;
923 }
924 if (*p == q)
925 p++;
a2371fa9 926 return p;
0f113f3e 927}
d86b6915
RL
928
929static char *scan_dquote(CONF *conf, char *p)
0f113f3e
MC
930{
931 int q = *p;
932
933 p++;
934 while (!(IS_EOF(conf, *p))) {
935 if (*p == q) {
936 if (*(p + 1) == q) {
937 p++;
938 } else {
939 break;
940 }
941 }
942 p++;
943 }
944 if (*p == q)
945 p++;
a2371fa9 946 return p;
0f113f3e 947}
d02b48c6 948
2a056de8 949static void dump_value_doall_arg(const CONF_VALUE *a, BIO *out)
0f113f3e
MC
950{
951 if (a->name)
952 BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
953 else
954 BIO_printf(out, "[[%s]]\n", a->section);
955}
d86b6915 956
2a056de8 957IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, BIO);
3c914840 958
9dd5ae65 959static int def_dump(const CONF *conf, BIO *out)
0f113f3e 960{
2a056de8 961 lh_CONF_VALUE_doall_BIO(conf->data, dump_value_doall_arg, out);
0f113f3e
MC
962 return 1;
963}
d02b48c6 964
9dd5ae65 965static int def_is_number(const CONF *conf, char c)
0f113f3e
MC
966{
967 return IS_NUMBER(conf, c);
968}
d02b48c6 969
9dd5ae65 970static int def_to_int(const CONF *conf, char c)
0f113f3e
MC
971{
972 return c - '0';
973}