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