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. 8280304Sjkim * 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). 15280304Sjkim * 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. 22280304Sjkim * 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 :-). 37280304Sjkim * 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)" 40280304Sjkim * 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. 52280304Sjkim * 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 62280304Sjkim# 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, 74280304Sjkim 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, 77280304Sjkim 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) 82280304Sjkim{ 83280304Sjkim CONF_VALUE *v, vv; 8468651Skris 85280304Sjkim if ((conf == NULL) || (section == NULL)) 86280304Sjkim return (NULL); 87280304Sjkim vv.name = NULL; 88280304Sjkim vv.section = (char *)section; 89280304Sjkim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 90280304Sjkim return (v); 91280304Sjkim} 9268651Skris 9368651Skris/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ 94109998SmarkmSTACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, 95280304Sjkim const char *section) 96280304Sjkim{ 97280304Sjkim CONF_VALUE *v; 9868651Skris 99280304Sjkim v = _CONF_get_section(conf, section); 100280304Sjkim if (v != NULL) 101280304Sjkim return ((STACK_OF(CONF_VALUE) *)v->value); 102280304Sjkim else 103280304Sjkim return (NULL); 104280304Sjkim} 10568651Skris 10668651Skrisint _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 107280304Sjkim{ 108280304Sjkim CONF_VALUE *v = NULL; 109280304Sjkim STACK_OF(CONF_VALUE) *ts; 11068651Skris 111280304Sjkim ts = (STACK_OF(CONF_VALUE) *)section->value; 11268651Skris 113280304Sjkim value->section = section->section; 114280304Sjkim if (!sk_CONF_VALUE_push(ts, value)) { 115280304Sjkim return 0; 116280304Sjkim } 11768651Skris 118280304Sjkim v = lh_CONF_VALUE_insert(conf->data, value); 119280304Sjkim if (v != NULL) { 120280304Sjkim (void)sk_CONF_VALUE_delete_ptr(ts, v); 121280304Sjkim OPENSSL_free(v->name); 122280304Sjkim OPENSSL_free(v->value); 123280304Sjkim OPENSSL_free(v); 124280304Sjkim } 125280304Sjkim return 1; 126280304Sjkim} 12768651Skris 128280304Sjkimchar *_CONF_get_string(const CONF *conf, const char *section, 129280304Sjkim const char *name) 130280304Sjkim{ 131280304Sjkim CONF_VALUE *v, vv; 132280304Sjkim char *p; 13368651Skris 134280304Sjkim if (name == NULL) 135280304Sjkim return (NULL); 136280304Sjkim if (conf != NULL) { 137280304Sjkim if (section != NULL) { 138280304Sjkim vv.name = (char *)name; 139280304Sjkim vv.section = (char *)section; 140280304Sjkim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 141280304Sjkim if (v != NULL) 142280304Sjkim return (v->value); 143280304Sjkim if (strcmp(section, "ENV") == 0) { 144280304Sjkim p = getenv(name); 145280304Sjkim if (p != NULL) 146280304Sjkim return (p); 147280304Sjkim } 148280304Sjkim } 149280304Sjkim vv.section = "default"; 150280304Sjkim vv.name = (char *)name; 151280304Sjkim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 152280304Sjkim if (v != NULL) 153280304Sjkim return (v->value); 154280304Sjkim else 155280304Sjkim return (NULL); 156280304Sjkim } else 157280304Sjkim return (getenv(name)); 158280304Sjkim} 15968651Skris 160280304Sjkim#if 0 /* There's no way to provide error checking 161280304Sjkim * with this function, so force implementors 162280304Sjkim * of the higher levels to get a string and 163280304Sjkim * read the number themselves. */ 16468651Skrislong _CONF_get_number(CONF *conf, char *section, char *name) 165280304Sjkim{ 166280304Sjkim char *str; 167280304Sjkim long ret = 0; 16868651Skris 169280304Sjkim str = _CONF_get_string(conf, section, name); 170280304Sjkim if (str == NULL) 171280304Sjkim return (0); 172280304Sjkim for (;;) { 173280304Sjkim if (conf->meth->is_number(conf, *str)) 174280304Sjkim ret = ret * 10 + conf->meth->to_int(conf, *str); 175280304Sjkim else 176280304Sjkim return (ret); 177280304Sjkim str++; 178280304Sjkim } 179280304Sjkim} 180109998Smarkm#endif 18168651Skris 182238405Sjkimstatic unsigned long conf_value_hash(const CONF_VALUE *v) 183280304Sjkim{ 184280304Sjkim return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); 185280304Sjkim} 186280304Sjkim 187238405Sjkimstatic IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) 188238405Sjkim 189238405Sjkimstatic int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 190280304Sjkim{ 191280304Sjkim int i; 192238405Sjkim 193280304Sjkim if (a->section != b->section) { 194280304Sjkim i = strcmp(a->section, b->section); 195280304Sjkim if (i) 196280304Sjkim return (i); 197280304Sjkim } 198238405Sjkim 199280304Sjkim if ((a->name != NULL) && (b->name != NULL)) { 200280304Sjkim i = strcmp(a->name, b->name); 201280304Sjkim return (i); 202280304Sjkim } else if (a->name == b->name) 203280304Sjkim return (0); 204280304Sjkim else 205280304Sjkim return ((a->name == NULL) ? -1 : 1); 206280304Sjkim} 207280304Sjkim 208238405Sjkimstatic IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) 209238405Sjkim 21068651Skrisint _CONF_new_data(CONF *conf) 211280304Sjkim{ 212280304Sjkim if (conf == NULL) { 213280304Sjkim return 0; 214280304Sjkim } 215280304Sjkim if (conf->data == NULL) 216280304Sjkim if ((conf->data = lh_CONF_VALUE_new()) == NULL) { 217280304Sjkim return 0; 218280304Sjkim } 219280304Sjkim return 1; 220280304Sjkim} 22168651Skris 22268651Skrisvoid _CONF_free_data(CONF *conf) 223280304Sjkim{ 224280304Sjkim if (conf == NULL || conf->data == NULL) 225280304Sjkim return; 22668651Skris 227280304Sjkim lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the 228280304Sjkim * 'OPENSSL_free()' works as * 229280304Sjkim * expected */ 230280304Sjkim lh_CONF_VALUE_doall_arg(conf->data, 231280304Sjkim LHASH_DOALL_ARG_FN(value_free_hash), 232280304Sjkim LHASH_OF(CONF_VALUE), conf->data); 23368651Skris 234280304Sjkim /* 235280304Sjkim * We now have only 'section' entries in the hash table. Due to problems 236280304Sjkim * with 237280304Sjkim */ 23868651Skris 239280304Sjkim lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); 240280304Sjkim lh_CONF_VALUE_free(conf->data); 241280304Sjkim} 24268651Skris 243280304Sjkimstatic void value_free_hash_doall_arg(CONF_VALUE *a, 244280304Sjkim LHASH_OF(CONF_VALUE) *conf) 245280304Sjkim{ 246280304Sjkim if (a->name != NULL) 247280304Sjkim (void)lh_CONF_VALUE_delete(conf, a); 248280304Sjkim} 24968651Skris 250238405Sjkimstatic void value_free_stack_doall(CONF_VALUE *a) 251280304Sjkim{ 252280304Sjkim CONF_VALUE *vv; 253280304Sjkim STACK_OF(CONF_VALUE) *sk; 254280304Sjkim int i; 25568651Skris 256280304Sjkim if (a->name != NULL) 257280304Sjkim return; 25868651Skris 259280304Sjkim sk = (STACK_OF(CONF_VALUE) *)a->value; 260280304Sjkim for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { 261280304Sjkim vv = sk_CONF_VALUE_value(sk, i); 262280304Sjkim OPENSSL_free(vv->value); 263280304Sjkim OPENSSL_free(vv->name); 264280304Sjkim OPENSSL_free(vv); 265280304Sjkim } 266280304Sjkim if (sk != NULL) 267280304Sjkim sk_CONF_VALUE_free(sk); 268280304Sjkim OPENSSL_free(a->section); 269280304Sjkim OPENSSL_free(a); 270280304Sjkim} 27168651Skris 27268651Skris/* Up until OpenSSL 0.9.5a, this was new_section */ 273109998SmarkmCONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 274280304Sjkim{ 275280304Sjkim STACK_OF(CONF_VALUE) *sk = NULL; 276280304Sjkim int ok = 0, i; 277280304Sjkim CONF_VALUE *v = NULL, *vv; 27868651Skris 279280304Sjkim if ((sk = sk_CONF_VALUE_new_null()) == NULL) 280280304Sjkim goto err; 281280304Sjkim if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) 282280304Sjkim goto err; 283280304Sjkim i = strlen(section) + 1; 284280304Sjkim if ((v->section = OPENSSL_malloc(i)) == NULL) 285280304Sjkim goto err; 28668651Skris 287280304Sjkim memcpy(v->section, section, i); 288280304Sjkim v->name = NULL; 289280304Sjkim v->value = (char *)sk; 29068651Skris 291280304Sjkim vv = lh_CONF_VALUE_insert(conf->data, v); 292280304Sjkim OPENSSL_assert(vv == NULL); 293280304Sjkim ok = 1; 294280304Sjkim err: 295280304Sjkim if (!ok) { 296280304Sjkim if (sk != NULL) 297280304Sjkim sk_CONF_VALUE_free(sk); 298280304Sjkim if (v != NULL) 299280304Sjkim OPENSSL_free(v); 300280304Sjkim v = NULL; 301280304Sjkim } 302280304Sjkim return (v); 303280304Sjkim} 304280304Sjkim 30568651SkrisIMPLEMENT_STACK_OF(CONF_VALUE) 306