]>
Commit | Line | Data |
---|---|---|
b2d0e06f MG |
1 | /* crypto/conf/conf.c */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |
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. | |
d3819813 | 8 | * |
b2d0e06f MG |
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). | |
d3819813 | 15 | * |
b2d0e06f MG |
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. | |
d3819813 | 22 | * |
b2d0e06f MG |
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 :-). | |
d3819813 | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
b2d0e06f MG |
38 | * the apps directory (application code) you must include an acknowledgement: |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
d3819813 | 40 | * |
b2d0e06f MG |
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. | |
d3819813 | 52 | * |
b2d0e06f MG |
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 | ||
59 | /* Part of the code in here was originally in conf.c, which is now removed */ | |
60 | ||
61 | #include <stdio.h> | |
62 | #include <string.h> | |
63 | #include "cryptlib.h" | |
64 | #include <openssl/stack.h> | |
65 | #include <openssl/lhash.h> | |
66 | #include <openssl/conf.h> | |
67 | #include <openssl/conf_api.h> | |
68 | #include "conf_def.h" | |
69 | #include <openssl/buffer.h> | |
70 | #include <openssl/err.h> | |
71 | ||
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); | |
d3819813 | 75 | static int str_copy(CONF *conf, char *section, char **to, char *from); |
b2d0e06f MG |
76 | static char *scan_quote(CONF *conf, char *p); |
77 | static char *scan_dquote(CONF *conf, char *p); | |
d3819813 | 78 | #define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) |
b2d0e06f MG |
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); | |
85 | static int def_load(CONF *conf, const char *name, long *eline); | |
86 | static int def_load_bio(CONF *conf, BIO *bp, long *eline); | |
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); | |
90 | ||
d3819813 | 91 | const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT; |
b2d0e06f MG |
92 | |
93 | static CONF_METHOD default_method = { | |
d3819813 MTL |
94 | "OpenSSL default", |
95 | def_create, | |
96 | def_init_default, | |
97 | def_destroy, | |
98 | def_destroy_data, | |
99 | def_load_bio, | |
100 | def_dump, | |
101 | def_is_number, | |
102 | def_to_int, | |
103 | def_load | |
104 | }; | |
b2d0e06f MG |
105 | |
106 | static CONF_METHOD WIN32_method = { | |
d3819813 MTL |
107 | "WIN32", |
108 | def_create, | |
109 | def_init_WIN32, | |
110 | def_destroy, | |
111 | def_destroy_data, | |
112 | def_load_bio, | |
113 | def_dump, | |
114 | def_is_number, | |
115 | def_to_int, | |
116 | def_load | |
117 | }; | |
b2d0e06f MG |
118 | |
119 | CONF_METHOD *NCONF_default() | |
d3819813 MTL |
120 | { |
121 | return &default_method; | |
122 | } | |
123 | ||
b2d0e06f | 124 | CONF_METHOD *NCONF_WIN32() |
d3819813 MTL |
125 | { |
126 | return &WIN32_method; | |
127 | } | |
b2d0e06f MG |
128 | |
129 | static CONF *def_create(CONF_METHOD *meth) | |
d3819813 MTL |
130 | { |
131 | CONF *ret; | |
132 | ||
133 | ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); | |
134 | if (ret) | |
135 | if (meth->init(ret) == 0) { | |
136 | OPENSSL_free(ret); | |
137 | ret = NULL; | |
138 | } | |
139 | return ret; | |
140 | } | |
141 | ||
b2d0e06f | 142 | static int def_init_default(CONF *conf) |
d3819813 MTL |
143 | { |
144 | if (conf == NULL) | |
145 | return 0; | |
b2d0e06f | 146 | |
d3819813 MTL |
147 | conf->meth = &default_method; |
148 | conf->meth_data = CONF_type_default; | |
149 | conf->data = NULL; | |
b2d0e06f | 150 | |
d3819813 MTL |
151 | return 1; |
152 | } | |
b2d0e06f MG |
153 | |
154 | static int def_init_WIN32(CONF *conf) | |
d3819813 MTL |
155 | { |
156 | if (conf == NULL) | |
157 | return 0; | |
b2d0e06f | 158 | |
d3819813 MTL |
159 | conf->meth = &WIN32_method; |
160 | conf->meth_data = (void *)CONF_type_win32; | |
161 | conf->data = NULL; | |
b2d0e06f | 162 | |
d3819813 MTL |
163 | return 1; |
164 | } | |
b2d0e06f MG |
165 | |
166 | static int def_destroy(CONF *conf) | |
d3819813 MTL |
167 | { |
168 | if (def_destroy_data(conf)) { | |
169 | OPENSSL_free(conf); | |
170 | return 1; | |
171 | } | |
172 | return 0; | |
173 | } | |
b2d0e06f MG |
174 | |
175 | static int def_destroy_data(CONF *conf) | |
d3819813 MTL |
176 | { |
177 | if (conf == NULL) | |
178 | return 0; | |
179 | _CONF_free_data(conf); | |
180 | return 1; | |
181 | } | |
b2d0e06f MG |
182 | |
183 | static int def_load(CONF *conf, const char *name, long *line) | |
d3819813 | 184 | { |
62f0afa2 MTL |
185 | #ifdef OPENSSL_NO_STDIO |
186 | CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); | |
187 | return 0; | |
188 | #else | |
d3819813 MTL |
189 | int ret; |
190 | BIO *in = NULL; | |
b2d0e06f MG |
191 | |
192 | #ifdef OPENSSL_SYS_VMS | |
d3819813 | 193 | in = BIO_new_file(name, "r"); |
b2d0e06f | 194 | #else |
d3819813 | 195 | in = BIO_new_file(name, "rb"); |
b2d0e06f | 196 | #endif |
d3819813 MTL |
197 | if (in == NULL) { |
198 | if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) | |
199 | CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); | |
200 | else | |
201 | CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); | |
202 | return 0; | |
203 | } | |
b2d0e06f | 204 | |
d3819813 MTL |
205 | ret = def_load_bio(conf, in, line); |
206 | BIO_free(in); | |
b2d0e06f | 207 | |
d3819813 | 208 | return ret; |
62f0afa2 | 209 | #endif |
d3819813 | 210 | } |
b2d0e06f MG |
211 | |
212 | static int def_load_bio(CONF *conf, BIO *in, long *line) | |
d3819813 | 213 | { |
b2d0e06f | 214 | /* The macro BUFSIZE conflicts with a system macro in VxWorks */ |
d3819813 MTL |
215 | #define CONFBUFSIZE 512 |
216 | int bufnum = 0, i, ii; | |
217 | BUF_MEM *buff = NULL; | |
218 | char *s, *p, *end; | |
219 | int again; | |
220 | long eline = 0; | |
221 | char btmp[DECIMAL_SIZE(eline) + 1]; | |
222 | CONF_VALUE *v = NULL, *tv; | |
223 | CONF_VALUE *sv = NULL; | |
224 | char *section = NULL, *buf; | |
225 | char *start, *psection, *pname; | |
226 | void *h = (void *)(conf->data); | |
227 | ||
228 | if ((buff = BUF_MEM_new()) == NULL) { | |
229 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); | |
230 | goto err; | |
231 | } | |
232 | ||
62f0afa2 | 233 | section = BUF_strdup("default"); |
d3819813 MTL |
234 | if (section == NULL) { |
235 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
236 | goto err; | |
237 | } | |
d3819813 MTL |
238 | |
239 | if (_CONF_new_data(conf) == 0) { | |
240 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
241 | goto err; | |
242 | } | |
243 | ||
244 | sv = _CONF_new_section(conf, section); | |
245 | if (sv == NULL) { | |
246 | CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | |
247 | goto err; | |
248 | } | |
249 | ||
250 | bufnum = 0; | |
251 | again = 0; | |
252 | for (;;) { | |
253 | if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { | |
254 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); | |
255 | goto err; | |
256 | } | |
257 | p = &(buff->data[bufnum]); | |
258 | *p = '\0'; | |
259 | BIO_gets(in, p, CONFBUFSIZE - 1); | |
260 | p[CONFBUFSIZE - 1] = '\0'; | |
261 | ii = i = strlen(p); | |
262 | if (i == 0 && !again) | |
263 | break; | |
264 | again = 0; | |
265 | while (i > 0) { | |
266 | if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) | |
267 | break; | |
268 | else | |
269 | i--; | |
270 | } | |
271 | /* | |
272 | * we removed some trailing stuff so there is a new line on the end. | |
273 | */ | |
274 | if (ii && i == ii) | |
275 | again = 1; /* long line */ | |
276 | else { | |
277 | p[i] = '\0'; | |
278 | eline++; /* another input line */ | |
279 | } | |
280 | ||
281 | /* we now have a line with trailing \r\n removed */ | |
282 | ||
283 | /* i is the number of bytes */ | |
284 | bufnum += i; | |
285 | ||
286 | v = NULL; | |
287 | /* check for line continuation */ | |
288 | if (bufnum >= 1) { | |
289 | /* | |
290 | * If we have bytes and the last char '\\' and second last char | |
291 | * is not '\\' | |
292 | */ | |
293 | p = &(buff->data[bufnum - 1]); | |
294 | if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { | |
295 | bufnum--; | |
296 | again = 1; | |
297 | } | |
298 | } | |
299 | if (again) | |
300 | continue; | |
301 | bufnum = 0; | |
302 | buf = buff->data; | |
303 | ||
304 | clear_comments(conf, buf); | |
305 | s = eat_ws(conf, buf); | |
306 | if (IS_EOF(conf, *s)) | |
307 | continue; /* blank line */ | |
308 | if (*s == '[') { | |
309 | char *ss; | |
310 | ||
311 | s++; | |
312 | start = eat_ws(conf, s); | |
313 | ss = start; | |
314 | again: | |
315 | end = eat_alpha_numeric(conf, ss); | |
316 | p = eat_ws(conf, end); | |
317 | if (*p != ']') { | |
318 | if (*p != '\0' && ss != p) { | |
319 | ss = p; | |
320 | goto again; | |
321 | } | |
322 | CONFerr(CONF_F_DEF_LOAD_BIO, | |
323 | CONF_R_MISSING_CLOSE_SQUARE_BRACKET); | |
324 | goto err; | |
325 | } | |
326 | *end = '\0'; | |
327 | if (!str_copy(conf, NULL, §ion, start)) | |
328 | goto err; | |
329 | if ((sv = _CONF_get_section(conf, section)) == NULL) | |
330 | sv = _CONF_new_section(conf, section); | |
331 | if (sv == NULL) { | |
332 | CONFerr(CONF_F_DEF_LOAD_BIO, | |
333 | CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | |
334 | goto err; | |
335 | } | |
336 | continue; | |
337 | } else { | |
338 | pname = s; | |
339 | psection = NULL; | |
340 | end = eat_alpha_numeric(conf, s); | |
341 | if ((end[0] == ':') && (end[1] == ':')) { | |
342 | *end = '\0'; | |
343 | end += 2; | |
344 | psection = pname; | |
345 | pname = end; | |
346 | end = eat_alpha_numeric(conf, end); | |
347 | } | |
348 | p = eat_ws(conf, end); | |
349 | if (*p != '=') { | |
350 | CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); | |
351 | goto err; | |
352 | } | |
353 | *end = '\0'; | |
354 | p++; | |
355 | start = eat_ws(conf, p); | |
356 | while (!IS_EOF(conf, *p)) | |
357 | p++; | |
358 | p--; | |
359 | while ((p != start) && (IS_WS(conf, *p))) | |
360 | p--; | |
361 | p++; | |
362 | *p = '\0'; | |
363 | ||
364 | if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { | |
365 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
366 | goto err; | |
367 | } | |
368 | if (psection == NULL) | |
369 | psection = section; | |
370 | v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); | |
371 | v->value = NULL; | |
372 | if (v->name == NULL) { | |
373 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
374 | goto err; | |
375 | } | |
376 | BUF_strlcpy(v->name, pname, strlen(pname) + 1); | |
377 | if (!str_copy(conf, psection, &(v->value), start)) | |
378 | goto err; | |
379 | ||
380 | if (strcmp(psection, section) != 0) { | |
381 | if ((tv = _CONF_get_section(conf, psection)) | |
382 | == NULL) | |
383 | tv = _CONF_new_section(conf, psection); | |
384 | if (tv == NULL) { | |
385 | CONFerr(CONF_F_DEF_LOAD_BIO, | |
386 | CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | |
387 | goto err; | |
388 | } | |
389 | } else | |
390 | tv = sv; | |
b2d0e06f | 391 | #if 1 |
d3819813 MTL |
392 | if (_CONF_add_string(conf, tv, v) == 0) { |
393 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
394 | goto err; | |
395 | } | |
b2d0e06f | 396 | #else |
d3819813 MTL |
397 | v->section = tv->section; |
398 | if (!sk_CONF_VALUE_push(ts, v)) { | |
399 | CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); | |
400 | goto err; | |
401 | } | |
402 | vv = (CONF_VALUE *)lh_insert(conf->data, v); | |
403 | if (vv != NULL) { | |
404 | sk_CONF_VALUE_delete_ptr(ts, vv); | |
405 | OPENSSL_free(vv->name); | |
406 | OPENSSL_free(vv->value); | |
407 | OPENSSL_free(vv); | |
408 | } | |
b2d0e06f | 409 | #endif |
d3819813 MTL |
410 | v = NULL; |
411 | } | |
412 | } | |
413 | if (buff != NULL) | |
414 | BUF_MEM_free(buff); | |
415 | if (section != NULL) | |
416 | OPENSSL_free(section); | |
417 | return (1); | |
418 | err: | |
419 | if (buff != NULL) | |
420 | BUF_MEM_free(buff); | |
421 | if (section != NULL) | |
422 | OPENSSL_free(section); | |
423 | if (line != NULL) | |
424 | *line = eline; | |
425 | BIO_snprintf(btmp, sizeof btmp, "%ld", eline); | |
426 | ERR_add_error_data(2, "line ", btmp); | |
427 | if ((h != conf->data) && (conf->data != NULL)) { | |
428 | CONF_free(conf->data); | |
429 | conf->data = NULL; | |
430 | } | |
431 | if (v != NULL) { | |
432 | if (v->name != NULL) | |
433 | OPENSSL_free(v->name); | |
434 | if (v->value != NULL) | |
435 | OPENSSL_free(v->value); | |
436 | if (v != NULL) | |
437 | OPENSSL_free(v); | |
438 | } | |
439 | return (0); | |
440 | } | |
b2d0e06f MG |
441 | |
442 | static void clear_comments(CONF *conf, char *p) | |
d3819813 MTL |
443 | { |
444 | for (;;) { | |
445 | if (IS_FCOMMENT(conf, *p)) { | |
446 | *p = '\0'; | |
447 | return; | |
448 | } | |
449 | if (!IS_WS(conf, *p)) { | |
450 | break; | |
451 | } | |
452 | p++; | |
453 | } | |
454 | ||
455 | for (;;) { | |
456 | if (IS_COMMENT(conf, *p)) { | |
457 | *p = '\0'; | |
458 | return; | |
459 | } | |
460 | if (IS_DQUOTE(conf, *p)) { | |
461 | p = scan_dquote(conf, p); | |
462 | continue; | |
463 | } | |
464 | if (IS_QUOTE(conf, *p)) { | |
465 | p = scan_quote(conf, p); | |
466 | continue; | |
467 | } | |
468 | if (IS_ESC(conf, *p)) { | |
469 | p = scan_esc(conf, p); | |
470 | continue; | |
471 | } | |
472 | if (IS_EOF(conf, *p)) | |
473 | return; | |
474 | else | |
475 | p++; | |
476 | } | |
477 | } | |
b2d0e06f MG |
478 | |
479 | static int str_copy(CONF *conf, char *section, char **pto, char *from) | |
d3819813 MTL |
480 | { |
481 | int q, r, rr = 0, to = 0, len = 0; | |
482 | char *s, *e, *rp, *p, *rrp, *np, *cp, v; | |
483 | BUF_MEM *buf; | |
484 | ||
485 | if ((buf = BUF_MEM_new()) == NULL) | |
486 | return (0); | |
487 | ||
488 | len = strlen(from) + 1; | |
489 | if (!BUF_MEM_grow(buf, len)) | |
490 | goto err; | |
491 | ||
492 | for (;;) { | |
493 | if (IS_QUOTE(conf, *from)) { | |
494 | q = *from; | |
495 | from++; | |
496 | while (!IS_EOF(conf, *from) && (*from != q)) { | |
497 | if (IS_ESC(conf, *from)) { | |
498 | from++; | |
499 | if (IS_EOF(conf, *from)) | |
500 | break; | |
501 | } | |
502 | buf->data[to++] = *(from++); | |
503 | } | |
504 | if (*from == q) | |
505 | from++; | |
506 | } else if (IS_DQUOTE(conf, *from)) { | |
507 | q = *from; | |
508 | from++; | |
509 | while (!IS_EOF(conf, *from)) { | |
510 | if (*from == q) { | |
511 | if (*(from + 1) == q) { | |
512 | from++; | |
513 | } else { | |
514 | break; | |
515 | } | |
516 | } | |
517 | buf->data[to++] = *(from++); | |
518 | } | |
519 | if (*from == q) | |
520 | from++; | |
521 | } else if (IS_ESC(conf, *from)) { | |
522 | from++; | |
523 | v = *(from++); | |
524 | if (IS_EOF(conf, v)) | |
525 | break; | |
526 | else if (v == 'r') | |
527 | v = '\r'; | |
528 | else if (v == 'n') | |
529 | v = '\n'; | |
530 | else if (v == 'b') | |
531 | v = '\b'; | |
532 | else if (v == 't') | |
533 | v = '\t'; | |
534 | buf->data[to++] = v; | |
535 | } else if (IS_EOF(conf, *from)) | |
536 | break; | |
537 | else if (*from == '$') { | |
538 | /* try to expand it */ | |
539 | rrp = NULL; | |
540 | s = &(from[1]); | |
541 | if (*s == '{') | |
542 | q = '}'; | |
543 | else if (*s == '(') | |
544 | q = ')'; | |
545 | else | |
546 | q = 0; | |
547 | ||
548 | if (q) | |
549 | s++; | |
550 | cp = section; | |
551 | e = np = s; | |
552 | while (IS_ALPHA_NUMERIC(conf, *e)) | |
553 | e++; | |
554 | if ((e[0] == ':') && (e[1] == ':')) { | |
555 | cp = np; | |
556 | rrp = e; | |
557 | rr = *e; | |
558 | *rrp = '\0'; | |
559 | e += 2; | |
560 | np = e; | |
561 | while (IS_ALPHA_NUMERIC(conf, *e)) | |
562 | e++; | |
563 | } | |
564 | r = *e; | |
565 | *e = '\0'; | |
566 | rp = e; | |
567 | if (q) { | |
568 | if (r != q) { | |
569 | CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); | |
570 | goto err; | |
571 | } | |
572 | e++; | |
573 | } | |
574 | /*- | |
575 | * So at this point we have | |
576 | * np which is the start of the name string which is | |
577 | * '\0' terminated. | |
578 | * cp which is the start of the section string which is | |
579 | * '\0' terminated. | |
580 | * e is the 'next point after'. | |
581 | * r and rr are the chars replaced by the '\0' | |
582 | * rp and rrp is where 'r' and 'rr' came from. | |
583 | */ | |
584 | p = _CONF_get_string(conf, cp, np); | |
585 | if (rrp != NULL) | |
586 | *rrp = rr; | |
587 | *rp = r; | |
588 | if (p == NULL) { | |
589 | CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); | |
590 | goto err; | |
591 | } | |
592 | if (!BUF_MEM_grow_clean(buf, | |
593 | (strlen(p) + buf->length - (e - from)))) { | |
594 | CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); | |
595 | goto err; | |
596 | } | |
597 | while (*p) | |
598 | buf->data[to++] = *(p++); | |
599 | ||
600 | /* | |
601 | * Since we change the pointer 'from', we also have to change the | |
602 | * perceived length of the string it points at. /RL | |
603 | */ | |
604 | len -= e - from; | |
605 | from = e; | |
606 | ||
607 | /* | |
608 | * In case there were no braces or parenthesis around the | |
609 | * variable reference, we have to put back the character that was | |
610 | * replaced with a '\0'. /RL | |
611 | */ | |
612 | *rp = r; | |
613 | } else | |
614 | buf->data[to++] = *(from++); | |
615 | } | |
616 | buf->data[to] = '\0'; | |
617 | if (*pto != NULL) | |
618 | OPENSSL_free(*pto); | |
619 | *pto = buf->data; | |
620 | OPENSSL_free(buf); | |
621 | return (1); | |
622 | err: | |
623 | if (buf != NULL) | |
624 | BUF_MEM_free(buf); | |
625 | return (0); | |
626 | } | |
b2d0e06f MG |
627 | |
628 | static char *eat_ws(CONF *conf, char *p) | |
d3819813 MTL |
629 | { |
630 | while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) | |
631 | p++; | |
632 | return (p); | |
633 | } | |
b2d0e06f MG |
634 | |
635 | static char *eat_alpha_numeric(CONF *conf, char *p) | |
d3819813 MTL |
636 | { |
637 | for (;;) { | |
638 | if (IS_ESC(conf, *p)) { | |
639 | p = scan_esc(conf, p); | |
640 | continue; | |
641 | } | |
642 | if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) | |
643 | return (p); | |
644 | p++; | |
645 | } | |
646 | } | |
b2d0e06f MG |
647 | |
648 | static char *scan_quote(CONF *conf, char *p) | |
d3819813 MTL |
649 | { |
650 | int q = *p; | |
651 | ||
652 | p++; | |
653 | while (!(IS_EOF(conf, *p)) && (*p != q)) { | |
654 | if (IS_ESC(conf, *p)) { | |
655 | p++; | |
656 | if (IS_EOF(conf, *p)) | |
657 | return (p); | |
658 | } | |
659 | p++; | |
660 | } | |
661 | if (*p == q) | |
662 | p++; | |
663 | return (p); | |
664 | } | |
b2d0e06f MG |
665 | |
666 | static char *scan_dquote(CONF *conf, char *p) | |
d3819813 MTL |
667 | { |
668 | int q = *p; | |
669 | ||
670 | p++; | |
671 | while (!(IS_EOF(conf, *p))) { | |
672 | if (*p == q) { | |
673 | if (*(p + 1) == q) { | |
674 | p++; | |
675 | } else { | |
676 | break; | |
677 | } | |
678 | } | |
679 | p++; | |
680 | } | |
681 | if (*p == q) | |
682 | p++; | |
683 | return (p); | |
684 | } | |
685 | ||
686 | static void dump_value_doall_arg(CONF_VALUE *a, BIO *out) | |
687 | { | |
688 | if (a->name) | |
689 | BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); | |
690 | else | |
691 | BIO_printf(out, "[[%s]]\n", a->section); | |
692 | } | |
693 | ||
694 | static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) | |
b2d0e06f MG |
695 | |
696 | static int def_dump(const CONF *conf, BIO *out) | |
d3819813 MTL |
697 | { |
698 | lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), | |
699 | BIO, out); | |
700 | return 1; | |
701 | } | |
b2d0e06f MG |
702 | |
703 | static int def_is_number(const CONF *conf, char c) | |
d3819813 MTL |
704 | { |
705 | return IS_NUMBER(conf, c); | |
706 | } | |
b2d0e06f MG |
707 | |
708 | static int def_to_int(const CONF *conf, char c) | |
d3819813 MTL |
709 | { |
710 | return c - '0'; | |
711 | } |