1*f102b974Stb /* $OpenBSD: conf_api.c,v 1.21 2024/08/31 09:29:03 tb Exp $ */ 2c109e398Sbeck /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3c109e398Sbeck * All rights reserved. 4c109e398Sbeck * 5c109e398Sbeck * This package is an SSL implementation written 6c109e398Sbeck * by Eric Young (eay@cryptsoft.com). 7c109e398Sbeck * The implementation was written so as to conform with Netscapes SSL. 8c109e398Sbeck * 9c109e398Sbeck * This library is free for commercial and non-commercial use as long as 10c109e398Sbeck * the following conditions are aheared to. The following conditions 11c109e398Sbeck * apply to all code found in this distribution, be it the RC4, RSA, 12c109e398Sbeck * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13c109e398Sbeck * included with this distribution is covered by the same copyright terms 14c109e398Sbeck * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15c109e398Sbeck * 16c109e398Sbeck * Copyright remains Eric Young's, and as such any Copyright notices in 17c109e398Sbeck * the code are not to be removed. 18c109e398Sbeck * If this package is used in a product, Eric Young should be given attribution 19c109e398Sbeck * as the author of the parts of the library used. 20c109e398Sbeck * This can be in the form of a textual message at program startup or 21c109e398Sbeck * in documentation (online or textual) provided with the package. 22c109e398Sbeck * 23c109e398Sbeck * Redistribution and use in source and binary forms, with or without 24c109e398Sbeck * modification, are permitted provided that the following conditions 25c109e398Sbeck * are met: 26c109e398Sbeck * 1. Redistributions of source code must retain the copyright 27c109e398Sbeck * notice, this list of conditions and the following disclaimer. 28c109e398Sbeck * 2. Redistributions in binary form must reproduce the above copyright 29c109e398Sbeck * notice, this list of conditions and the following disclaimer in the 30c109e398Sbeck * documentation and/or other materials provided with the distribution. 31c109e398Sbeck * 3. All advertising materials mentioning features or use of this software 32c109e398Sbeck * must display the following acknowledgement: 33c109e398Sbeck * "This product includes cryptographic software written by 34c109e398Sbeck * Eric Young (eay@cryptsoft.com)" 35c109e398Sbeck * The word 'cryptographic' can be left out if the rouines from the library 36c109e398Sbeck * being used are not cryptographic related :-). 37c109e398Sbeck * 4. If you include any Windows specific code (or a derivative thereof) from 38c109e398Sbeck * the apps directory (application code) you must include an acknowledgement: 39c109e398Sbeck * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40c109e398Sbeck * 41c109e398Sbeck * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42c109e398Sbeck * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43c109e398Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44c109e398Sbeck * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45c109e398Sbeck * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46c109e398Sbeck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47c109e398Sbeck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c109e398Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49c109e398Sbeck * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50c109e398Sbeck * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51c109e398Sbeck * SUCH DAMAGE. 52c109e398Sbeck * 53c109e398Sbeck * The licence and distribution terms for any publically available version or 54c109e398Sbeck * derivative of this code cannot be changed. i.e. this code cannot simply be 55c109e398Sbeck * copied and put under another distribution licence 56c109e398Sbeck * [including the GNU Public Licence.] 57c109e398Sbeck */ 58c109e398Sbeck 59c109e398Sbeck /* Part of the code in here was originally in conf.c, which is now removed */ 60c109e398Sbeck 61c109e398Sbeck #ifndef CONF_DEBUG 62c109e398Sbeck # undef NDEBUG /* avoid conflicting definitions */ 63c109e398Sbeck # define NDEBUG 64c109e398Sbeck #endif 65c109e398Sbeck 66c32db552Sdjm #include <stdlib.h> 67c109e398Sbeck #include <string.h> 6875eb8854Sderaadt #include <unistd.h> 69c109e398Sbeck #include <openssl/conf.h> 70c109e398Sbeck 71a681313fStb #include "conf_local.h" 72a681313fStb 730a5d6edeSdjm static void value_free_hash_doall_arg(CONF_VALUE *a, 740a5d6edeSdjm LHASH_OF(CONF_VALUE) *conf); 750a5d6edeSdjm static void value_free_stack_doall(CONF_VALUE *a); 760a5d6edeSdjm static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, 770a5d6edeSdjm LHASH_OF(CONF_VALUE)) 780a5d6edeSdjm static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) 79c109e398Sbeck 80c109e398Sbeck /* Up until OpenSSL 0.9.5a, this was get_section */ 8144486fcbSjsing CONF_VALUE * 8244486fcbSjsing _CONF_get_section(const CONF *conf, const char *section) 83c109e398Sbeck { 84c109e398Sbeck CONF_VALUE *v, vv; 85c109e398Sbeck 8644486fcbSjsing if ((conf == NULL) || (section == NULL)) 8744486fcbSjsing return (NULL); 88c109e398Sbeck vv.name = NULL; 89da347917Sbeck vv.section = (char *)section; 900a5d6edeSdjm v = lh_CONF_VALUE_retrieve(conf->data, &vv); 91c109e398Sbeck return (v); 92c109e398Sbeck } 93c109e398Sbeck 94c109e398Sbeck /* Up until OpenSSL 0.9.5a, this was CONF_get_section */ 9544486fcbSjsing STACK_OF(CONF_VALUE) * 9644486fcbSjsing _CONF_get_section_values(const CONF *conf, const char *section) 97c109e398Sbeck { 98c109e398Sbeck CONF_VALUE *v; 99c109e398Sbeck 100c109e398Sbeck v = _CONF_get_section(conf, section); 101c109e398Sbeck if (v != NULL) 102c109e398Sbeck return ((STACK_OF(CONF_VALUE) *)v->value); 103c109e398Sbeck else 104c109e398Sbeck return (NULL); 105c109e398Sbeck } 106c109e398Sbeck 10744486fcbSjsing int 10844486fcbSjsing _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 109c109e398Sbeck { 110c109e398Sbeck CONF_VALUE *v = NULL; 111c109e398Sbeck STACK_OF(CONF_VALUE) *ts; 112c109e398Sbeck 113c109e398Sbeck ts = (STACK_OF(CONF_VALUE) *)section->value; 114c109e398Sbeck 115c109e398Sbeck value->section = section->section; 11644486fcbSjsing if (!sk_CONF_VALUE_push(ts, value)) { 117c109e398Sbeck return 0; 118c109e398Sbeck } 119c109e398Sbeck 1200a5d6edeSdjm v = lh_CONF_VALUE_insert(conf->data, value); 12144486fcbSjsing if (v != NULL) { 1224fcf65c5Sdjm (void)sk_CONF_VALUE_delete_ptr(ts, v); 1236f3a6cb1Sbeck free(v->name); 1246f3a6cb1Sbeck free(v->value); 1256f3a6cb1Sbeck free(v); 126c109e398Sbeck } 127c109e398Sbeck return 1; 128c109e398Sbeck } 129c109e398Sbeck 13044486fcbSjsing char * 13144486fcbSjsing _CONF_get_string(const CONF *conf, const char *section, const char *name) 132c109e398Sbeck { 133c109e398Sbeck CONF_VALUE *v, vv; 134c109e398Sbeck 13544486fcbSjsing if (name == NULL) 13644486fcbSjsing return (NULL); 13744486fcbSjsing if (conf != NULL) { 13844486fcbSjsing if (section != NULL) { 139da347917Sbeck vv.name = (char *)name; 140da347917Sbeck vv.section = (char *)section; 1410a5d6edeSdjm v = lh_CONF_VALUE_retrieve(conf->data, &vv); 14244486fcbSjsing if (v != NULL) 14344486fcbSjsing return (v->value); 144c109e398Sbeck } 145c109e398Sbeck vv.section = "default"; 146da347917Sbeck vv.name = (char *)name; 1470a5d6edeSdjm v = lh_CONF_VALUE_retrieve(conf->data, &vv); 148c109e398Sbeck if (v != NULL) 149c109e398Sbeck return (v->value); 150c109e398Sbeck else 151c109e398Sbeck return (NULL); 152920ccb62Sderaadt } else 15375eb8854Sderaadt return (NULL); 15475eb8854Sderaadt } 155c109e398Sbeck 15644486fcbSjsing static unsigned long 15744486fcbSjsing conf_value_hash(const CONF_VALUE *v) 158c109e398Sbeck { 1590a5d6edeSdjm return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); 160c109e398Sbeck } 16144486fcbSjsing 1620a5d6edeSdjm static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) 163c109e398Sbeck 16444486fcbSjsing static int 16544486fcbSjsing conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 166c109e398Sbeck { 167c109e398Sbeck int i; 168c109e398Sbeck 16944486fcbSjsing if (a->section != b->section) { 170c109e398Sbeck i = strcmp(a->section, b->section); 17144486fcbSjsing if (i) 172c109e398Sbeck return (i); 173c109e398Sbeck } 17444486fcbSjsing if ((a->name != NULL) && (b->name != NULL)) { 17544486fcbSjsing i = strcmp(a->name, b->name); 17644486fcbSjsing return (i); 17744486fcbSjsing } else if (a->name == b->name) 178c109e398Sbeck return (0); 179c109e398Sbeck else 180c109e398Sbeck return ((a->name == NULL)?-1 : 1); 181c109e398Sbeck } 18244486fcbSjsing 1830a5d6edeSdjm static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) 1840a5d6edeSdjm 18544486fcbSjsing int 18644486fcbSjsing _CONF_new_data(CONF *conf) 1870a5d6edeSdjm { 18844486fcbSjsing if (conf == NULL) { 1890a5d6edeSdjm return 0; 1900a5d6edeSdjm } 1910a5d6edeSdjm if (conf->data == NULL) 19244486fcbSjsing if ((conf->data = lh_CONF_VALUE_new()) == NULL) { 1930a5d6edeSdjm return 0; 1940a5d6edeSdjm } 1950a5d6edeSdjm return 1; 1960a5d6edeSdjm } 1970a5d6edeSdjm 19844486fcbSjsing void 19944486fcbSjsing _CONF_free_data(CONF *conf) 2000a5d6edeSdjm { 20144486fcbSjsing if (conf == NULL || conf->data == NULL) 20244486fcbSjsing return; 2030a5d6edeSdjm 2040a5d6edeSdjm lh_CONF_VALUE_doall_arg(conf->data, 2050a5d6edeSdjm LHASH_DOALL_ARG_FN(value_free_hash), 2060a5d6edeSdjm LHASH_OF(CONF_VALUE), conf->data); 2070a5d6edeSdjm 2080a5d6edeSdjm /* We now have only 'section' entries in the hash table. 2090a5d6edeSdjm * Due to problems with */ 2100a5d6edeSdjm 2110a5d6edeSdjm lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); 2120a5d6edeSdjm lh_CONF_VALUE_free(conf->data); 2130a5d6edeSdjm } 2140a5d6edeSdjm 21544486fcbSjsing static void 21644486fcbSjsing value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) 2170a5d6edeSdjm { 2180a5d6edeSdjm if (a->name != NULL) 2190a5d6edeSdjm (void)lh_CONF_VALUE_delete(conf, a); 2200a5d6edeSdjm } 2210a5d6edeSdjm 22244486fcbSjsing static void 22344486fcbSjsing value_free_stack_doall(CONF_VALUE *a) 2240a5d6edeSdjm { 2250a5d6edeSdjm CONF_VALUE *vv; 2260a5d6edeSdjm STACK_OF(CONF_VALUE) *sk; 2270a5d6edeSdjm int i; 2280a5d6edeSdjm 22944486fcbSjsing if (a->name != NULL) 23044486fcbSjsing return; 2310a5d6edeSdjm 2320a5d6edeSdjm sk = (STACK_OF(CONF_VALUE) *)a->value; 23344486fcbSjsing for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { 2340a5d6edeSdjm vv = sk_CONF_VALUE_value(sk, i); 2356f3a6cb1Sbeck free(vv->value); 2366f3a6cb1Sbeck free(vv->name); 2376f3a6cb1Sbeck free(vv); 2380a5d6edeSdjm } 23944486fcbSjsing if (sk != NULL) 24044486fcbSjsing sk_CONF_VALUE_free(sk); 2416f3a6cb1Sbeck free(a->section); 2426f3a6cb1Sbeck free(a); 2430a5d6edeSdjm } 244c109e398Sbeck 245c109e398Sbeck /* Up until OpenSSL 0.9.5a, this was new_section */ 24644486fcbSjsing CONF_VALUE * 24744486fcbSjsing _CONF_new_section(CONF *conf, const char *section) 248c109e398Sbeck { 2490a5d6edeSdjm STACK_OF(CONF_VALUE) *sk = NULL; 250c109e398Sbeck int ok = 0, i; 251c109e398Sbeck CONF_VALUE *v = NULL, *vv; 252c109e398Sbeck 2530a5d6edeSdjm if ((sk = sk_CONF_VALUE_new_null()) == NULL) 254c109e398Sbeck goto err; 2556f3a6cb1Sbeck if ((v = malloc(sizeof(CONF_VALUE))) == NULL) 256c109e398Sbeck goto err; 257c109e398Sbeck i = strlen(section) + 1; 2586f3a6cb1Sbeck if ((v->section = malloc(i)) == NULL) 259c109e398Sbeck goto err; 260c109e398Sbeck 261c109e398Sbeck memcpy(v->section, section, i); 262c109e398Sbeck v->name = NULL; 263c109e398Sbeck v->value = (char *)sk; 264c109e398Sbeck 2650a5d6edeSdjm vv = lh_CONF_VALUE_insert(conf->data, v); 266c32db552Sdjm OPENSSL_assert(vv == NULL); 267c109e398Sbeck ok = 1; 26844486fcbSjsing 269c109e398Sbeck err: 27044486fcbSjsing if (!ok) { 27144486fcbSjsing if (sk != NULL) 27244486fcbSjsing sk_CONF_VALUE_free(sk); 27344486fcbSjsing free(v); 274c109e398Sbeck v = NULL; 275c109e398Sbeck } 276c109e398Sbeck return (v); 277c109e398Sbeck } 278