168651Skris/* conf_api.c */ 268651Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 368651Skris * All rights reserved. 468651Skris * 568651Skris * This package is an SSL implementation written 668651Skris * by Eric Young (eay@cryptsoft.com). 768651Skris * The implementation was written so as to conform with Netscapes SSL. 868651Skris * 968651Skris * This library is free for commercial and non-commercial use as long as 1068651Skris * the following conditions are aheared to. The following conditions 1168651Skris * apply to all code found in this distribution, be it the RC4, RSA, 1268651Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1368651Skris * included with this distribution is covered by the same copyright terms 1468651Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1568651Skris * 1668651Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1768651Skris * the code are not to be removed. 1868651Skris * If this package is used in a product, Eric Young should be given attribution 1968651Skris * as the author of the parts of the library used. 2068651Skris * This can be in the form of a textual message at program startup or 2168651Skris * in documentation (online or textual) provided with the package. 2268651Skris * 2368651Skris * Redistribution and use in source and binary forms, with or without 2468651Skris * modification, are permitted provided that the following conditions 2568651Skris * are met: 2668651Skris * 1. Redistributions of source code must retain the copyright 2768651Skris * notice, this list of conditions and the following disclaimer. 2868651Skris * 2. Redistributions in binary form must reproduce the above copyright 2968651Skris * notice, this list of conditions and the following disclaimer in the 3068651Skris * documentation and/or other materials provided with the distribution. 3168651Skris * 3. All advertising materials mentioning features or use of this software 3268651Skris * must display the following acknowledgement: 3368651Skris * "This product includes cryptographic software written by 3468651Skris * Eric Young (eay@cryptsoft.com)" 3568651Skris * The word 'cryptographic' can be left out if the rouines from the library 3668651Skris * being used are not cryptographic related :-). 3768651Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3868651Skris * the apps directory (application code) you must include an acknowledgement: 3968651Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4068651Skris * 4168651Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4268651Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4368651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4468651Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4568651Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4668651Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4768651Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4968651Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5068651Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5168651Skris * SUCH DAMAGE. 5268651Skris * 5368651Skris * The licence and distribution terms for any publically available version or 5468651Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5568651Skris * copied and put under another distribution licence 5668651Skris * [including the GNU Public Licence.] 5768651Skris */ 5868651Skris 5968651Skris/* Part of the code in here was originally in conf.c, which is now removed */ 6068651Skris 6168651Skris#ifndef CONF_DEBUG 6268651Skris# undef NDEBUG /* avoid conflicting definitions */ 6368651Skris# define NDEBUG 6468651Skris#endif 6568651Skris 6668651Skris#include <assert.h> 67237657Sjkim#include <stdlib.h> 6868651Skris#include <string.h> 6968651Skris#include <openssl/conf.h> 7068651Skris#include <openssl/conf_api.h> 71109998Smarkm#include "e_os.h" 7268651Skris 73238405Sjkimstatic void value_free_hash_doall_arg(CONF_VALUE *a, 74238405Sjkim LHASH_OF(CONF_VALUE) *conf); 75238405Sjkimstatic void value_free_stack_doall(CONF_VALUE *a); 76238405Sjkimstatic IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, 77238405Sjkim LHASH_OF(CONF_VALUE)) 78238405Sjkimstatic IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) 7968651Skris 8068651Skris/* Up until OpenSSL 0.9.5a, this was get_section */ 81109998SmarkmCONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) 8268651Skris { 8368651Skris CONF_VALUE *v,vv; 8468651Skris 8568651Skris if ((conf == NULL) || (section == NULL)) return(NULL); 8668651Skris vv.name=NULL; 87109998Smarkm vv.section=(char *)section; 88238405Sjkim v=lh_CONF_VALUE_retrieve(conf->data,&vv); 8968651Skris return(v); 9068651Skris } 9168651Skris 9268651Skris/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ 93109998SmarkmSTACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, 94109998Smarkm const char *section) 9568651Skris { 9668651Skris CONF_VALUE *v; 9768651Skris 9868651Skris v=_CONF_get_section(conf,section); 9968651Skris if (v != NULL) 10068651Skris return((STACK_OF(CONF_VALUE) *)v->value); 10168651Skris else 10268651Skris return(NULL); 10368651Skris } 10468651Skris 10568651Skrisint _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 10668651Skris { 10768651Skris CONF_VALUE *v = NULL; 10868651Skris STACK_OF(CONF_VALUE) *ts; 10968651Skris 11068651Skris ts = (STACK_OF(CONF_VALUE) *)section->value; 11168651Skris 11268651Skris value->section=section->section; 11368651Skris if (!sk_CONF_VALUE_push(ts,value)) 11468651Skris { 11568651Skris return 0; 11668651Skris } 11768651Skris 118238405Sjkim v = lh_CONF_VALUE_insert(conf->data, value); 11968651Skris if (v != NULL) 12068651Skris { 121194206Ssimon (void)sk_CONF_VALUE_delete_ptr(ts,v); 12268651Skris OPENSSL_free(v->name); 12368651Skris OPENSSL_free(v->value); 12468651Skris OPENSSL_free(v); 12568651Skris } 12668651Skris return 1; 12768651Skris } 12868651Skris 129109998Smarkmchar *_CONF_get_string(const CONF *conf, const char *section, const char *name) 13068651Skris { 13168651Skris CONF_VALUE *v,vv; 13268651Skris char *p; 13368651Skris 13468651Skris if (name == NULL) return(NULL); 13568651Skris if (conf != NULL) 13668651Skris { 13768651Skris if (section != NULL) 13868651Skris { 139109998Smarkm vv.name=(char *)name; 140109998Smarkm vv.section=(char *)section; 141238405Sjkim v=lh_CONF_VALUE_retrieve(conf->data,&vv); 14268651Skris if (v != NULL) return(v->value); 14368651Skris if (strcmp(section,"ENV") == 0) 14468651Skris { 145238405Sjkim p=getenv(name); 14668651Skris if (p != NULL) return(p); 14768651Skris } 14868651Skris } 14968651Skris vv.section="default"; 150109998Smarkm vv.name=(char *)name; 151238405Sjkim v=lh_CONF_VALUE_retrieve(conf->data,&vv); 15268651Skris if (v != NULL) 15368651Skris return(v->value); 15468651Skris else 15568651Skris return(NULL); 15668651Skris } 15768651Skris else 158238405Sjkim return(getenv(name)); 15968651Skris } 16068651Skris 161109998Smarkm#if 0 /* There's no way to provide error checking with this function, so 162109998Smarkm force implementors of the higher levels to get a string and read 163109998Smarkm the number themselves. */ 16468651Skrislong _CONF_get_number(CONF *conf, char *section, char *name) 16568651Skris { 16668651Skris char *str; 16768651Skris long ret=0; 16868651Skris 16968651Skris str=_CONF_get_string(conf,section,name); 17068651Skris if (str == NULL) return(0); 17168651Skris for (;;) 17268651Skris { 17368651Skris if (conf->meth->is_number(conf, *str)) 17468651Skris ret=ret*10+conf->meth->to_int(conf, *str); 17568651Skris else 17668651Skris return(ret); 17768651Skris str++; 17868651Skris } 17968651Skris } 180109998Smarkm#endif 18168651Skris 182238405Sjkimstatic unsigned long conf_value_hash(const CONF_VALUE *v) 183238405Sjkim { 184238405Sjkim return (lh_strhash(v->section)<<2)^lh_strhash(v->name); 185238405Sjkim } 186238405Sjkimstatic IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) 187238405Sjkim 188238405Sjkimstatic int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 189238405Sjkim { 190238405Sjkim int i; 191238405Sjkim 192238405Sjkim if (a->section != b->section) 193238405Sjkim { 194238405Sjkim i=strcmp(a->section,b->section); 195238405Sjkim if (i) return(i); 196238405Sjkim } 197238405Sjkim 198238405Sjkim if ((a->name != NULL) && (b->name != NULL)) 199238405Sjkim { 200238405Sjkim i=strcmp(a->name,b->name); 201238405Sjkim return(i); 202238405Sjkim } 203238405Sjkim else if (a->name == b->name) 204238405Sjkim return(0); 205238405Sjkim else 206238405Sjkim return((a->name == NULL)?-1:1); 207238405Sjkim } 208238405Sjkimstatic IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) 209238405Sjkim 21068651Skrisint _CONF_new_data(CONF *conf) 21168651Skris { 21268651Skris if (conf == NULL) 21368651Skris { 21468651Skris return 0; 21568651Skris } 21668651Skris if (conf->data == NULL) 217238405Sjkim if ((conf->data = lh_CONF_VALUE_new()) == NULL) 21868651Skris { 21968651Skris return 0; 22068651Skris } 22168651Skris return 1; 22268651Skris } 22368651Skris 22468651Skrisvoid _CONF_free_data(CONF *conf) 22568651Skris { 22668651Skris if (conf == NULL || conf->data == NULL) return; 22768651Skris 228238405Sjkim lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make 229238405Sjkim * sure the 'OPENSSL_free()' works as 230238405Sjkim * expected */ 231238405Sjkim lh_CONF_VALUE_doall_arg(conf->data, 232238405Sjkim LHASH_DOALL_ARG_FN(value_free_hash), 233238405Sjkim LHASH_OF(CONF_VALUE), conf->data); 23468651Skris 23568651Skris /* We now have only 'section' entries in the hash table. 23668651Skris * Due to problems with */ 23768651Skris 238238405Sjkim lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); 239238405Sjkim lh_CONF_VALUE_free(conf->data); 24068651Skris } 24168651Skris 242238405Sjkimstatic void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) 24368651Skris { 24468651Skris if (a->name != NULL) 245238405Sjkim (void)lh_CONF_VALUE_delete(conf,a); 24668651Skris } 24768651Skris 248238405Sjkimstatic void value_free_stack_doall(CONF_VALUE *a) 24968651Skris { 25068651Skris CONF_VALUE *vv; 251238405Sjkim STACK_OF(CONF_VALUE) *sk; 25268651Skris int i; 25368651Skris 25468651Skris if (a->name != NULL) return; 25568651Skris 256238405Sjkim sk=(STACK_OF(CONF_VALUE) *)a->value; 257238405Sjkim for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--) 25868651Skris { 259238405Sjkim vv=sk_CONF_VALUE_value(sk,i); 26068651Skris OPENSSL_free(vv->value); 26168651Skris OPENSSL_free(vv->name); 26268651Skris OPENSSL_free(vv); 26368651Skris } 264238405Sjkim if (sk != NULL) sk_CONF_VALUE_free(sk); 26568651Skris OPENSSL_free(a->section); 26668651Skris OPENSSL_free(a); 26768651Skris } 26868651Skris 26968651Skris/* Up until OpenSSL 0.9.5a, this was new_section */ 270109998SmarkmCONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 27168651Skris { 272238405Sjkim STACK_OF(CONF_VALUE) *sk=NULL; 27368651Skris int ok=0,i; 27468651Skris CONF_VALUE *v=NULL,*vv; 27568651Skris 276238405Sjkim if ((sk=sk_CONF_VALUE_new_null()) == NULL) 27768651Skris goto err; 278238405Sjkim if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) 27968651Skris goto err; 28068651Skris i=strlen(section)+1; 281238405Sjkim if ((v->section=OPENSSL_malloc(i)) == NULL) 28268651Skris goto err; 28368651Skris 28468651Skris memcpy(v->section,section,i); 28568651Skris v->name=NULL; 28668651Skris v->value=(char *)sk; 28768651Skris 288238405Sjkim vv=lh_CONF_VALUE_insert(conf->data,v); 289238405Sjkim OPENSSL_assert(vv == NULL); 29068651Skris ok=1; 29168651Skriserr: 29268651Skris if (!ok) 29368651Skris { 294238405Sjkim if (sk != NULL) sk_CONF_VALUE_free(sk); 29568651Skris if (v != NULL) OPENSSL_free(v); 29668651Skris v=NULL; 29768651Skris } 29868651Skris return(v); 29968651Skris } 30068651Skris 30168651SkrisIMPLEMENT_STACK_OF(CONF_VALUE) 302