Hide OPENSSL_INIT_SETTINGS.
[openssl.git] / crypto / conf / conf_lib.c
1 /*
2  * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
3  * 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 <string.h>
61 #include <internal/conf.h>
62 #include <openssl/crypto.h>
63 #include <openssl/err.h>
64 #include <openssl/conf.h>
65 #include <openssl/conf_api.h>
66 #include <openssl/lhash.h>
67
68 static CONF_METHOD *default_CONF_method = NULL;
69
70 /* Init a 'CONF' structure from an old LHASH */
71
72 void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
73 {
74     if (default_CONF_method == NULL)
75         default_CONF_method = NCONF_default();
76
77     default_CONF_method->init(conf);
78     conf->data = hash;
79 }
80
81 /*
82  * The following section contains the "CONF classic" functions, rewritten in
83  * terms of the new CONF interface.
84  */
85
86 int CONF_set_default_method(CONF_METHOD *meth)
87 {
88     default_CONF_method = meth;
89     return 1;
90 }
91
92 LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
93                                 long *eline)
94 {
95     LHASH_OF(CONF_VALUE) *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_STDIO
115 LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
116                                    long *eline)
117 {
118     BIO *btmp;
119     LHASH_OF(CONF_VALUE) *ltmp;
120     if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
121         CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
122         return NULL;
123     }
124     ltmp = CONF_load_bio(conf, btmp, eline);
125     BIO_free(btmp);
126     return ltmp;
127 }
128 #endif
129
130 LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
131                                     long *eline)
132 {
133     CONF ctmp;
134     int ret;
135
136     CONF_set_nconf(&ctmp, conf);
137
138     ret = NCONF_load_bio(&ctmp, bp, eline);
139     if (ret)
140         return ctmp.data;
141     return NULL;
142 }
143
144 STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
145                                        const char *section)
146 {
147     if (conf == NULL) {
148         return NULL;
149     } else {
150         CONF ctmp;
151         CONF_set_nconf(&ctmp, conf);
152         return NCONF_get_section(&ctmp, section);
153     }
154 }
155
156 char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
157                       const char *name)
158 {
159     if (conf == NULL) {
160         return NCONF_get_string(NULL, group, name);
161     } else {
162         CONF ctmp;
163         CONF_set_nconf(&ctmp, conf);
164         return NCONF_get_string(&ctmp, group, name);
165     }
166 }
167
168 long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
169                      const char *name)
170 {
171     int status;
172     long result = 0;
173
174     if (conf == NULL) {
175         status = NCONF_get_number_e(NULL, group, name, &result);
176     } else {
177         CONF ctmp;
178         CONF_set_nconf(&ctmp, conf);
179         status = NCONF_get_number_e(&ctmp, group, name, &result);
180     }
181
182     if (status == 0) {
183         /* This function does not believe in errors... */
184         ERR_clear_error();
185     }
186     return result;
187 }
188
189 void CONF_free(LHASH_OF(CONF_VALUE) *conf)
190 {
191     CONF ctmp;
192     CONF_set_nconf(&ctmp, conf);
193     NCONF_free_data(&ctmp);
194 }
195
196 #ifndef OPENSSL_NO_STDIO
197 int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
198 {
199     BIO *btmp;
200     int ret;
201
202     if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
203         CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
204         return 0;
205     }
206     ret = CONF_dump_bio(conf, btmp);
207     BIO_free(btmp);
208     return ret;
209 }
210 #endif
211
212 int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
213 {
214     CONF ctmp;
215     CONF_set_nconf(&ctmp, conf);
216     return NCONF_dump_bio(&ctmp, out);
217 }
218
219 /*
220  * The following section contains the "New CONF" functions.  They are
221  * completely centralised around a new CONF structure that may contain
222  * basically anything, but at least a method pointer and a table of data.
223  * These functions are also written in terms of the bridge functions used by
224  * the "CONF classic" functions, for consistency.
225  */
226
227 CONF *NCONF_new(CONF_METHOD *meth)
228 {
229     CONF *ret;
230
231     if (meth == NULL)
232         meth = NCONF_default();
233
234     ret = meth->create(meth);
235     if (ret == NULL) {
236         CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
237         return (NULL);
238     }
239
240     return ret;
241 }
242
243 void NCONF_free(CONF *conf)
244 {
245     if (conf == NULL)
246         return;
247     conf->meth->destroy(conf);
248 }
249
250 void NCONF_free_data(CONF *conf)
251 {
252     if (conf == NULL)
253         return;
254     conf->meth->destroy_data(conf);
255 }
256
257 int NCONF_load(CONF *conf, const char *file, long *eline)
258 {
259     if (conf == NULL) {
260         CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
261         return 0;
262     }
263
264     return conf->meth->load(conf, file, eline);
265 }
266
267 #ifndef OPENSSL_NO_STDIO
268 int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
269 {
270     BIO *btmp;
271     int ret;
272     if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
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 #endif
281
282 int 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) *NCONF_get_section(const CONF *conf, const char *section)
293 {
294     if (conf == NULL) {
295         CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
296         return NULL;
297     }
298
299     if (section == NULL) {
300         CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
301         return NULL;
302     }
303
304     return _CONF_get_section_values(conf, section);
305 }
306
307 char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
308 {
309     char *s = _CONF_get_string(conf, group, name);
310
311     /*
312      * Since we may get a value from an environment variable even if conf is
313      * NULL, let's check the value first
314      */
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_add_error_data(4, "group=", group, " name=", name);
325     return NULL;
326 }
327
328 int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
329                        long *result)
330 {
331     char *str;
332
333     if (result == NULL) {
334         CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
335         return 0;
336     }
337
338     str = NCONF_get_string(conf, group, name);
339
340     if (str == NULL)
341         return 0;
342
343     for (*result = 0; conf->meth->is_number(conf, *str);) {
344         *result = (*result) * 10 + conf->meth->to_int(conf, *str);
345         str++;
346     }
347
348     return 1;
349 }
350
351 #ifndef OPENSSL_NO_STDIO
352 int NCONF_dump_fp(const CONF *conf, FILE *out)
353 {
354     BIO *btmp;
355     int ret;
356     if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
357         CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
358         return 0;
359     }
360     ret = NCONF_dump_bio(conf, btmp);
361     BIO_free(btmp);
362     return ret;
363 }
364 #endif
365
366 int NCONF_dump_bio(const CONF *conf, BIO *out)
367 {
368     if (conf == NULL) {
369         CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
370         return 0;
371     }
372
373     return conf->meth->dump(conf, out);
374 }
375
376 /*
377  * These routines call the C malloc/free, to avoid intermixing with
378  * OpenSSL function pointers before the library is initialized.
379  */
380 OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void)
381 {
382     OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret));
383
384     memset(ret, 0, sizeof(*ret));
385     return ret;
386 }
387
388
389 void OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings,
390                                       const char *config_file)
391 {
392     free(settings->config_name);
393     settings->config_name = config_file == NULL ? NULL : strdup(config_file);
394 }
395
396 void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings)
397 {
398     free(settings->config_name);
399     free(settings);
400 }