conf_lib.c revision 296465
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 *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 *CONF_load(LHASH *conf, const char *file, long *eline) 94{ 95 LHASH *ltmp; 96 BIO *in = NULL; 97 98#ifdef OPENSSL_SYS_VMS 99 in = BIO_new_file(file, "r"); 100#else 101 in = BIO_new_file(file, "rb"); 102#endif 103 if (in == NULL) { 104 CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); 105 return NULL; 106 } 107 108 ltmp = CONF_load_bio(conf, in, eline); 109 BIO_free(in); 110 111 return ltmp; 112} 113 114#ifndef OPENSSL_NO_FP_API 115LHASH *CONF_load_fp(LHASH *conf, FILE *fp, long *eline) 116{ 117 BIO *btmp; 118 LHASH *ltmp; 119 if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 120 CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); 121 return NULL; 122 } 123 ltmp = CONF_load_bio(conf, btmp, eline); 124 BIO_free(btmp); 125 return ltmp; 126} 127#endif 128 129LHASH *CONF_load_bio(LHASH *conf, BIO *bp, long *eline) 130{ 131 CONF ctmp; 132 int ret; 133 134 CONF_set_nconf(&ctmp, conf); 135 136 ret = NCONF_load_bio(&ctmp, bp, eline); 137 if (ret) 138 return ctmp.data; 139 return NULL; 140} 141 142STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf, const char *section) 143{ 144 if (conf == NULL) { 145 return NULL; 146 } else { 147 CONF ctmp; 148 CONF_set_nconf(&ctmp, conf); 149 return NCONF_get_section(&ctmp, section); 150 } 151} 152 153char *CONF_get_string(LHASH *conf, const char *group, const char *name) 154{ 155 if (conf == NULL) { 156 return NCONF_get_string(NULL, group, name); 157 } else { 158 CONF ctmp; 159 CONF_set_nconf(&ctmp, conf); 160 return NCONF_get_string(&ctmp, group, name); 161 } 162} 163 164long CONF_get_number(LHASH *conf, const char *group, const char *name) 165{ 166 int status; 167 long result = 0; 168 169 if (conf == NULL) { 170 status = NCONF_get_number_e(NULL, group, name, &result); 171 } else { 172 CONF ctmp; 173 CONF_set_nconf(&ctmp, conf); 174 status = NCONF_get_number_e(&ctmp, group, name, &result); 175 } 176 177 if (status == 0) { 178 /* This function does not believe in errors... */ 179 ERR_clear_error(); 180 } 181 return result; 182} 183 184void CONF_free(LHASH *conf) 185{ 186 CONF ctmp; 187 CONF_set_nconf(&ctmp, conf); 188 NCONF_free_data(&ctmp); 189} 190 191#ifndef OPENSSL_NO_FP_API 192int CONF_dump_fp(LHASH *conf, FILE *out) 193{ 194 BIO *btmp; 195 int ret; 196 197 if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 198 CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); 199 return 0; 200 } 201 ret = CONF_dump_bio(conf, btmp); 202 BIO_free(btmp); 203 return ret; 204} 205#endif 206 207int CONF_dump_bio(LHASH *conf, BIO *out) 208{ 209 CONF ctmp; 210 CONF_set_nconf(&ctmp, conf); 211 return NCONF_dump_bio(&ctmp, out); 212} 213 214/* 215 * The following section contains the "New CONF" functions. They are 216 * completely centralised around a new CONF structure that may contain 217 * basically anything, but at least a method pointer and a table of data. 218 * These functions are also written in terms of the bridge functions used by 219 * the "CONF classic" functions, for consistency. 220 */ 221 222CONF *NCONF_new(CONF_METHOD *meth) 223{ 224 CONF *ret; 225 226 if (meth == NULL) 227 meth = NCONF_default(); 228 229 ret = meth->create(meth); 230 if (ret == NULL) { 231 CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); 232 return (NULL); 233 } 234 235 return ret; 236} 237 238void NCONF_free(CONF *conf) 239{ 240 if (conf == NULL) 241 return; 242 conf->meth->destroy(conf); 243} 244 245void NCONF_free_data(CONF *conf) 246{ 247 if (conf == NULL) 248 return; 249 conf->meth->destroy_data(conf); 250} 251 252int NCONF_load(CONF *conf, const char *file, long *eline) 253{ 254 if (conf == NULL) { 255 CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); 256 return 0; 257 } 258 259 return conf->meth->load(conf, file, eline); 260} 261 262#ifndef OPENSSL_NO_FP_API 263int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) 264{ 265 BIO *btmp; 266 int ret; 267 if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 268 CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); 269 return 0; 270 } 271 ret = NCONF_load_bio(conf, btmp, eline); 272 BIO_free(btmp); 273 return ret; 274} 275#endif 276 277int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) 278{ 279 if (conf == NULL) { 280 CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); 281 return 0; 282 } 283 284 return conf->meth->load_bio(conf, bp, eline); 285} 286 287STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) 288{ 289 if (conf == NULL) { 290 CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); 291 return NULL; 292 } 293 294 if (section == NULL) { 295 CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); 296 return NULL; 297 } 298 299 return _CONF_get_section_values(conf, section); 300} 301 302char *NCONF_get_string(const CONF *conf, const char *group, const char *name) 303{ 304 char *s = _CONF_get_string(conf, group, name); 305 306 /* 307 * Since we may get a value from an environment variable even if conf is 308 * NULL, let's check the value first 309 */ 310 if (s) 311 return s; 312 313 if (conf == NULL) { 314 CONFerr(CONF_F_NCONF_GET_STRING, 315 CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); 316 return NULL; 317 } 318 CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); 319 ERR_add_error_data(4, "group=", group, " name=", name); 320 return NULL; 321} 322 323int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, 324 long *result) 325{ 326 char *str; 327 328 if (result == NULL) { 329 CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); 330 return 0; 331 } 332 333 str = NCONF_get_string(conf, group, name); 334 335 if (str == NULL) 336 return 0; 337 338 for (*result = 0; conf->meth->is_number(conf, *str);) { 339 *result = (*result) * 10 + conf->meth->to_int(conf, *str); 340 str++; 341 } 342 343 return 1; 344} 345 346#ifndef OPENSSL_NO_FP_API 347int NCONF_dump_fp(const CONF *conf, FILE *out) 348{ 349 BIO *btmp; 350 int ret; 351 if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { 352 CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); 353 return 0; 354 } 355 ret = NCONF_dump_bio(conf, btmp); 356 BIO_free(btmp); 357 return ret; 358} 359#endif 360 361int NCONF_dump_bio(const CONF *conf, BIO *out) 362{ 363 if (conf == NULL) { 364 CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); 365 return 0; 366 } 367 368 return conf->meth->dump(conf, out); 369} 370 371/* This function should be avoided */ 372#if 0 373long NCONF_get_number(CONF *conf, char *group, char *name) 374{ 375 int status; 376 long ret = 0; 377 378 status = NCONF_get_number_e(conf, group, name, &ret); 379 if (status == 0) { 380 /* This function does not believe in errors... */ 381 ERR_get_error(); 382 } 383 return ret; 384} 385#endif 386