1ddd58736SKris Kennaway /* conf_api.c */ 2ddd58736SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3ddd58736SKris Kennaway * All rights reserved. 4ddd58736SKris Kennaway * 5ddd58736SKris Kennaway * This package is an SSL implementation written 6ddd58736SKris Kennaway * by Eric Young (eay@cryptsoft.com). 7ddd58736SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 8ddd58736SKris Kennaway * 9ddd58736SKris Kennaway * This library is free for commercial and non-commercial use as long as 10ddd58736SKris Kennaway * the following conditions are aheared to. The following conditions 11ddd58736SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 12ddd58736SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13ddd58736SKris Kennaway * included with this distribution is covered by the same copyright terms 14ddd58736SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15ddd58736SKris Kennaway * 16ddd58736SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 17ddd58736SKris Kennaway * the code are not to be removed. 18ddd58736SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 19ddd58736SKris Kennaway * as the author of the parts of the library used. 20ddd58736SKris Kennaway * This can be in the form of a textual message at program startup or 21ddd58736SKris Kennaway * in documentation (online or textual) provided with the package. 22ddd58736SKris Kennaway * 23ddd58736SKris Kennaway * Redistribution and use in source and binary forms, with or without 24ddd58736SKris Kennaway * modification, are permitted provided that the following conditions 25ddd58736SKris Kennaway * are met: 26ddd58736SKris Kennaway * 1. Redistributions of source code must retain the copyright 27ddd58736SKris Kennaway * notice, this list of conditions and the following disclaimer. 28ddd58736SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 29ddd58736SKris Kennaway * notice, this list of conditions and the following disclaimer in the 30ddd58736SKris Kennaway * documentation and/or other materials provided with the distribution. 31ddd58736SKris Kennaway * 3. All advertising materials mentioning features or use of this software 32ddd58736SKris Kennaway * must display the following acknowledgement: 33ddd58736SKris Kennaway * "This product includes cryptographic software written by 34ddd58736SKris Kennaway * Eric Young (eay@cryptsoft.com)" 35ddd58736SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 36ddd58736SKris Kennaway * being used are not cryptographic related :-). 37ddd58736SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 38ddd58736SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 39ddd58736SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40ddd58736SKris Kennaway * 41ddd58736SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42ddd58736SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43ddd58736SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44ddd58736SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45ddd58736SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46ddd58736SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47ddd58736SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48ddd58736SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49ddd58736SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50ddd58736SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51ddd58736SKris Kennaway * SUCH DAMAGE. 52ddd58736SKris Kennaway * 53ddd58736SKris Kennaway * The licence and distribution terms for any publically available version or 54ddd58736SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 55ddd58736SKris Kennaway * copied and put under another distribution licence 56ddd58736SKris Kennaway * [including the GNU Public Licence.] 57ddd58736SKris Kennaway */ 58ddd58736SKris Kennaway 59ddd58736SKris Kennaway /* Part of the code in here was originally in conf.c, which is now removed */ 60ddd58736SKris Kennaway 61ddd58736SKris Kennaway #ifndef CONF_DEBUG 62ddd58736SKris Kennaway # undef NDEBUG /* avoid conflicting definitions */ 63ddd58736SKris Kennaway # define NDEBUG 64ddd58736SKris Kennaway #endif 65ddd58736SKris Kennaway 66ddd58736SKris Kennaway #include <assert.h> 6712de4ed2SJung-uk Kim #include <stdlib.h> 68ddd58736SKris Kennaway #include <string.h> 69ddd58736SKris Kennaway #include <openssl/conf.h> 70ddd58736SKris Kennaway #include <openssl/conf_api.h> 715c87c606SMark Murray #include "e_os.h" 72ddd58736SKris Kennaway 731f13597dSJung-uk Kim static void value_free_hash_doall_arg(CONF_VALUE *a, 741f13597dSJung-uk Kim LHASH_OF(CONF_VALUE) *conf); 751f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a); 761f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, 771f13597dSJung-uk Kim LHASH_OF(CONF_VALUE)) 781f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) 79ddd58736SKris Kennaway 80ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was get_section */ 815c87c606SMark Murray CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) 82ddd58736SKris Kennaway { 83ddd58736SKris Kennaway CONF_VALUE *v, vv; 84ddd58736SKris Kennaway 856f9291ceSJung-uk Kim if ((conf == NULL) || (section == NULL)) 866f9291ceSJung-uk Kim return (NULL); 87ddd58736SKris Kennaway vv.name = NULL; 885c87c606SMark Murray vv.section = (char *)section; 891f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 90ddd58736SKris Kennaway return (v); 91ddd58736SKris Kennaway } 92ddd58736SKris Kennaway 93ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was CONF_get_section */ 945c87c606SMark Murray STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, 955c87c606SMark Murray const char *section) 96ddd58736SKris Kennaway { 97ddd58736SKris Kennaway CONF_VALUE *v; 98ddd58736SKris Kennaway 99ddd58736SKris Kennaway v = _CONF_get_section(conf, section); 100ddd58736SKris Kennaway if (v != NULL) 101ddd58736SKris Kennaway return ((STACK_OF(CONF_VALUE) *)v->value); 102ddd58736SKris Kennaway else 103ddd58736SKris Kennaway return (NULL); 104ddd58736SKris Kennaway } 105ddd58736SKris Kennaway 106ddd58736SKris Kennaway int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 107ddd58736SKris Kennaway { 108ddd58736SKris Kennaway CONF_VALUE *v = NULL; 109ddd58736SKris Kennaway STACK_OF(CONF_VALUE) *ts; 110ddd58736SKris Kennaway 111ddd58736SKris Kennaway ts = (STACK_OF(CONF_VALUE) *)section->value; 112ddd58736SKris Kennaway 113ddd58736SKris Kennaway value->section = section->section; 1146f9291ceSJung-uk Kim if (!sk_CONF_VALUE_push(ts, value)) { 115ddd58736SKris Kennaway return 0; 116ddd58736SKris Kennaway } 117ddd58736SKris Kennaway 1181f13597dSJung-uk Kim v = lh_CONF_VALUE_insert(conf->data, value); 1196f9291ceSJung-uk Kim if (v != NULL) { 120db522d3aSSimon L. B. Nielsen (void)sk_CONF_VALUE_delete_ptr(ts, v); 121ddd58736SKris Kennaway OPENSSL_free(v->name); 122ddd58736SKris Kennaway OPENSSL_free(v->value); 123ddd58736SKris Kennaway OPENSSL_free(v); 124ddd58736SKris Kennaway } 125ddd58736SKris Kennaway return 1; 126ddd58736SKris Kennaway } 127ddd58736SKris Kennaway 1286f9291ceSJung-uk Kim char *_CONF_get_string(const CONF *conf, const char *section, 1296f9291ceSJung-uk Kim const char *name) 130ddd58736SKris Kennaway { 131ddd58736SKris Kennaway CONF_VALUE *v, vv; 132ddd58736SKris Kennaway char *p; 133ddd58736SKris Kennaway 1346f9291ceSJung-uk Kim if (name == NULL) 1356f9291ceSJung-uk Kim return (NULL); 1366f9291ceSJung-uk Kim if (conf != NULL) { 1376f9291ceSJung-uk Kim if (section != NULL) { 1385c87c606SMark Murray vv.name = (char *)name; 1395c87c606SMark Murray vv.section = (char *)section; 1401f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 1416f9291ceSJung-uk Kim if (v != NULL) 1426f9291ceSJung-uk Kim return (v->value); 1436f9291ceSJung-uk Kim if (strcmp(section, "ENV") == 0) { 1441f13597dSJung-uk Kim p = getenv(name); 1456f9291ceSJung-uk Kim if (p != NULL) 1466f9291ceSJung-uk Kim return (p); 147ddd58736SKris Kennaway } 148ddd58736SKris Kennaway } 149ddd58736SKris Kennaway vv.section = "default"; 1505c87c606SMark Murray vv.name = (char *)name; 1511f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 152ddd58736SKris Kennaway if (v != NULL) 153ddd58736SKris Kennaway return (v->value); 154ddd58736SKris Kennaway else 155ddd58736SKris Kennaway return (NULL); 1566f9291ceSJung-uk Kim } else 1571f13597dSJung-uk Kim return (getenv(name)); 158ddd58736SKris Kennaway } 159ddd58736SKris Kennaway 1606f9291ceSJung-uk Kim #if 0 /* There's no way to provide error checking 1616f9291ceSJung-uk Kim * with this function, so force implementors 1626f9291ceSJung-uk Kim * of the higher levels to get a string and 1636f9291ceSJung-uk Kim * read the number themselves. */ 164ddd58736SKris Kennaway long _CONF_get_number(CONF *conf, char *section, char *name) 165ddd58736SKris Kennaway { 166ddd58736SKris Kennaway char *str; 167ddd58736SKris Kennaway long ret = 0; 168ddd58736SKris Kennaway 169ddd58736SKris Kennaway str = _CONF_get_string(conf, section, name); 1706f9291ceSJung-uk Kim if (str == NULL) 1716f9291ceSJung-uk Kim return (0); 1726f9291ceSJung-uk Kim for (;;) { 173ddd58736SKris Kennaway if (conf->meth->is_number(conf, *str)) 174ddd58736SKris Kennaway ret = ret * 10 + conf->meth->to_int(conf, *str); 175ddd58736SKris Kennaway else 176ddd58736SKris Kennaway return (ret); 177ddd58736SKris Kennaway str++; 178ddd58736SKris Kennaway } 179ddd58736SKris Kennaway } 1805c87c606SMark Murray #endif 181ddd58736SKris Kennaway 1821f13597dSJung-uk Kim static unsigned long conf_value_hash(const CONF_VALUE *v) 183ddd58736SKris Kennaway { 1841f13597dSJung-uk Kim return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); 185ddd58736SKris Kennaway } 1866f9291ceSJung-uk Kim 1871f13597dSJung-uk Kim static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) 188ddd58736SKris Kennaway 1891f13597dSJung-uk Kim static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 190ddd58736SKris Kennaway { 191ddd58736SKris Kennaway int i; 192ddd58736SKris Kennaway 1936f9291ceSJung-uk Kim if (a->section != b->section) { 194ddd58736SKris Kennaway i = strcmp(a->section, b->section); 1956f9291ceSJung-uk Kim if (i) 196ddd58736SKris Kennaway return (i); 197ddd58736SKris Kennaway } 1986f9291ceSJung-uk Kim 1996f9291ceSJung-uk Kim if ((a->name != NULL) && (b->name != NULL)) { 2006f9291ceSJung-uk Kim i = strcmp(a->name, b->name); 2016f9291ceSJung-uk Kim return (i); 2026f9291ceSJung-uk Kim } else if (a->name == b->name) 203ddd58736SKris Kennaway return (0); 204ddd58736SKris Kennaway else 205ddd58736SKris Kennaway return ((a->name == NULL) ? -1 : 1); 206ddd58736SKris Kennaway } 2076f9291ceSJung-uk Kim 2081f13597dSJung-uk Kim static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) 2091f13597dSJung-uk Kim 2101f13597dSJung-uk Kim int _CONF_new_data(CONF *conf) 2111f13597dSJung-uk Kim { 2126f9291ceSJung-uk Kim if (conf == NULL) { 2131f13597dSJung-uk Kim return 0; 2141f13597dSJung-uk Kim } 2151f13597dSJung-uk Kim if (conf->data == NULL) 2166f9291ceSJung-uk Kim if ((conf->data = lh_CONF_VALUE_new()) == NULL) { 2171f13597dSJung-uk Kim return 0; 2181f13597dSJung-uk Kim } 2191f13597dSJung-uk Kim return 1; 2201f13597dSJung-uk Kim } 2211f13597dSJung-uk Kim 2221f13597dSJung-uk Kim void _CONF_free_data(CONF *conf) 2231f13597dSJung-uk Kim { 2246f9291ceSJung-uk Kim if (conf == NULL || conf->data == NULL) 2256f9291ceSJung-uk Kim return; 2261f13597dSJung-uk Kim 2276f9291ceSJung-uk Kim lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the 2286f9291ceSJung-uk Kim * 'OPENSSL_free()' works as * 2291f13597dSJung-uk Kim * expected */ 2301f13597dSJung-uk Kim lh_CONF_VALUE_doall_arg(conf->data, 2311f13597dSJung-uk Kim LHASH_DOALL_ARG_FN(value_free_hash), 2321f13597dSJung-uk Kim LHASH_OF(CONF_VALUE), conf->data); 2331f13597dSJung-uk Kim 2346f9291ceSJung-uk Kim /* 2356f9291ceSJung-uk Kim * We now have only 'section' entries in the hash table. Due to problems 2366f9291ceSJung-uk Kim * with 2376f9291ceSJung-uk Kim */ 2381f13597dSJung-uk Kim 2391f13597dSJung-uk Kim lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); 2401f13597dSJung-uk Kim lh_CONF_VALUE_free(conf->data); 2411f13597dSJung-uk Kim } 2421f13597dSJung-uk Kim 2436f9291ceSJung-uk Kim static void value_free_hash_doall_arg(CONF_VALUE *a, 2446f9291ceSJung-uk Kim LHASH_OF(CONF_VALUE) *conf) 2451f13597dSJung-uk Kim { 2461f13597dSJung-uk Kim if (a->name != NULL) 2471f13597dSJung-uk Kim (void)lh_CONF_VALUE_delete(conf, a); 2481f13597dSJung-uk Kim } 2491f13597dSJung-uk Kim 2501f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a) 2511f13597dSJung-uk Kim { 2521f13597dSJung-uk Kim CONF_VALUE *vv; 2531f13597dSJung-uk Kim STACK_OF(CONF_VALUE) *sk; 2541f13597dSJung-uk Kim int i; 2551f13597dSJung-uk Kim 2566f9291ceSJung-uk Kim if (a->name != NULL) 2576f9291ceSJung-uk Kim return; 2581f13597dSJung-uk Kim 2591f13597dSJung-uk Kim sk = (STACK_OF(CONF_VALUE) *)a->value; 2606f9291ceSJung-uk Kim for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { 2611f13597dSJung-uk Kim vv = sk_CONF_VALUE_value(sk, i); 2621f13597dSJung-uk Kim OPENSSL_free(vv->value); 2631f13597dSJung-uk Kim OPENSSL_free(vv->name); 2641f13597dSJung-uk Kim OPENSSL_free(vv); 2651f13597dSJung-uk Kim } 2666f9291ceSJung-uk Kim if (sk != NULL) 2676f9291ceSJung-uk Kim sk_CONF_VALUE_free(sk); 2681f13597dSJung-uk Kim OPENSSL_free(a->section); 2691f13597dSJung-uk Kim OPENSSL_free(a); 2701f13597dSJung-uk Kim } 271ddd58736SKris Kennaway 272ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was new_section */ 2735c87c606SMark Murray CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 274ddd58736SKris Kennaway { 2751f13597dSJung-uk Kim STACK_OF(CONF_VALUE) *sk = NULL; 276ddd58736SKris Kennaway int ok = 0, i; 277ddd58736SKris Kennaway CONF_VALUE *v = NULL, *vv; 278ddd58736SKris Kennaway 2791f13597dSJung-uk Kim if ((sk = sk_CONF_VALUE_new_null()) == NULL) 280ddd58736SKris Kennaway goto err; 2811f13597dSJung-uk Kim if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) 282ddd58736SKris Kennaway goto err; 283ddd58736SKris Kennaway i = strlen(section) + 1; 2841f13597dSJung-uk Kim if ((v->section = OPENSSL_malloc(i)) == NULL) 285ddd58736SKris Kennaway goto err; 286ddd58736SKris Kennaway 287ddd58736SKris Kennaway memcpy(v->section, section, i); 288ddd58736SKris Kennaway v->name = NULL; 289ddd58736SKris Kennaway v->value = (char *)sk; 290ddd58736SKris Kennaway 2911f13597dSJung-uk Kim vv = lh_CONF_VALUE_insert(conf->data, v); 2921f13597dSJung-uk Kim OPENSSL_assert(vv == NULL); 293dea77ea6SJung-uk Kim if (lh_CONF_VALUE_error(conf->data) > 0) 294dea77ea6SJung-uk Kim goto err; 295ddd58736SKris Kennaway ok = 1; 296ddd58736SKris Kennaway err: 2976f9291ceSJung-uk Kim if (!ok) { 2986f9291ceSJung-uk Kim if (sk != NULL) 2996f9291ceSJung-uk Kim sk_CONF_VALUE_free(sk); 3006f9291ceSJung-uk Kim if (v != NULL) 3016f9291ceSJung-uk Kim OPENSSL_free(v); 302ddd58736SKris Kennaway v = NULL; 303ddd58736SKris Kennaway } 304ddd58736SKris Kennaway return (v); 305ddd58736SKris Kennaway } 306ddd58736SKris Kennaway 307ddd58736SKris Kennaway IMPLEMENT_STACK_OF(CONF_VALUE) 308