1/* conf_lib.c */ 2/* 3 * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4 * 2000. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59 60#include <stdio.h> 61#include <openssl/crypto.h> 62#include <openssl/err.h> 63#include <openssl/conf.h> 64#include <openssl/conf_api.h> 65#include <openssl/lhash.h> 66 67const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; 68 69static CONF_METHOD *default_CONF_method = NULL; 70 71/* Init a 'CONF' structure from an old LHASH */ 72 73void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) 74{ 75 if (default_CONF_method == NULL) 76 default_CONF_method = NCONF_default(); 77 78 default_CONF_method->init(conf); 79 conf->data = hash; 80} 81 82/* 83 * The following section contains the "CONF classic" functions, rewritten in 84 * terms of the new CONF interface. 85 */ 86 87int CONF_set_default_method(CONF_METHOD *meth) 88{ 89 default_CONF_method = meth; 90 return 1; 91} 92 93LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, 94 long *eline) 95{ 96 LHASH_OF(CONF_VALUE) *ltmp; 97 BIO *in = NULL; 98 99#ifdef OPENSSL_SYS_VMS 100 in = BIO_new_file(file, "r"); 101#else 102 in = BIO_new_file(file, "rb"); 103#endif 104 if (in == NULL) { 105 CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); 106 return NULL; 107 } 108 109 ltmp = CONF_load_bio(conf, in, eline); 110 BIO_free(in); 111 112 return ltmp; 113} 114 115#ifndef OPENSSL_NO_FP_API 116LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, 117 long *eline) 118{ 119 BIO *btmp; 120 LHASH_OF(CONF_VALUE) *ltmp; 121 if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 122 CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); 123 return NULL; 124 } 125 ltmp = CONF_load_bio(conf, btmp, eline); 126 BIO_free(btmp); 127 return ltmp; 128} 129#endif 130 131LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, 132 long *eline) 133{ 134 CONF ctmp; 135 int ret; 136 137 CONF_set_nconf(&ctmp, conf); 138 139 ret = NCONF_load_bio(&ctmp, bp, eline); 140 if (ret) 141 return ctmp.data; 142 return NULL; 143} 144 145STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, 146 const char *section) 147{ 148 if (conf == NULL) { 149 return NULL; 150 } else { 151 CONF ctmp; 152 CONF_set_nconf(&ctmp, conf); 153 return NCONF_get_section(&ctmp, section); 154 } 155} 156 157char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, 158 const char *name) 159{ 160 if (conf == NULL) { 161 return NCONF_get_string(NULL, group, name); 162 } else { 163 CONF ctmp; 164 CONF_set_nconf(&ctmp, conf); 165 return NCONF_get_string(&ctmp, group, name); 166 } 167} 168 169long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, 170 const char *name) 171{ 172 int status; 173 long result = 0; 174 175 if (conf == NULL) { 176 status = NCONF_get_number_e(NULL, group, name, &result); 177 } else { 178 CONF ctmp; 179 CONF_set_nconf(&ctmp, conf); 180 status = NCONF_get_number_e(&ctmp, group, name, &result); 181 } 182 183 if (status == 0) { 184 /* This function does not believe in errors... */ 185 ERR_clear_error(); 186 } 187 return result; 188} 189 190void CONF_free(LHASH_OF(CONF_VALUE) *conf) 191{ 192 CONF ctmp; 193 CONF_set_nconf(&ctmp, conf); 194 NCONF_free_data(&ctmp); 195} 196 197#ifndef OPENSSL_NO_FP_API 198int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) 199{ 200 BIO *btmp; 201 int ret; 202 203 if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 204 CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); 205 return 0; 206 } 207 ret = CONF_dump_bio(conf, btmp); 208 BIO_free(btmp); 209 return ret; 210} 211#endif 212 213int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) 214{ 215 CONF ctmp; 216 CONF_set_nconf(&ctmp, conf); 217 return NCONF_dump_bio(&ctmp, out); 218} 219 220/* 221 * The following section contains the "New CONF" functions. They are 222 * completely centralised around a new CONF structure that may contain 223 * basically anything, but at least a method pointer and a table of data. 224 * These functions are also written in terms of the bridge functions used by 225 * the "CONF classic" functions, for consistency. 226 */ 227 228CONF *NCONF_new(CONF_METHOD *meth) 229{ 230 CONF *ret; 231 232 if (meth == NULL) 233 meth = NCONF_default(); 234 235 ret = meth->create(meth); 236 if (ret == NULL) { 237 CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); 238 return (NULL); 239 } 240 241 return ret; 242} 243 244void NCONF_free(CONF *conf) 245{ 246 if (conf == NULL) 247 return; 248 conf->meth->destroy(conf); 249} 250 251void NCONF_free_data(CONF *conf) 252{ 253 if (conf == NULL) 254 return; 255 conf->meth->destroy_data(conf); 256} 257 258int NCONF_load(CONF *conf, const char *file, long *eline) 259{ 260 if (conf == NULL) { 261 CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); 262 return 0; 263 } 264 265 return conf->meth->load(conf, file, eline); 266} 267 268#ifndef OPENSSL_NO_FP_API 269int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) 270{ 271 BIO *btmp; 272 int ret; 273 if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 274 CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); 275 return 0; 276 } 277 ret = NCONF_load_bio(conf, btmp, eline); 278 BIO_free(btmp); 279 return ret; 280} 281#endif 282 283int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) 284{ 285 if (conf == NULL) { 286 CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); 287 return 0; 288 } 289 290 return conf->meth->load_bio(conf, bp, eline); 291} 292 293STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) 294{ 295 if (conf == NULL) { 296 CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); 297 return NULL; 298 } 299 300 if (section == NULL) { 301 CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); 302 return NULL; 303 } 304 305 return _CONF_get_section_values(conf, section); 306} 307 308char *NCONF_get_string(const CONF *conf, const char *group, const char *name) 309{ 310 char *s = _CONF_get_string(conf, group, name); 311 312 /* 313 * Since we may get a value from an environment variable even if conf is 314 * NULL, let's check the value first 315 */ 316 if (s) 317 return s; 318 319 if (conf == NULL) { 320 CONFerr(CONF_F_NCONF_GET_STRING, 321 CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); 322 return NULL; 323 } 324 CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); 325 ERR_add_error_data(4, "group=", group, " name=", name); 326 return NULL; 327} 328 329int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, 330 long *result) 331{ 332 char *str; 333 334 if (result == NULL) { 335 CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); 336 return 0; 337 } 338 339 str = NCONF_get_string(conf, group, name); 340 341 if (str == NULL) 342 return 0; 343 344 for (*result = 0; conf->meth->is_number(conf, *str);) { 345 *result = (*result) * 10 + conf->meth->to_int(conf, *str); 346 str++; 347 } 348 349 return 1; 350} 351 352#ifndef OPENSSL_NO_FP_API 353int NCONF_dump_fp(const CONF *conf, FILE *out) 354{ 355 BIO *btmp; 356 int ret; 357 if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 358 CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); 359 return 0; 360 } 361 ret = NCONF_dump_bio(conf, btmp); 362 BIO_free(btmp); 363 return ret; 364} 365#endif 366 367int NCONF_dump_bio(const CONF *conf, BIO *out) 368{ 369 if (conf == NULL) { 370 CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); 371 return 0; 372 } 373 374 return conf->meth->dump(conf, out); 375} 376 377/* This function should be avoided */ 378#if 0 379long NCONF_get_number(CONF *conf, char *group, char *name) 380{ 381 int status; 382 long ret = 0; 383 384 status = NCONF_get_number_e(conf, group, name, &ret); 385 if (status == 0) { 386 /* This function does not believe in errors... */ 387 ERR_get_error(); 388 } 389 return ret; 390} 391#endif 392