diff options
author | Richard Levitte <levitte@openssl.org> | 2000-04-09 12:04:35 +0000 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2000-04-09 12:04:35 +0000 |
commit | d86b6915bebbd86c46680e24d152f497cd85bc85 (patch) | |
tree | 6f3e3eb19cd5689c34c2ec47bc4a6074000c9c0d /crypto/conf/conf.c | |
parent | 05e15b046f624a9a05e86a2c0ca7e3d87794d138 (diff) | |
download | openssl-d86b6915bebbd86c46680e24d152f497cd85bc85.tar.gz |
I've always wanted to make the CONF library more adaptable. Here's
the result.
I have retained the old behavior of the CONF_* functions, and have
added a more "object oriented" interface through NCONF_* functions
(New CONF, you see :-)), working the same way as, for example, the
BIO interface. Really, the CONF_* are rewritten so they use the
NCONF_* functions internally.
In addition to that, I've split the old conf.c code into two files,
conf_def.c and conf_api.c. conf_def.c contains the default config
object that reads a configuration file the standard OpenSSL way, as
well as configuration file with Win32 registry file syntax (I'm not
sure I got that one right). conf_api.c provides an API to build other
configuration file readers around (can you see a configuraion file in
XML? I can :-)).
Finally, I've changed the name conf_lcl.h to conf_def.h, since it's
made specifically for that "class" and none others.
Diffstat (limited to 'crypto/conf/conf.c')
-rw-r--r-- | crypto/conf/conf.c | 730 |
1 files changed, 0 insertions, 730 deletions
diff --git a/crypto/conf/conf.c b/crypto/conf/conf.c deleted file mode 100644 index 3031fa3b44..0000000000 --- a/crypto/conf/conf.c +++ /dev/null @@ -1,730 +0,0 @@ -/* crypto/conf/conf.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <errno.h> -#include "cryptlib.h" -#include <openssl/stack.h> -#include <openssl/lhash.h> -#include <openssl/conf.h> -#include <openssl/buffer.h> -#include <openssl/err.h> - -#include "conf_lcl.h" - -static void value_free_hash(CONF_VALUE *a, LHASH *conf); -static void value_free_stack(CONF_VALUE *a,LHASH *conf); -static unsigned long hash(CONF_VALUE *v); -static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); -static char *eat_ws(char *p); -static char *eat_alpha_numeric(char *p); -static void clear_comments(char *p); -static int str_copy(LHASH *conf,char *section,char **to, char *from); -static char *scan_quote(char *p); -static CONF_VALUE *new_section(LHASH *conf,char *section); -static CONF_VALUE *get_section(LHASH *conf,char *section); -#define scan_esc(p) ((((p)[1] == '\0')?(p++):(p+=2)),p) - -const char *CONF_version="CONF" OPENSSL_VERSION_PTEXT; - - -LHASH *CONF_load(LHASH *h, const char *file, long *line) - { - LHASH *ltmp; - BIO *in=NULL; - -#ifdef VMS - in=BIO_new_file(file, "r"); -#else - in=BIO_new_file(file, "rb"); -#endif - if (in == NULL) - { - CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); - return NULL; - } - - ltmp = CONF_load_bio(h, in, line); - BIO_free(in); - - return ltmp; -} -#ifndef NO_FP_API -LHASH *CONF_load_fp(LHASH *h, FILE *in, long *line) -{ - BIO *btmp; - LHASH *ltmp; - if(!(btmp = BIO_new_fp(in, BIO_NOCLOSE))) { - CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); - return NULL; - } - ltmp = CONF_load_bio(h, btmp, line); - BIO_free(btmp); - return ltmp; -} -#endif - -LHASH *CONF_load_bio(LHASH *h, BIO *in, long *line) - { - LHASH *ret=NULL; -#define BUFSIZE 512 - char btmp[16]; - int bufnum=0,i,ii; - BUF_MEM *buff=NULL; - char *s,*p,*end; - int again,n; - long eline=0; - CONF_VALUE *v=NULL,*vv,*tv; - CONF_VALUE *sv=NULL; - char *section=NULL,*buf; - STACK_OF(CONF_VALUE) *section_sk=NULL,*ts; - char *start,*psection,*pname; - - if ((buff=BUF_MEM_new()) == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); - goto err; - } - - section=(char *)Malloc(10); - if (section == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); - goto err; - } - strcpy(section,"default"); - - if (h == NULL) - { - if ((ret=lh_new(hash,cmp_conf)) == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); - goto err; - } - } - else - ret=h; - - sv=new_section(ret,section); - if (sv == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - section_sk=(STACK_OF(CONF_VALUE) *)sv->value; - - bufnum=0; - for (;;) - { - again=0; - if (!BUF_MEM_grow(buff,bufnum+BUFSIZE)) - { - CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); - goto err; - } - p= &(buff->data[bufnum]); - *p='\0'; - BIO_gets(in, p, BUFSIZE-1); - p[BUFSIZE-1]='\0'; - ii=i=strlen(p); - if (i == 0) break; - while (i > 0) - { - if ((p[i-1] != '\r') && (p[i-1] != '\n')) - break; - else - i--; - } - /* we removed some trailing stuff so there is a new - * line on the end. */ - if (i == ii) - again=1; /* long line */ - else - { - p[i]='\0'; - eline++; /* another input line */ - } - - /* we now have a line with trailing \r\n removed */ - - /* i is the number of bytes */ - bufnum+=i; - - v=NULL; - /* check for line continuation */ - if (bufnum >= 1) - { - /* If we have bytes and the last char '\\' and - * second last char is not '\\' */ - p= &(buff->data[bufnum-1]); - if ( IS_ESC(p[0]) && - ((bufnum <= 1) || !IS_ESC(p[-1]))) - { - bufnum--; - again=1; - } - } - if (again) continue; - bufnum=0; - buf=buff->data; - - clear_comments(buf); - n=strlen(buf); - s=eat_ws(buf); - if (IS_EOF(*s)) continue; /* blank line */ - if (*s == '[') - { - char *ss; - - s++; - start=eat_ws(s); - ss=start; -again: - end=eat_alpha_numeric(ss); - p=eat_ws(end); - if (*p != ']') - { - if (*p != '\0') - { - ss=p; - goto again; - } - CONFerr(CONF_F_CONF_LOAD_BIO, - CONF_R_MISSING_CLOSE_SQUARE_BRACKET); - goto err; - } - *end='\0'; - if (!str_copy(ret,NULL,§ion,start)) goto err; - if ((sv=get_section(ret,section)) == NULL) - sv=new_section(ret,section); - if (sv == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - section_sk=(STACK_OF(CONF_VALUE) *)sv->value; - continue; - } - else - { - pname=s; - psection=NULL; - end=eat_alpha_numeric(s); - if ((end[0] == ':') && (end[1] == ':')) - { - *end='\0'; - end+=2; - psection=pname; - pname=end; - end=eat_alpha_numeric(end); - } - p=eat_ws(end); - if (*p != '=') - { - CONFerr(CONF_F_CONF_LOAD_BIO, - CONF_R_MISSING_EQUAL_SIGN); - goto err; - } - *end='\0'; - p++; - start=eat_ws(p); - while (!IS_EOF(*p)) - p++; - p--; - while ((p != start) && (IS_WS(*p))) - p--; - p++; - *p='\0'; - - if (!(v=(CONF_VALUE *)Malloc(sizeof(CONF_VALUE)))) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (psection == NULL) psection=section; - v->name=(char *)Malloc(strlen(pname)+1); - v->value=NULL; - if (v->name == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - ERR_R_MALLOC_FAILURE); - goto err; - } - strcpy(v->name,pname); - if (!str_copy(ret,psection,&(v->value),start)) goto err; - - if (strcmp(psection,section) != 0) - { - if ((tv=get_section(ret,psection)) - == NULL) - tv=new_section(ret,psection); - if (tv == NULL) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - ts=(STACK_OF(CONF_VALUE) *)tv->value; - } - else - { - tv=sv; - ts=section_sk; - } - v->section=tv->section; - if (!sk_CONF_VALUE_push(ts,v)) - { - CONFerr(CONF_F_CONF_LOAD_BIO, - ERR_R_MALLOC_FAILURE); - goto err; - } - vv=(CONF_VALUE *)lh_insert(ret,v); - if (vv != NULL) - { - sk_CONF_VALUE_delete_ptr(ts,vv); - Free(vv->name); - Free(vv->value); - Free(vv); - } - v=NULL; - } - } - if (buff != NULL) BUF_MEM_free(buff); - if (section != NULL) Free(section); - return(ret); -err: - if (buff != NULL) BUF_MEM_free(buff); - if (section != NULL) Free(section); - if (line != NULL) *line=eline; - sprintf(btmp,"%ld",eline); - ERR_add_error_data(2,"line ",btmp); - if ((h != ret) && (ret != NULL)) CONF_free(ret); - if (v != NULL) - { - if (v->name != NULL) Free(v->name); - if (v->value != NULL) Free(v->value); - if (v != NULL) Free(v); - } - return(NULL); - } - -char *CONF_get_string(LHASH *conf, char *section, char *name) - { - CONF_VALUE *v,vv; - char *p; - - if (name == NULL) return(NULL); - if (conf != NULL) - { - if (section != NULL) - { - vv.name=name; - vv.section=section; - v=(CONF_VALUE *)lh_retrieve(conf,&vv); - if (v != NULL) return(v->value); - if (strcmp(section,"ENV") == 0) - { - p=Getenv(name); - if (p != NULL) return(p); - } - } - vv.section="default"; - vv.name=name; - v=(CONF_VALUE *)lh_retrieve(conf,&vv); - if (v != NULL) - return(v->value); - else - return(NULL); - } - else - return(Getenv(name)); - } - -static CONF_VALUE *get_section(LHASH *conf, char *section) - { - CONF_VALUE *v,vv; - - if ((conf == NULL) || (section == NULL)) return(NULL); - vv.name=NULL; - vv.section=section; - v=(CONF_VALUE *)lh_retrieve(conf,&vv); - return(v); - } - -STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf, char *section) - { - CONF_VALUE *v; - - v=get_section(conf,section); - if (v != NULL) - return((STACK_OF(CONF_VALUE) *)v->value); - else - return(NULL); - } - -long CONF_get_number(LHASH *conf, char *section, char *name) - { - char *str; - long ret=0; - - str=CONF_get_string(conf,section,name); - if (str == NULL) return(0); - for (;;) - { - if (IS_NUMER(*str)) - ret=ret*10+(*str -'0'); - else - return(ret); - str++; - } - } - -void CONF_free(LHASH *conf) - { - if (conf == NULL) return; - - conf->down_load=0; /* evil thing to make sure the 'Free()' - * works as expected */ - lh_doall_arg(conf,(void (*)())value_free_hash,conf); - - /* We now have only 'section' entries in the hash table. - * Due to problems with */ - - lh_doall_arg(conf,(void (*)())value_free_stack,conf); - lh_free(conf); - } - -static void value_free_hash(CONF_VALUE *a, LHASH *conf) - { - if (a->name != NULL) - { - a=(CONF_VALUE *)lh_delete(conf,a); - } - } - -static void value_free_stack(CONF_VALUE *a, LHASH *conf) - { - CONF_VALUE *vv; - STACK *sk; - int i; - - if (a->name != NULL) return; - - sk=(STACK *)a->value; - for (i=sk_num(sk)-1; i>=0; i--) - { - vv=(CONF_VALUE *)sk_value(sk,i); - Free(vv->value); - Free(vv->name); - Free(vv); - } - if (sk != NULL) sk_free(sk); - Free(a->section); - Free(a); - } - -static void clear_comments(char *p) - { - char *to; - - to=p; - for (;;) - { - if (IS_COMMENT(*p)) - { - *p='\0'; - return; - } - if (IS_QUOTE(*p)) - { - p=scan_quote(p); - continue; - } - if (IS_ESC(*p)) - { - p=scan_esc(p); - continue; - } - if (IS_EOF(*p)) - return; - else - p++; - } - } - -static int str_copy(LHASH *conf, char *section, char **pto, char *from) - { - int q,r,rr=0,to=0,len=0; - char *s,*e,*rp,*p,*rrp,*np,*cp,v; - BUF_MEM *buf; - - if ((buf=BUF_MEM_new()) == NULL) return(0); - - len=strlen(from)+1; - if (!BUF_MEM_grow(buf,len)) goto err; - - for (;;) - { - if (IS_QUOTE(*from)) - { - q= *from; - from++; - while ((*from != '\0') && (*from != q)) - { - if (*from == '\\') - { - from++; - if (*from == '\0') break; - } - buf->data[to++]= *(from++); - } - } - else if (*from == '\\') - { - from++; - v= *(from++); - if (v == '\0') break; - else if (v == 'r') v='\r'; - else if (v == 'n') v='\n'; - else if (v == 'b') v='\b'; - else if (v == 't') v='\t'; - buf->data[to++]= v; - } - else if (*from == '\0') - break; - else if (*from == '$') - { - /* try to expand it */ - rrp=NULL; - s= &(from[1]); - if (*s == '{') - q='}'; - else if (*s == '(') - q=')'; - else q=0; - - if (q) s++; - cp=section; - e=np=s; - while (IS_ALPHA_NUMERIC(*e)) - e++; - if ((e[0] == ':') && (e[1] == ':')) - { - cp=np; - rrp=e; - rr= *e; - *rrp='\0'; - e+=2; - np=e; - while (IS_ALPHA_NUMERIC(*e)) - e++; - } - r= *e; - *e='\0'; - rp=e; - if (q) - { - if (r != q) - { - CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE); - goto err; - } - e++; - } - /* So at this point we have - * ns which is the start of the name string which is - * '\0' terminated. - * cs which is the start of the section string which is - * '\0' terminated. - * e is the 'next point after'. - * r and s are the chars replaced by the '\0' - * rp and sp is where 'r' and 's' came from. - */ - p=CONF_get_string(conf,cp,np); - if (rrp != NULL) *rrp=rr; - *rp=r; - if (p == NULL) - { - CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE); - goto err; - } - BUF_MEM_grow(buf,(strlen(p)+len-(e-from))); - while (*p) - buf->data[to++]= *(p++); - from=e; - } - else - buf->data[to++]= *(from++); - } - buf->data[to]='\0'; - if (*pto != NULL) Free(*pto); - *pto=buf->data; - Free(buf); - return(1); -err: - if (buf != NULL) BUF_MEM_free(buf); - return(0); - } - -static char *eat_ws(char *p) - { - while (IS_WS(*p) && (!IS_EOF(*p))) - p++; - return(p); - } - -static char *eat_alpha_numeric(char *p) - { - for (;;) - { - if (IS_ESC(*p)) - { - p=scan_esc(p); - continue; - } - if (!IS_ALPHA_NUMERIC_PUNCT(*p)) - return(p); - p++; - } - } - -static unsigned long hash(CONF_VALUE *v) - { - return((lh_strhash(v->section)<<2)^lh_strhash(v->name)); - } - -static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) - { - int i; - - if (a->section != b->section) - { - i=strcmp(a->section,b->section); - if (i) return(i); - } - - if ((a->name != NULL) && (b->name != NULL)) - { - i=strcmp(a->name,b->name); - return(i); - } - else if (a->name == b->name) - return(0); - else - return((a->name == NULL)?-1:1); - } - -static char *scan_quote(char *p) - { - int q= *p; - - p++; - while (!(IS_EOF(*p)) && (*p != q)) - { - if (IS_ESC(*p)) - { - p++; - if (IS_EOF(*p)) return(p); - } - p++; - } - if (*p == q) p++; - return(p); - } - -static CONF_VALUE *new_section(LHASH *conf, char *section) - { - STACK *sk=NULL; - int ok=0,i; - CONF_VALUE *v=NULL,*vv; - - if ((sk=sk_new_null()) == NULL) - goto err; - if ((v=(CONF_VALUE *)Malloc(sizeof(CONF_VALUE))) == NULL) - goto err; - i=strlen(section)+1; - if ((v->section=(char *)Malloc(i)) == NULL) - goto err; - - memcpy(v->section,section,i); - v->name=NULL; - v->value=(char *)sk; - - vv=(CONF_VALUE *)lh_insert(conf,v); - if (vv != NULL) - { -#if !defined(NO_STDIO) && !defined(WIN16) - fprintf(stderr,"internal fault\n"); -#endif - abort(); - } - ok=1; -err: - if (!ok) - { - if (sk != NULL) sk_free(sk); - if (v != NULL) Free(v); - v=NULL; - } - return(v); - } - -IMPLEMENT_STACK_OF(CONF_VALUE) |