168651Skris/* conf_lib.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4296465Sdelphij * 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 14296465Sdelphij * 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 67296465Sdelphijconst char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; 6868651Skris 69296465Sdelphijstatic CONF_METHOD *default_CONF_method = NULL; 7068651Skris 71109998Smarkm/* Init a 'CONF' structure from an old LHASH */ 72109998Smarkm 73109998Smarkmvoid CONF_set_nconf(CONF *conf, LHASH *hash) 74296465Sdelphij{ 75296465Sdelphij if (default_CONF_method == NULL) 76296465Sdelphij default_CONF_method = NCONF_default(); 77109998Smarkm 78296465Sdelphij default_CONF_method->init(conf); 79296465Sdelphij conf->data = hash; 80296465Sdelphij} 81109998Smarkm 82296465Sdelphij/* 83296465Sdelphij * The following section contains the "CONF classic" functions, rewritten in 84296465Sdelphij * terms of the new CONF interface. 85296465Sdelphij */ 8668651Skris 8768651Skrisint CONF_set_default_method(CONF_METHOD *meth) 88296465Sdelphij{ 89296465Sdelphij default_CONF_method = meth; 90296465Sdelphij return 1; 91296465Sdelphij} 9268651Skris 9368651SkrisLHASH *CONF_load(LHASH *conf, const char *file, long *eline) 94296465Sdelphij{ 95296465Sdelphij LHASH *ltmp; 96296465Sdelphij BIO *in = NULL; 9768651Skris 98109998Smarkm#ifdef OPENSSL_SYS_VMS 99296465Sdelphij in = BIO_new_file(file, "r"); 10068651Skris#else 101296465Sdelphij in = BIO_new_file(file, "rb"); 10268651Skris#endif 103296465Sdelphij if (in == NULL) { 104296465Sdelphij CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); 105296465Sdelphij return NULL; 106296465Sdelphij } 10768651Skris 108296465Sdelphij ltmp = CONF_load_bio(conf, in, eline); 109296465Sdelphij BIO_free(in); 11068651Skris 111296465Sdelphij return ltmp; 112296465Sdelphij} 11368651Skris 114109998Smarkm#ifndef OPENSSL_NO_FP_API 115296465SdelphijLHASH *CONF_load_fp(LHASH *conf, FILE *fp, long *eline) 116296465Sdelphij{ 117296465Sdelphij BIO *btmp; 118296465Sdelphij LHASH *ltmp; 119296465Sdelphij if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 120296465Sdelphij CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); 121296465Sdelphij return NULL; 122296465Sdelphij } 123296465Sdelphij ltmp = CONF_load_bio(conf, btmp, eline); 124296465Sdelphij BIO_free(btmp); 125296465Sdelphij return ltmp; 126296465Sdelphij} 12768651Skris#endif 12868651Skris 129296465SdelphijLHASH *CONF_load_bio(LHASH *conf, BIO *bp, long *eline) 130296465Sdelphij{ 131296465Sdelphij CONF ctmp; 132296465Sdelphij int ret; 13368651Skris 134296465Sdelphij CONF_set_nconf(&ctmp, conf); 13568651Skris 136296465Sdelphij ret = NCONF_load_bio(&ctmp, bp, eline); 137296465Sdelphij if (ret) 138296465Sdelphij return ctmp.data; 139296465Sdelphij return NULL; 140296465Sdelphij} 14168651Skris 142296465SdelphijSTACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf, const char *section) 143296465Sdelphij{ 144296465Sdelphij if (conf == NULL) { 145296465Sdelphij return NULL; 146296465Sdelphij } else { 147296465Sdelphij CONF ctmp; 148296465Sdelphij CONF_set_nconf(&ctmp, conf); 149296465Sdelphij return NCONF_get_section(&ctmp, section); 150296465Sdelphij } 151296465Sdelphij} 15268651Skris 153296465Sdelphijchar *CONF_get_string(LHASH *conf, const char *group, const char *name) 154296465Sdelphij{ 155296465Sdelphij if (conf == NULL) { 156296465Sdelphij return NCONF_get_string(NULL, group, name); 157296465Sdelphij } else { 158296465Sdelphij CONF ctmp; 159296465Sdelphij CONF_set_nconf(&ctmp, conf); 160296465Sdelphij return NCONF_get_string(&ctmp, group, name); 161296465Sdelphij } 162296465Sdelphij} 16368651Skris 164296465Sdelphijlong CONF_get_number(LHASH *conf, const char *group, const char *name) 165296465Sdelphij{ 166296465Sdelphij int status; 167296465Sdelphij long result = 0; 168109998Smarkm 169296465Sdelphij if (conf == NULL) { 170296465Sdelphij status = NCONF_get_number_e(NULL, group, name, &result); 171296465Sdelphij } else { 172296465Sdelphij CONF ctmp; 173296465Sdelphij CONF_set_nconf(&ctmp, conf); 174296465Sdelphij status = NCONF_get_number_e(&ctmp, group, name, &result); 175296465Sdelphij } 17668651Skris 177296465Sdelphij if (status == 0) { 178296465Sdelphij /* This function does not believe in errors... */ 179296465Sdelphij ERR_clear_error(); 180296465Sdelphij } 181296465Sdelphij return result; 182296465Sdelphij} 18368651Skris 18468651Skrisvoid CONF_free(LHASH *conf) 185296465Sdelphij{ 186296465Sdelphij CONF ctmp; 187296465Sdelphij CONF_set_nconf(&ctmp, conf); 188296465Sdelphij NCONF_free_data(&ctmp); 189296465Sdelphij} 19068651Skris 191109998Smarkm#ifndef OPENSSL_NO_FP_API 19268651Skrisint CONF_dump_fp(LHASH *conf, FILE *out) 193296465Sdelphij{ 194296465Sdelphij BIO *btmp; 195296465Sdelphij int ret; 19668651Skris 197296465Sdelphij if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 198296465Sdelphij CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); 199296465Sdelphij return 0; 200296465Sdelphij } 201296465Sdelphij ret = CONF_dump_bio(conf, btmp); 202296465Sdelphij BIO_free(btmp); 203296465Sdelphij return ret; 204296465Sdelphij} 20568651Skris#endif 20668651Skris 20768651Skrisint CONF_dump_bio(LHASH *conf, BIO *out) 208296465Sdelphij{ 209296465Sdelphij CONF ctmp; 210296465Sdelphij CONF_set_nconf(&ctmp, conf); 211296465Sdelphij return NCONF_dump_bio(&ctmp, out); 212296465Sdelphij} 21368651Skris 214296465Sdelphij/* 215296465Sdelphij * The following section contains the "New CONF" functions. They are 216296465Sdelphij * completely centralised around a new CONF structure that may contain 217296465Sdelphij * basically anything, but at least a method pointer and a table of data. 218296465Sdelphij * These functions are also written in terms of the bridge functions used by 219296465Sdelphij * the "CONF classic" functions, for consistency. 220296465Sdelphij */ 22168651Skris 22268651SkrisCONF *NCONF_new(CONF_METHOD *meth) 223296465Sdelphij{ 224296465Sdelphij CONF *ret; 22568651Skris 226296465Sdelphij if (meth == NULL) 227296465Sdelphij meth = NCONF_default(); 22868651Skris 229296465Sdelphij ret = meth->create(meth); 230296465Sdelphij if (ret == NULL) { 231296465Sdelphij CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); 232296465Sdelphij return (NULL); 233296465Sdelphij } 23468651Skris 235296465Sdelphij return ret; 236296465Sdelphij} 23768651Skris 23868651Skrisvoid NCONF_free(CONF *conf) 239296465Sdelphij{ 240296465Sdelphij if (conf == NULL) 241296465Sdelphij return; 242296465Sdelphij conf->meth->destroy(conf); 243296465Sdelphij} 24468651Skris 24568651Skrisvoid NCONF_free_data(CONF *conf) 246296465Sdelphij{ 247296465Sdelphij if (conf == NULL) 248296465Sdelphij return; 249296465Sdelphij conf->meth->destroy_data(conf); 250296465Sdelphij} 25168651Skris 25268651Skrisint NCONF_load(CONF *conf, const char *file, long *eline) 253296465Sdelphij{ 254296465Sdelphij if (conf == NULL) { 255296465Sdelphij CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); 256296465Sdelphij return 0; 257296465Sdelphij } 25868651Skris 259296465Sdelphij return conf->meth->load(conf, file, eline); 260296465Sdelphij} 26168651Skris 262109998Smarkm#ifndef OPENSSL_NO_FP_API 263296465Sdelphijint NCONF_load_fp(CONF *conf, FILE *fp, long *eline) 264296465Sdelphij{ 265296465Sdelphij BIO *btmp; 266296465Sdelphij int ret; 267296465Sdelphij if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 268296465Sdelphij CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); 269296465Sdelphij return 0; 270296465Sdelphij } 271296465Sdelphij ret = NCONF_load_bio(conf, btmp, eline); 272296465Sdelphij BIO_free(btmp); 273296465Sdelphij return ret; 274296465Sdelphij} 27568651Skris#endif 27668651Skris 277296465Sdelphijint NCONF_load_bio(CONF *conf, BIO *bp, long *eline) 278296465Sdelphij{ 279296465Sdelphij if (conf == NULL) { 280296465Sdelphij CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); 281296465Sdelphij return 0; 282296465Sdelphij } 28368651Skris 284296465Sdelphij return conf->meth->load_bio(conf, bp, eline); 285296465Sdelphij} 28668651Skris 287296465SdelphijSTACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) 288296465Sdelphij{ 289296465Sdelphij if (conf == NULL) { 290296465Sdelphij CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); 291296465Sdelphij return NULL; 292296465Sdelphij } 29368651Skris 294296465Sdelphij if (section == NULL) { 295296465Sdelphij CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); 296296465Sdelphij return NULL; 297296465Sdelphij } 29872613Skris 299296465Sdelphij return _CONF_get_section_values(conf, section); 300296465Sdelphij} 30168651Skris 302296465Sdelphijchar *NCONF_get_string(const CONF *conf, const char *group, const char *name) 303296465Sdelphij{ 304296465Sdelphij char *s = _CONF_get_string(conf, group, name); 30572613Skris 306296465Sdelphij /* 307296465Sdelphij * Since we may get a value from an environment variable even if conf is 308296465Sdelphij * NULL, let's check the value first 309296465Sdelphij */ 310296465Sdelphij if (s) 311296465Sdelphij return s; 31272613Skris 313296465Sdelphij if (conf == NULL) { 314296465Sdelphij CONFerr(CONF_F_NCONF_GET_STRING, 315296465Sdelphij CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); 316296465Sdelphij return NULL; 317296465Sdelphij } 318296465Sdelphij CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); 319296465Sdelphij ERR_add_error_data(4, "group=", group, " name=", name); 320296465Sdelphij return NULL; 321296465Sdelphij} 32268651Skris 323296465Sdelphijint NCONF_get_number_e(const CONF *conf, const char *group, const char *name, 324296465Sdelphij long *result) 325296465Sdelphij{ 326296465Sdelphij char *str; 327109998Smarkm 328296465Sdelphij if (result == NULL) { 329296465Sdelphij CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); 330296465Sdelphij return 0; 331296465Sdelphij } 332109998Smarkm 333296465Sdelphij str = NCONF_get_string(conf, group, name); 334109998Smarkm 335296465Sdelphij if (str == NULL) 336296465Sdelphij return 0; 337109998Smarkm 338296465Sdelphij for (*result = 0; conf->meth->is_number(conf, *str);) { 339296465Sdelphij *result = (*result) * 10 + conf->meth->to_int(conf, *str); 340296465Sdelphij str++; 341296465Sdelphij } 342109998Smarkm 343296465Sdelphij return 1; 344296465Sdelphij} 34568651Skris 346109998Smarkm#ifndef OPENSSL_NO_FP_API 347109998Smarkmint NCONF_dump_fp(const CONF *conf, FILE *out) 348296465Sdelphij{ 349296465Sdelphij BIO *btmp; 350296465Sdelphij int ret; 351296465Sdelphij if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 352296465Sdelphij CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); 353296465Sdelphij return 0; 354296465Sdelphij } 355296465Sdelphij ret = NCONF_dump_bio(conf, btmp); 356296465Sdelphij BIO_free(btmp); 357296465Sdelphij return ret; 358296465Sdelphij} 35968651Skris#endif 36068651Skris 361109998Smarkmint NCONF_dump_bio(const CONF *conf, BIO *out) 362296465Sdelphij{ 363296465Sdelphij if (conf == NULL) { 364296465Sdelphij CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); 365296465Sdelphij return 0; 366296465Sdelphij } 36768651Skris 368296465Sdelphij return conf->meth->dump(conf, out); 369296465Sdelphij} 37068651Skris 371109998Smarkm/* This function should be avoided */ 372109998Smarkm#if 0 373296465Sdelphijlong NCONF_get_number(CONF *conf, char *group, char *name) 374296465Sdelphij{ 375296465Sdelphij int status; 376296465Sdelphij long ret = 0; 377109998Smarkm 378296465Sdelphij status = NCONF_get_number_e(conf, group, name, &ret); 379296465Sdelphij if (status == 0) { 380296465Sdelphij /* This function does not believe in errors... */ 381296465Sdelphij ERR_get_error(); 382296465Sdelphij } 383296465Sdelphij return ret; 384296465Sdelphij} 385109998Smarkm#endif 386