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