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