168651Skris/* conf_lib.c */ 2280304Sjkim/* 3280304Sjkim * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4280304Sjkim * 2000. 568651Skris */ 668651Skris/* ==================================================================== 768651Skris * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 868651Skris * 968651Skris * Redistribution and use in source and binary forms, with or without 1068651Skris * modification, are permitted provided that the following conditions 1168651Skris * are met: 1268651Skris * 1368651Skris * 1. Redistributions of source code must retain the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer. 1568651Skris * 1668651Skris * 2. Redistributions in binary form must reproduce the above copyright 1768651Skris * notice, this list of conditions and the following disclaimer in 1868651Skris * the documentation and/or other materials provided with the 1968651Skris * distribution. 2068651Skris * 2168651Skris * 3. All advertising materials mentioning features or use of this 2268651Skris * software must display the following acknowledgment: 2368651Skris * "This product includes software developed by the OpenSSL Project 2468651Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2568651Skris * 2668651Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2768651Skris * endorse or promote products derived from this software without 2868651Skris * prior written permission. For written permission, please contact 2968651Skris * licensing@OpenSSL.org. 3068651Skris * 3168651Skris * 5. Products derived from this software may not be called "OpenSSL" 3268651Skris * nor may "OpenSSL" appear in their names without prior written 3368651Skris * permission of the OpenSSL Project. 3468651Skris * 3568651Skris * 6. Redistributions of any form whatsoever must retain the following 3668651Skris * acknowledgment: 3768651Skris * "This product includes software developed by the OpenSSL Project 3868651Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3968651Skris * 4068651Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4168651Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4268651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4368651Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4468651Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4568651Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4668651Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4768651Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4968651Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5068651Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5168651Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5268651Skris * ==================================================================== 5368651Skris * 5468651Skris * This product includes cryptographic software written by Eric Young 5568651Skris * (eay@cryptsoft.com). This product includes software written by Tim 5668651Skris * Hudson (tjh@cryptsoft.com). 5768651Skris * 5868651Skris */ 5968651Skris 6068651Skris#include <stdio.h> 6168651Skris#include <openssl/crypto.h> 6268651Skris#include <openssl/err.h> 6368651Skris#include <openssl/conf.h> 6468651Skris#include <openssl/conf_api.h> 6568651Skris#include <openssl/lhash.h> 6668651Skris 67280304Sjkimconst char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; 6868651Skris 69280304Sjkimstatic CONF_METHOD *default_CONF_method = NULL; 7068651Skris 71109998Smarkm/* Init a 'CONF' structure from an old LHASH */ 72109998Smarkm 73238405Sjkimvoid CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) 74280304Sjkim{ 75280304Sjkim if (default_CONF_method == NULL) 76280304Sjkim default_CONF_method = NCONF_default(); 77109998Smarkm 78280304Sjkim default_CONF_method->init(conf); 79280304Sjkim conf->data = hash; 80280304Sjkim} 81109998Smarkm 82280304Sjkim/* 83280304Sjkim * The following section contains the "CONF classic" functions, rewritten in 84280304Sjkim * terms of the new CONF interface. 85280304Sjkim */ 8668651Skris 8768651Skrisint CONF_set_default_method(CONF_METHOD *meth) 88280304Sjkim{ 89280304Sjkim default_CONF_method = meth; 90280304Sjkim return 1; 91280304Sjkim} 9268651Skris 93238405SjkimLHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, 94280304Sjkim long *eline) 95280304Sjkim{ 96280304Sjkim LHASH_OF(CONF_VALUE) *ltmp; 97280304Sjkim BIO *in = NULL; 9868651Skris 99109998Smarkm#ifdef OPENSSL_SYS_VMS 100280304Sjkim in = BIO_new_file(file, "r"); 10168651Skris#else 102280304Sjkim in = BIO_new_file(file, "rb"); 10368651Skris#endif 104280304Sjkim if (in == NULL) { 105280304Sjkim CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); 106280304Sjkim return NULL; 107280304Sjkim } 10868651Skris 109280304Sjkim ltmp = CONF_load_bio(conf, in, eline); 110280304Sjkim BIO_free(in); 11168651Skris 112280304Sjkim return ltmp; 113280304Sjkim} 11468651Skris 115109998Smarkm#ifndef OPENSSL_NO_FP_API 116238405SjkimLHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, 117280304Sjkim long *eline) 118280304Sjkim{ 119280304Sjkim BIO *btmp; 120280304Sjkim LHASH_OF(CONF_VALUE) *ltmp; 121280304Sjkim if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 122280304Sjkim CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); 123280304Sjkim return NULL; 124280304Sjkim } 125280304Sjkim ltmp = CONF_load_bio(conf, btmp, eline); 126280304Sjkim BIO_free(btmp); 127280304Sjkim return ltmp; 128280304Sjkim} 12968651Skris#endif 13068651Skris 131238405SjkimLHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, 132280304Sjkim long *eline) 133280304Sjkim{ 134280304Sjkim CONF ctmp; 135280304Sjkim int ret; 13668651Skris 137280304Sjkim CONF_set_nconf(&ctmp, conf); 13868651Skris 139280304Sjkim ret = NCONF_load_bio(&ctmp, bp, eline); 140280304Sjkim if (ret) 141280304Sjkim return ctmp.data; 142280304Sjkim return NULL; 143280304Sjkim} 14468651Skris 145238405SjkimSTACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, 146280304Sjkim const char *section) 147280304Sjkim{ 148280304Sjkim if (conf == NULL) { 149280304Sjkim return NULL; 150280304Sjkim } else { 151280304Sjkim CONF ctmp; 152280304Sjkim CONF_set_nconf(&ctmp, conf); 153280304Sjkim return NCONF_get_section(&ctmp, section); 154280304Sjkim } 155280304Sjkim} 15668651Skris 157280304Sjkimchar *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, 158280304Sjkim const char *name) 159280304Sjkim{ 160280304Sjkim if (conf == NULL) { 161280304Sjkim return NCONF_get_string(NULL, group, name); 162280304Sjkim } else { 163280304Sjkim CONF ctmp; 164280304Sjkim CONF_set_nconf(&ctmp, conf); 165280304Sjkim return NCONF_get_string(&ctmp, group, name); 166280304Sjkim } 167280304Sjkim} 16868651Skris 169280304Sjkimlong CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, 170280304Sjkim const char *name) 171280304Sjkim{ 172280304Sjkim int status; 173280304Sjkim long result = 0; 174109998Smarkm 175280304Sjkim if (conf == NULL) { 176280304Sjkim status = NCONF_get_number_e(NULL, group, name, &result); 177280304Sjkim } else { 178280304Sjkim CONF ctmp; 179280304Sjkim CONF_set_nconf(&ctmp, conf); 180280304Sjkim status = NCONF_get_number_e(&ctmp, group, name, &result); 181280304Sjkim } 18268651Skris 183280304Sjkim if (status == 0) { 184280304Sjkim /* This function does not believe in errors... */ 185280304Sjkim ERR_clear_error(); 186280304Sjkim } 187280304Sjkim return result; 188280304Sjkim} 18968651Skris 190238405Sjkimvoid CONF_free(LHASH_OF(CONF_VALUE) *conf) 191280304Sjkim{ 192280304Sjkim CONF ctmp; 193280304Sjkim CONF_set_nconf(&ctmp, conf); 194280304Sjkim NCONF_free_data(&ctmp); 195280304Sjkim} 19668651Skris 197109998Smarkm#ifndef OPENSSL_NO_FP_API 198238405Sjkimint CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) 199280304Sjkim{ 200280304Sjkim BIO *btmp; 201280304Sjkim int ret; 20268651Skris 203280304Sjkim if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 204280304Sjkim CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); 205280304Sjkim return 0; 206280304Sjkim } 207280304Sjkim ret = CONF_dump_bio(conf, btmp); 208280304Sjkim BIO_free(btmp); 209280304Sjkim return ret; 210280304Sjkim} 21168651Skris#endif 21268651Skris 213238405Sjkimint CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) 214280304Sjkim{ 215280304Sjkim CONF ctmp; 216280304Sjkim CONF_set_nconf(&ctmp, conf); 217280304Sjkim return NCONF_dump_bio(&ctmp, out); 218280304Sjkim} 21968651Skris 220280304Sjkim/* 221280304Sjkim * The following section contains the "New CONF" functions. They are 222280304Sjkim * completely centralised around a new CONF structure that may contain 223280304Sjkim * basically anything, but at least a method pointer and a table of data. 224280304Sjkim * These functions are also written in terms of the bridge functions used by 225280304Sjkim * the "CONF classic" functions, for consistency. 226280304Sjkim */ 22768651Skris 22868651SkrisCONF *NCONF_new(CONF_METHOD *meth) 229280304Sjkim{ 230280304Sjkim CONF *ret; 23168651Skris 232280304Sjkim if (meth == NULL) 233280304Sjkim meth = NCONF_default(); 23468651Skris 235280304Sjkim ret = meth->create(meth); 236280304Sjkim if (ret == NULL) { 237280304Sjkim CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); 238280304Sjkim return (NULL); 239280304Sjkim } 24068651Skris 241280304Sjkim return ret; 242280304Sjkim} 24368651Skris 24468651Skrisvoid NCONF_free(CONF *conf) 245280304Sjkim{ 246280304Sjkim if (conf == NULL) 247280304Sjkim return; 248280304Sjkim conf->meth->destroy(conf); 249280304Sjkim} 25068651Skris 25168651Skrisvoid NCONF_free_data(CONF *conf) 252280304Sjkim{ 253280304Sjkim if (conf == NULL) 254280304Sjkim return; 255280304Sjkim conf->meth->destroy_data(conf); 256280304Sjkim} 25768651Skris 25868651Skrisint NCONF_load(CONF *conf, const char *file, long *eline) 259280304Sjkim{ 260280304Sjkim if (conf == NULL) { 261280304Sjkim CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); 262280304Sjkim return 0; 263280304Sjkim } 26468651Skris 265280304Sjkim return conf->meth->load(conf, file, eline); 266280304Sjkim} 26768651Skris 268109998Smarkm#ifndef OPENSSL_NO_FP_API 269280304Sjkimint NCONF_load_fp(CONF *conf, FILE *fp, long *eline) 270280304Sjkim{ 271280304Sjkim BIO *btmp; 272280304Sjkim int ret; 273280304Sjkim if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 274280304Sjkim CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); 275280304Sjkim return 0; 276280304Sjkim } 277280304Sjkim ret = NCONF_load_bio(conf, btmp, eline); 278280304Sjkim BIO_free(btmp); 279280304Sjkim return ret; 280280304Sjkim} 28168651Skris#endif 28268651Skris 283280304Sjkimint NCONF_load_bio(CONF *conf, BIO *bp, long *eline) 284280304Sjkim{ 285280304Sjkim if (conf == NULL) { 286280304Sjkim CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); 287280304Sjkim return 0; 288280304Sjkim } 28968651Skris 290280304Sjkim return conf->meth->load_bio(conf, bp, eline); 291280304Sjkim} 29268651Skris 293280304SjkimSTACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) 294280304Sjkim{ 295280304Sjkim if (conf == NULL) { 296280304Sjkim CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); 297280304Sjkim return NULL; 298280304Sjkim } 29968651Skris 300280304Sjkim if (section == NULL) { 301280304Sjkim CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); 302280304Sjkim return NULL; 303280304Sjkim } 30472613Skris 305280304Sjkim return _CONF_get_section_values(conf, section); 306280304Sjkim} 30768651Skris 308280304Sjkimchar *NCONF_get_string(const CONF *conf, const char *group, const char *name) 309280304Sjkim{ 310280304Sjkim char *s = _CONF_get_string(conf, group, name); 31172613Skris 312280304Sjkim /* 313280304Sjkim * Since we may get a value from an environment variable even if conf is 314280304Sjkim * NULL, let's check the value first 315280304Sjkim */ 316280304Sjkim if (s) 317280304Sjkim return s; 31872613Skris 319280304Sjkim if (conf == NULL) { 320280304Sjkim CONFerr(CONF_F_NCONF_GET_STRING, 321280304Sjkim CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); 322280304Sjkim return NULL; 323280304Sjkim } 324280304Sjkim CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); 325280304Sjkim ERR_add_error_data(4, "group=", group, " name=", name); 326280304Sjkim return NULL; 327280304Sjkim} 32868651Skris 329280304Sjkimint NCONF_get_number_e(const CONF *conf, const char *group, const char *name, 330280304Sjkim long *result) 331280304Sjkim{ 332280304Sjkim char *str; 333109998Smarkm 334280304Sjkim if (result == NULL) { 335280304Sjkim CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); 336280304Sjkim return 0; 337280304Sjkim } 338109998Smarkm 339280304Sjkim str = NCONF_get_string(conf, group, name); 340109998Smarkm 341280304Sjkim if (str == NULL) 342280304Sjkim return 0; 343109998Smarkm 344280304Sjkim for (*result = 0; conf->meth->is_number(conf, *str);) { 345280304Sjkim *result = (*result) * 10 + conf->meth->to_int(conf, *str); 346280304Sjkim str++; 347280304Sjkim } 348109998Smarkm 349280304Sjkim return 1; 350280304Sjkim} 35168651Skris 352109998Smarkm#ifndef OPENSSL_NO_FP_API 353109998Smarkmint NCONF_dump_fp(const CONF *conf, FILE *out) 354280304Sjkim{ 355280304Sjkim BIO *btmp; 356280304Sjkim int ret; 357280304Sjkim if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 358280304Sjkim CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); 359280304Sjkim return 0; 360280304Sjkim } 361280304Sjkim ret = NCONF_dump_bio(conf, btmp); 362280304Sjkim BIO_free(btmp); 363280304Sjkim return ret; 364280304Sjkim} 36568651Skris#endif 36668651Skris 367109998Smarkmint NCONF_dump_bio(const CONF *conf, BIO *out) 368280304Sjkim{ 369280304Sjkim if (conf == NULL) { 370280304Sjkim CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); 371280304Sjkim return 0; 372280304Sjkim } 37368651Skris 374280304Sjkim return conf->meth->dump(conf, out); 375280304Sjkim} 37668651Skris 377109998Smarkm/* This function should be avoided */ 378109998Smarkm#if 0 379280304Sjkimlong NCONF_get_number(CONF *conf, char *group, char *name) 380280304Sjkim{ 381280304Sjkim int status; 382280304Sjkim long ret = 0; 383109998Smarkm 384280304Sjkim status = NCONF_get_number_e(conf, group, name, &ret); 385280304Sjkim if (status == 0) { 386280304Sjkim /* This function does not believe in errors... */ 387280304Sjkim ERR_get_error(); 388280304Sjkim } 389280304Sjkim return ret; 390280304Sjkim} 391109998Smarkm#endif 392