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