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 0 : static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
77 : LHASH_OF(CONF_VALUE))
78 0 : static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
79 :
80 : /* Up until OpenSSL 0.9.5a, this was get_section */
81 0 : CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
82 : {
83 : CONF_VALUE *v, vv;
84 :
85 0 : if ((conf == NULL) || (section == NULL))
86 : return (NULL);
87 0 : vv.name = NULL;
88 0 : vv.section = (char *)section;
89 0 : v = lh_CONF_VALUE_retrieve(conf->data, &vv);
90 0 : return (v);
91 : }
92 :
93 : /* Up until OpenSSL 0.9.5a, this was CONF_get_section */
94 0 : STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
95 : const char *section)
96 : {
97 : CONF_VALUE *v;
98 :
99 0 : v = _CONF_get_section(conf, section);
100 0 : if (v != NULL)
101 0 : return ((STACK_OF(CONF_VALUE) *)v->value);
102 : else
103 : return (NULL);
104 : }
105 :
106 0 : int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
107 : {
108 : CONF_VALUE *v = NULL;
109 : STACK_OF(CONF_VALUE) *ts;
110 :
111 0 : ts = (STACK_OF(CONF_VALUE) *)section->value;
112 :
113 0 : value->section = section->section;
114 0 : if (!sk_CONF_VALUE_push(ts, value)) {
115 : return 0;
116 : }
117 :
118 0 : v = lh_CONF_VALUE_insert(conf->data, value);
119 0 : if (v != NULL) {
120 0 : (void)sk_CONF_VALUE_delete_ptr(ts, v);
121 0 : OPENSSL_free(v->name);
122 0 : OPENSSL_free(v->value);
123 0 : OPENSSL_free(v);
124 : }
125 : return 1;
126 : }
127 :
128 0 : char *_CONF_get_string(const CONF *conf, const char *section,
129 : const char *name)
130 : {
131 : CONF_VALUE *v, vv;
132 : char *p;
133 :
134 0 : if (name == NULL)
135 : return (NULL);
136 0 : if (conf != NULL) {
137 0 : if (section != NULL) {
138 0 : vv.name = (char *)name;
139 0 : vv.section = (char *)section;
140 0 : v = lh_CONF_VALUE_retrieve(conf->data, &vv);
141 0 : if (v != NULL)
142 0 : return (v->value);
143 0 : if (strcmp(section, "ENV") == 0) {
144 0 : p = getenv(name);
145 0 : if (p != NULL)
146 : return (p);
147 : }
148 : }
149 0 : vv.section = "default";
150 0 : vv.name = (char *)name;
151 0 : v = lh_CONF_VALUE_retrieve(conf->data, &vv);
152 0 : if (v != NULL)
153 0 : return (v->value);
154 : else
155 : return (NULL);
156 : } else
157 0 : return (getenv(name));
158 : }
159 :
160 : #if 0 /* There's no way to provide error checking
161 : * with this function, so force implementors
162 : * of the higher levels to get a string and
163 : * read 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)
171 : return (0);
172 : for (;;) {
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 0 : static unsigned long conf_value_hash(const CONF_VALUE *v)
183 : {
184 0 : return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name);
185 : }
186 :
187 0 : static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
188 :
189 0 : static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
190 : {
191 : int i;
192 :
193 0 : if (a->section != b->section) {
194 0 : i = strcmp(a->section, b->section);
195 0 : if (i)
196 : return (i);
197 : }
198 :
199 0 : if ((a->name != NULL) && (b->name != NULL)) {
200 0 : i = strcmp(a->name, b->name);
201 : return (i);
202 0 : } else if (a->name == b->name)
203 : return (0);
204 : else
205 0 : return ((a->name == NULL) ? -1 : 1);
206 : }
207 :
208 0 : static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
209 :
210 0 : int _CONF_new_data(CONF *conf)
211 : {
212 0 : if (conf == NULL) {
213 : return 0;
214 : }
215 0 : if (conf->data == NULL)
216 0 : if ((conf->data = lh_CONF_VALUE_new()) == NULL) {
217 : return 0;
218 : }
219 : return 1;
220 : }
221 :
222 0 : void _CONF_free_data(CONF *conf)
223 : {
224 0 : if (conf == NULL || conf->data == NULL)
225 0 : return;
226 :
227 0 : lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the
228 : * 'OPENSSL_free()' works as *
229 : * expected */
230 0 : lh_CONF_VALUE_doall_arg(conf->data,
231 : LHASH_DOALL_ARG_FN(value_free_hash),
232 : LHASH_OF(CONF_VALUE), conf->data);
233 :
234 : /*
235 : * We now have only 'section' entries in the hash table. Due to problems
236 : * with
237 : */
238 :
239 0 : lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
240 0 : lh_CONF_VALUE_free(conf->data);
241 : }
242 :
243 : static void value_free_hash_doall_arg(CONF_VALUE *a,
244 : LHASH_OF(CONF_VALUE) *conf)
245 : {
246 0 : if (a->name != NULL)
247 0 : (void)lh_CONF_VALUE_delete(conf, a);
248 : }
249 :
250 0 : static void value_free_stack_doall(CONF_VALUE *a)
251 : {
252 : CONF_VALUE *vv;
253 : STACK_OF(CONF_VALUE) *sk;
254 : int i;
255 :
256 0 : if (a->name != NULL)
257 0 : return;
258 :
259 0 : sk = (STACK_OF(CONF_VALUE) *)a->value;
260 0 : for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
261 0 : vv = sk_CONF_VALUE_value(sk, i);
262 0 : OPENSSL_free(vv->value);
263 0 : OPENSSL_free(vv->name);
264 0 : OPENSSL_free(vv);
265 : }
266 0 : if (sk != NULL)
267 0 : sk_CONF_VALUE_free(sk);
268 0 : OPENSSL_free(a->section);
269 0 : OPENSSL_free(a);
270 : }
271 :
272 : /* Up until OpenSSL 0.9.5a, this was new_section */
273 0 : CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
274 : {
275 : STACK_OF(CONF_VALUE) *sk = NULL;
276 : int ok = 0, i;
277 : CONF_VALUE *v = NULL, *vv;
278 :
279 0 : if ((sk = sk_CONF_VALUE_new_null()) == NULL)
280 : goto err;
281 0 : if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
282 : goto err;
283 0 : i = strlen(section) + 1;
284 0 : if ((v->section = OPENSSL_malloc(i)) == NULL)
285 : goto err;
286 :
287 0 : memcpy(v->section, section, i);
288 0 : v->name = NULL;
289 0 : v->value = (char *)sk;
290 :
291 0 : vv = lh_CONF_VALUE_insert(conf->data, v);
292 0 : OPENSSL_assert(vv == NULL);
293 : ok = 1;
294 : err:
295 0 : if (!ok) {
296 0 : if (sk != NULL)
297 0 : sk_CONF_VALUE_free(sk);
298 0 : if (v != NULL)
299 0 : OPENSSL_free(v);
300 : v = NULL;
301 : }
302 0 : return (v);
303 : }
304 :
305 : IMPLEMENT_STACK_OF(CONF_VALUE)
|