Line data Source code
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 :
67 : const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT;
68 :
69 : static CONF_METHOD *default_CONF_method = NULL;
70 :
71 : /* Init a 'CONF' structure from an old LHASH */
72 :
73 0 : void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
74 : {
75 0 : if (default_CONF_method == NULL)
76 0 : default_CONF_method = NCONF_default();
77 :
78 0 : default_CONF_method->init(conf);
79 0 : conf->data = hash;
80 0 : }
81 :
82 : /*
83 : * The following section contains the "CONF classic" functions, rewritten in
84 : * terms of the new CONF interface.
85 : */
86 :
87 0 : int CONF_set_default_method(CONF_METHOD *meth)
88 : {
89 0 : default_CONF_method = meth;
90 0 : return 1;
91 : }
92 :
93 0 : LHASH_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 0 : in = BIO_new_file(file, "rb");
103 : #endif
104 0 : if (in == NULL) {
105 0 : CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
106 0 : return NULL;
107 : }
108 :
109 0 : ltmp = CONF_load_bio(conf, in, eline);
110 0 : BIO_free(in);
111 :
112 0 : return ltmp;
113 : }
114 :
115 : #ifndef OPENSSL_NO_FP_API
116 0 : LHASH_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 0 : if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
122 0 : CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
123 0 : return NULL;
124 : }
125 0 : ltmp = CONF_load_bio(conf, btmp, eline);
126 0 : BIO_free(btmp);
127 0 : return ltmp;
128 : }
129 : #endif
130 :
131 0 : LHASH_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 0 : CONF_set_nconf(&ctmp, conf);
138 :
139 0 : ret = NCONF_load_bio(&ctmp, bp, eline);
140 0 : if (ret)
141 0 : return ctmp.data;
142 : return NULL;
143 : }
144 :
145 0 : STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
146 : const char *section)
147 : {
148 0 : if (conf == NULL) {
149 : return NULL;
150 : } else {
151 : CONF ctmp;
152 0 : CONF_set_nconf(&ctmp, conf);
153 0 : return NCONF_get_section(&ctmp, section);
154 : }
155 : }
156 :
157 0 : char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
158 : const char *name)
159 : {
160 0 : if (conf == NULL) {
161 0 : return NCONF_get_string(NULL, group, name);
162 : } else {
163 : CONF ctmp;
164 0 : CONF_set_nconf(&ctmp, conf);
165 0 : return NCONF_get_string(&ctmp, group, name);
166 : }
167 : }
168 :
169 0 : long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
170 : const char *name)
171 : {
172 : int status;
173 0 : long result = 0;
174 :
175 0 : if (conf == NULL) {
176 0 : status = NCONF_get_number_e(NULL, group, name, &result);
177 : } else {
178 : CONF ctmp;
179 0 : CONF_set_nconf(&ctmp, conf);
180 0 : status = NCONF_get_number_e(&ctmp, group, name, &result);
181 : }
182 :
183 0 : if (status == 0) {
184 : /* This function does not believe in errors... */
185 0 : ERR_clear_error();
186 : }
187 0 : return result;
188 : }
189 :
190 0 : void CONF_free(LHASH_OF(CONF_VALUE) *conf)
191 : {
192 : CONF ctmp;
193 0 : CONF_set_nconf(&ctmp, conf);
194 : NCONF_free_data(&ctmp);
195 0 : }
196 :
197 : #ifndef OPENSSL_NO_FP_API
198 0 : int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
199 : {
200 : BIO *btmp;
201 : int ret;
202 :
203 0 : if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
204 0 : CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
205 0 : return 0;
206 : }
207 : ret = CONF_dump_bio(conf, btmp);
208 0 : BIO_free(btmp);
209 0 : return ret;
210 : }
211 : #endif
212 :
213 0 : int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
214 : {
215 : CONF ctmp;
216 0 : CONF_set_nconf(&ctmp, conf);
217 0 : 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 :
228 0 : CONF *NCONF_new(CONF_METHOD *meth)
229 : {
230 : CONF *ret;
231 :
232 0 : if (meth == NULL)
233 0 : meth = NCONF_default();
234 :
235 0 : ret = meth->create(meth);
236 0 : if (ret == NULL) {
237 0 : CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
238 0 : return (NULL);
239 : }
240 :
241 : return ret;
242 : }
243 :
244 0 : void NCONF_free(CONF *conf)
245 : {
246 0 : if (conf == NULL)
247 0 : return;
248 0 : conf->meth->destroy(conf);
249 : }
250 :
251 0 : void NCONF_free_data(CONF *conf)
252 : {
253 0 : if (conf == NULL)
254 0 : return;
255 0 : conf->meth->destroy_data(conf);
256 : }
257 :
258 0 : int NCONF_load(CONF *conf, const char *file, long *eline)
259 : {
260 0 : if (conf == NULL) {
261 0 : CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
262 0 : return 0;
263 : }
264 :
265 0 : return conf->meth->load(conf, file, eline);
266 : }
267 :
268 : #ifndef OPENSSL_NO_FP_API
269 0 : int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
270 : {
271 : BIO *btmp;
272 : int ret;
273 0 : if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
274 0 : CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
275 0 : return 0;
276 : }
277 0 : ret = NCONF_load_bio(conf, btmp, eline);
278 0 : BIO_free(btmp);
279 0 : return ret;
280 : }
281 : #endif
282 :
283 0 : int NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
284 : {
285 0 : if (conf == NULL) {
286 0 : CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
287 0 : return 0;
288 : }
289 :
290 0 : return conf->meth->load_bio(conf, bp, eline);
291 : }
292 :
293 0 : STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section)
294 : {
295 0 : if (conf == NULL) {
296 0 : CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
297 0 : return NULL;
298 : }
299 :
300 0 : if (section == NULL) {
301 0 : CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
302 0 : return NULL;
303 : }
304 :
305 0 : return _CONF_get_section_values(conf, section);
306 : }
307 :
308 0 : char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
309 : {
310 0 : 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 0 : if (s)
317 : return s;
318 :
319 0 : if (conf == NULL) {
320 0 : CONFerr(CONF_F_NCONF_GET_STRING,
321 : CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
322 0 : return NULL;
323 : }
324 0 : CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
325 0 : ERR_add_error_data(4, "group=", group, " name=", name);
326 0 : return NULL;
327 : }
328 :
329 0 : int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
330 : long *result)
331 : {
332 : char *str;
333 :
334 0 : if (result == NULL) {
335 0 : CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
336 0 : return 0;
337 : }
338 :
339 0 : str = NCONF_get_string(conf, group, name);
340 :
341 0 : if (str == NULL)
342 : return 0;
343 :
344 0 : for (*result = 0; conf->meth->is_number(conf, *str);) {
345 0 : *result = (*result) * 10 + conf->meth->to_int(conf, *str);
346 0 : str++;
347 : }
348 :
349 : return 1;
350 : }
351 :
352 : #ifndef OPENSSL_NO_FP_API
353 0 : int NCONF_dump_fp(const CONF *conf, FILE *out)
354 : {
355 : BIO *btmp;
356 : int ret;
357 0 : if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
358 0 : CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
359 0 : return 0;
360 : }
361 0 : ret = NCONF_dump_bio(conf, btmp);
362 0 : BIO_free(btmp);
363 0 : return ret;
364 : }
365 : #endif
366 :
367 0 : int NCONF_dump_bio(const CONF *conf, BIO *out)
368 : {
369 0 : if (conf == NULL) {
370 0 : CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
371 0 : return 0;
372 : }
373 :
374 0 : return conf->meth->dump(conf, out);
375 : }
376 :
377 : /* This function should be avoided */
378 : #if 0
379 : long 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
|