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