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