Branch data Line data Source code
1 : : /* conf_api.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : /* Part of the code in here was originally in conf.c, which is now removed */
60 : :
61 : : #ifndef CONF_DEBUG
62 : : # undef NDEBUG /* avoid conflicting definitions */
63 : : # define NDEBUG
64 : : #endif
65 : :
66 : : #include <assert.h>
67 : : #include <stdlib.h>
68 : : #include <string.h>
69 : : #include <openssl/conf.h>
70 : : #include <openssl/conf_api.h>
71 : : #include "e_os.h"
72 : :
73 : : static void value_free_hash_doall_arg(CONF_VALUE *a,
74 : : LHASH_OF(CONF_VALUE) *conf);
75 : : static void value_free_stack_doall(CONF_VALUE *a);
76 : 164380 : static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
77 : : LHASH_OF(CONF_VALUE))
78 : 24242 : static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
79 : :
80 : : /* Up until OpenSSL 0.9.5a, this was get_section */
81 : 11443 : CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
82 : : {
83 : : CONF_VALUE *v,vv;
84 : :
85 [ + - ]: 11443 : if ((conf == NULL) || (section == NULL)) return(NULL);
86 : 11443 : vv.name=NULL;
87 : 11443 : vv.section=(char *)section;
88 : 11443 : v=lh_CONF_VALUE_retrieve(conf->data,&vv);
89 : 11443 : return(v);
90 : : }
91 : :
92 : : /* Up until OpenSSL 0.9.5a, this was CONF_get_section */
93 : 89 : STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
94 : : const char *section)
95 : : {
96 : : CONF_VALUE *v;
97 : :
98 : 89 : v=_CONF_get_section(conf,section);
99 [ + - ]: 89 : if (v != NULL)
100 : 89 : return((STACK_OF(CONF_VALUE) *)v->value);
101 : : else
102 : : return(NULL);
103 : : }
104 : :
105 : 70073 : int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
106 : : {
107 : 70073 : CONF_VALUE *v = NULL;
108 : : STACK_OF(CONF_VALUE) *ts;
109 : :
110 : 70073 : ts = (STACK_OF(CONF_VALUE) *)section->value;
111 : :
112 : 70073 : value->section=section->section;
113 [ + - ]: 70073 : if (!sk_CONF_VALUE_push(ts,value))
114 : : {
115 : : return 0;
116 : : }
117 : :
118 : 70073 : v = lh_CONF_VALUE_insert(conf->data, value);
119 [ - + ]: 70073 : if (v != NULL)
120 : : {
121 : 0 : (void)sk_CONF_VALUE_delete_ptr(ts,v);
122 : 0 : OPENSSL_free(v->name);
123 : 0 : OPENSSL_free(v->value);
124 : 0 : OPENSSL_free(v);
125 : : }
126 : : return 1;
127 : : }
128 : :
129 : 12701 : char *_CONF_get_string(const CONF *conf, const char *section, const char *name)
130 : : {
131 : : CONF_VALUE *v,vv;
132 : : char *p;
133 : :
134 [ + - ]: 12701 : if (name == NULL) return(NULL);
135 [ + - ]: 12701 : if (conf != NULL)
136 : : {
137 [ + + ]: 12701 : if (section != NULL)
138 : : {
139 : 11947 : vv.name=(char *)name;
140 : 11947 : vv.section=(char *)section;
141 : 11947 : v=lh_CONF_VALUE_retrieve(conf->data,&vv);
142 [ + + ]: 11947 : if (v != NULL) return(v->value);
143 [ + + ]: 1085 : if (strcmp(section,"ENV") == 0)
144 : : {
145 : 804 : p=getenv(name);
146 [ + + ]: 804 : if (p != NULL) return(p);
147 : : }
148 : : }
149 : 1036 : vv.section="default";
150 : 1036 : vv.name=(char *)name;
151 : 1036 : v=lh_CONF_VALUE_retrieve(conf->data,&vv);
152 [ + + ]: 1036 : if (v != NULL)
153 : 51 : return(v->value);
154 : : else
155 : : return(NULL);
156 : : }
157 : : else
158 : 0 : return(getenv(name));
159 : : }
160 : :
161 : : #if 0 /* There's no way to provide error checking with this function, so
162 : : force implementors of the higher levels to get a string and read
163 : : the number themselves. */
164 : : long _CONF_get_number(CONF *conf, char *section, char *name)
165 : : {
166 : : char *str;
167 : : long ret=0;
168 : :
169 : : str=_CONF_get_string(conf,section,name);
170 : : if (str == NULL) return(0);
171 : : for (;;)
172 : : {
173 : : if (conf->meth->is_number(conf, *str))
174 : : ret=ret*10+conf->meth->to_int(conf, *str);
175 : : else
176 : : return(ret);
177 : : str++;
178 : : }
179 : : }
180 : : #endif
181 : :
182 : 353386 : static unsigned long conf_value_hash(const CONF_VALUE *v)
183 : : {
184 : 176693 : return (lh_strhash(v->section)<<2)^lh_strhash(v->name);
185 : : }
186 : 353386 : static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
187 : :
188 : 81071 : static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
189 : : {
190 : : int i;
191 : :
192 [ + + ]: 81071 : if (a->section != b->section)
193 : : {
194 : 11002 : i=strcmp(a->section,b->section);
195 [ + - ]: 11002 : if (i) return(i);
196 : : }
197 : :
198 [ + + ][ + - ]: 81071 : if ((a->name != NULL) && (b->name != NULL))
199 : : {
200 : 80982 : i=strcmp(a->name,b->name);
201 : : return(i);
202 : : }
203 [ - + ]: 89 : else if (a->name == b->name)
204 : : return(0);
205 : : else
206 [ # # ]: 0 : return((a->name == NULL)?-1:1);
207 : : }
208 : 162142 : static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
209 : :
210 : 771 : int _CONF_new_data(CONF *conf)
211 : : {
212 [ + - ]: 771 : if (conf == NULL)
213 : : {
214 : : return 0;
215 : : }
216 [ + - ]: 771 : if (conf->data == NULL)
217 [ + - ]: 771 : if ((conf->data = lh_CONF_VALUE_new()) == NULL)
218 : : {
219 : : return 0;
220 : : }
221 : : return 1;
222 : : }
223 : :
224 : 775 : void _CONF_free_data(CONF *conf)
225 : : {
226 [ + - ][ + + ]: 775 : if (conf == NULL || conf->data == NULL) return;
227 : :
228 : 770 : lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make
229 : : * sure the 'OPENSSL_free()' works as
230 : : * expected */
231 : 770 : lh_CONF_VALUE_doall_arg(conf->data,
232 : : LHASH_DOALL_ARG_FN(value_free_hash),
233 : : LHASH_OF(CONF_VALUE), conf->data);
234 : :
235 : : /* We now have only 'section' entries in the hash table.
236 : : * Due to problems with */
237 : :
238 : 770 : lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
239 : 770 : lh_CONF_VALUE_free(conf->data);
240 : : }
241 : :
242 : 82190 : static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
243 : : {
244 [ + + ]: 82190 : if (a->name != NULL)
245 : 70069 : (void)lh_CONF_VALUE_delete(conf,a);
246 : 82190 : }
247 : :
248 : 12121 : static void value_free_stack_doall(CONF_VALUE *a)
249 : : {
250 : : CONF_VALUE *vv;
251 : : STACK_OF(CONF_VALUE) *sk;
252 : : int i;
253 : :
254 [ + - ]: 12121 : if (a->name != NULL) return;
255 : :
256 : 12121 : sk=(STACK_OF(CONF_VALUE) *)a->value;
257 [ + + ]: 82190 : for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--)
258 : : {
259 : 70069 : vv=sk_CONF_VALUE_value(sk,i);
260 : 70069 : OPENSSL_free(vv->value);
261 : 70069 : OPENSSL_free(vv->name);
262 : 70069 : OPENSSL_free(vv);
263 : : }
264 [ + - ]: 12121 : if (sk != NULL) sk_CONF_VALUE_free(sk);
265 : 12121 : OPENSSL_free(a->section);
266 : 12121 : OPENSSL_free(a);
267 : : }
268 : :
269 : : /* Up until OpenSSL 0.9.5a, this was new_section */
270 : 12125 : CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
271 : : {
272 : 12125 : STACK_OF(CONF_VALUE) *sk=NULL;
273 : 12125 : int ok=0,i;
274 : 12125 : CONF_VALUE *v=NULL,*vv;
275 : :
276 [ + - ]: 12125 : if ((sk=sk_CONF_VALUE_new_null()) == NULL)
277 : : goto err;
278 [ + - ]: 12125 : if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
279 : : goto err;
280 : 12125 : i=strlen(section)+1;
281 [ + - ]: 12125 : if ((v->section=OPENSSL_malloc(i)) == NULL)
282 : : goto err;
283 : :
284 : 12125 : memcpy(v->section,section,i);
285 : 12125 : v->name=NULL;
286 : 12125 : v->value=(char *)sk;
287 : :
288 : 12125 : vv=lh_CONF_VALUE_insert(conf->data,v);
289 [ - + ]: 12125 : OPENSSL_assert(vv == NULL);
290 : : ok=1;
291 : : err:
292 [ - + ]: 12125 : if (!ok)
293 : : {
294 [ # # ]: 0 : if (sk != NULL) sk_CONF_VALUE_free(sk);
295 [ # # ]: 0 : if (v != NULL) OPENSSL_free(v);
296 : : v=NULL;
297 : : }
298 : 12125 : return(v);
299 : : }
300 : :
301 : : IMPLEMENT_STACK_OF(CONF_VALUE)
|