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