6026dca928214b06d9348ce841bd459cc9b3a275
[openssl.git] / crypto / conf / conf_api.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /* Part of the code in here was originally in conf.c, which is now removed */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <openssl/conf.h>
15 #include <openssl/conf_api.h>
16 #include "e_os.h"
17
18 static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf);
19 static void value_free_stack_doall(CONF_VALUE *a);
20
21 /* Up until OpenSSL 0.9.5a, this was get_section */
22 CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
23 {
24     CONF_VALUE *v, vv;
25
26     if ((conf == NULL) || (section == NULL))
27         return (NULL);
28     vv.name = NULL;
29     vv.section = (char *)section;
30     v = lh_CONF_VALUE_retrieve(conf->data, &vv);
31     return (v);
32 }
33
34 /* Up until OpenSSL 0.9.5a, this was CONF_get_section */
35 STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
36                                                const char *section)
37 {
38     CONF_VALUE *v;
39
40     v = _CONF_get_section(conf, section);
41     if (v != NULL)
42         return ((STACK_OF(CONF_VALUE) *)v->value);
43     else
44         return (NULL);
45 }
46
47 int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
48 {
49     CONF_VALUE *v = NULL;
50     STACK_OF(CONF_VALUE) *ts;
51
52     ts = (STACK_OF(CONF_VALUE) *)section->value;
53
54     value->section = section->section;
55     if (!sk_CONF_VALUE_push(ts, value)) {
56         return 0;
57     }
58
59     v = lh_CONF_VALUE_insert(conf->data, value);
60     if (v != NULL) {
61         (void)sk_CONF_VALUE_delete_ptr(ts, v);
62         OPENSSL_free(v->name);
63         OPENSSL_free(v->value);
64         OPENSSL_free(v);
65     }
66     return 1;
67 }
68
69 char *_CONF_get_string(const CONF *conf, const char *section,
70                        const char *name)
71 {
72     CONF_VALUE *v, vv;
73     char *p;
74
75     if (name == NULL)
76         return (NULL);
77     if (conf != NULL) {
78         if (section != NULL) {
79             vv.name = (char *)name;
80             vv.section = (char *)section;
81             v = lh_CONF_VALUE_retrieve(conf->data, &vv);
82             if (v != NULL)
83                 return (v->value);
84             if (strcmp(section, "ENV") == 0) {
85                 p = getenv(name);
86                 if (p != NULL)
87                     return (p);
88             }
89         }
90         vv.section = "default";
91         vv.name = (char *)name;
92         v = lh_CONF_VALUE_retrieve(conf->data, &vv);
93         if (v != NULL)
94             return (v->value);
95         else
96             return (NULL);
97     } else
98         return (getenv(name));
99 }
100
101 static unsigned long conf_value_hash(const CONF_VALUE *v)
102 {
103     return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name);
104 }
105
106 static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
107 {
108     int i;
109
110     if (a->section != b->section) {
111         i = strcmp(a->section, b->section);
112         if (i)
113             return (i);
114     }
115
116     if ((a->name != NULL) && (b->name != NULL)) {
117         i = strcmp(a->name, b->name);
118         return (i);
119     } else if (a->name == b->name)
120         return (0);
121     else
122         return ((a->name == NULL) ? -1 : 1);
123 }
124
125 int _CONF_new_data(CONF *conf)
126 {
127     if (conf == NULL) {
128         return 0;
129     }
130     if (conf->data == NULL) {
131         conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp);
132         if (conf->data == NULL)
133             return 0;
134     }
135     return 1;
136 }
137
138 typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE;
139
140 IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE);
141
142 void _CONF_free_data(CONF *conf)
143 {
144     if (conf == NULL || conf->data == NULL)
145         return;
146
147     /* evil thing to make sure the 'OPENSSL_free()' works as expected */
148     lh_CONF_VALUE_set_down_load(conf->data, 0);
149     lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data);
150
151     /*
152      * We now have only 'section' entries in the hash table. Due to problems
153      * with
154      */
155
156     lh_CONF_VALUE_doall(conf->data, value_free_stack_doall);
157     lh_CONF_VALUE_free(conf->data);
158 }
159
160 static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
161 {
162     if (a->name != NULL)
163         (void)lh_CONF_VALUE_delete(conf, a);
164 }
165
166 static void value_free_stack_doall(CONF_VALUE *a)
167 {
168     CONF_VALUE *vv;
169     STACK_OF(CONF_VALUE) *sk;
170     int i;
171
172     if (a->name != NULL)
173         return;
174
175     sk = (STACK_OF(CONF_VALUE) *)a->value;
176     for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
177         vv = sk_CONF_VALUE_value(sk, i);
178         OPENSSL_free(vv->value);
179         OPENSSL_free(vv->name);
180         OPENSSL_free(vv);
181     }
182     sk_CONF_VALUE_free(sk);
183     OPENSSL_free(a->section);
184     OPENSSL_free(a);
185 }
186
187 /* Up until OpenSSL 0.9.5a, this was new_section */
188 CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
189 {
190     STACK_OF(CONF_VALUE) *sk = NULL;
191     int i;
192     CONF_VALUE *v = NULL, *vv;
193
194     if ((sk = sk_CONF_VALUE_new_null()) == NULL)
195         goto err;
196     if ((v = OPENSSL_malloc(sizeof(*v))) == NULL)
197         goto err;
198     i = strlen(section) + 1;
199     if ((v->section = OPENSSL_malloc(i)) == NULL)
200         goto err;
201
202     memcpy(v->section, section, i);
203     v->name = NULL;
204     v->value = (char *)sk;
205
206     vv = lh_CONF_VALUE_insert(conf->data, v);
207     if (vv != NULL)
208         goto err;
209     return v;
210
211  err:
212     sk_CONF_VALUE_free(sk);
213     OPENSSL_free(v);
214     return NULL;
215 }