GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/conf/conf_api.c Lines: 86 103 83.5 %
Date: 2017-11-07 Branches: 36 58 62.1 %

Line Branch Exec Source
1
/* $OpenBSD: conf_api.c,v 1.15 2015/04/11 16:03:21 deraadt Exp $ */
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 <stdlib.h>
67
#include <string.h>
68
#include <unistd.h>
69
#include <openssl/conf.h>
70
#include <openssl/conf_api.h>
71
72
static void value_free_hash_doall_arg(CONF_VALUE *a,
73
    LHASH_OF(CONF_VALUE) *conf);
74
static void value_free_stack_doall(CONF_VALUE *a);
75
34296
static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
76
    LHASH_OF(CONF_VALUE))
77
8324
static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
78
79
/* Up until OpenSSL 0.9.5a, this was get_section */
80
CONF_VALUE *
81
_CONF_get_section(const CONF *conf, const char *section)
82
{
83
5556
	CONF_VALUE *v, vv;
84
85
2778
	if ((conf == NULL) || (section == NULL))
86
		return (NULL);
87
2778
	vv.name = NULL;
88
2778
	vv.section = (char *)section;
89
2778
	v = lh_CONF_VALUE_retrieve(conf->data, &vv);
90
2778
	return (v);
91
2778
}
92
93
/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
94
STACK_OF(CONF_VALUE) *
95
_CONF_get_section_values(const CONF *conf, const char *section)
96
{
97
	CONF_VALUE *v;
98
99
212
	v = _CONF_get_section(conf, section);
100
106
	if (v != NULL)
101
106
		return ((STACK_OF(CONF_VALUE) *)v->value);
102
	else
103
		return (NULL);
104
106
}
105
106
int
107
_CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
108
{
109
	CONF_VALUE *v = NULL;
110
	STACK_OF(CONF_VALUE) *ts;
111
112
25972
	ts = (STACK_OF(CONF_VALUE) *)section->value;
113
114
12986
	value->section = section->section;
115
12986
	if (!sk_CONF_VALUE_push(ts, value)) {
116
		return 0;
117
	}
118
119
12986
	v = lh_CONF_VALUE_insert(conf->data, value);
120
12986
	if (v != NULL) {
121
		(void)sk_CONF_VALUE_delete_ptr(ts, v);
122
		free(v->name);
123
		free(v->value);
124
		free(v);
125
	}
126
12986
	return 1;
127
12986
}
128
129
char *
130
_CONF_get_string(const CONF *conf, const char *section, const char *name)
131
{
132
6072
	CONF_VALUE *v, vv;
133
134
3036
	if (name == NULL)
135
		return (NULL);
136
3036
	if (conf != NULL) {
137
3036
		if (section != NULL) {
138
1464
			vv.name = (char *)name;
139
1464
			vv.section = (char *)section;
140
1464
			v = lh_CONF_VALUE_retrieve(conf->data, &vv);
141
1464
			if (v != NULL)
142
862
				return (v->value);
143
		}
144
2174
		vv.section = "default";
145
2174
		vv.name = (char *)name;
146
2174
		v = lh_CONF_VALUE_retrieve(conf->data, &vv);
147
2174
		if (v != NULL)
148
44
			return (v->value);
149
		else
150
2130
			return (NULL);
151
	} else
152
		return (NULL);
153
3036
}
154
155
static unsigned long
156
conf_value_hash(const CONF_VALUE *v)
157
{
158
73100
	return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name);
159
}
160
161
73100
static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
162
163
static int
164
conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
165
{
166
	int i;
167
168
27996
	if (a->section != b->section) {
169
1012
		i = strcmp(a->section, b->section);
170
1012
		if (i)
171
			return (i);
172
	}
173

27890
	if ((a->name != NULL) && (b->name != NULL)) {
174
13892
		i = strcmp(a->name, b->name);
175
13892
		return (i);
176
106
	} else if (a->name == b->name)
177
106
		return (0);
178
	else
179
		return ((a->name == NULL)?-1 : 1);
180
13998
}
181
182
27996
static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
183
184
int
185
_CONF_new_data(CONF *conf)
186
{
187
2980
	if (conf == NULL) {
188
		return 0;
189
	}
190
1490
	if (conf->data == NULL)
191
1490
		if ((conf->data = lh_CONF_VALUE_new()) == NULL) {
192
			return 0;
193
		}
194
1490
	return 1;
195
1490
}
196
197
void
198
_CONF_free_data(CONF *conf)
199
{
200

4476
	if (conf == NULL || conf->data == NULL)
201
		return;
202
203
1490
	lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make
204
						  * sure the 'free()' works as
205
						  * expected */
206
1490
	lh_CONF_VALUE_doall_arg(conf->data,
207
	    LHASH_DOALL_ARG_FN(value_free_hash),
208
	    LHASH_OF(CONF_VALUE), conf->data);
209
210
	/* We now have only 'section' entries in the hash table.
211
	 * Due to problems with */
212
213
1490
	lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
214
1490
	lh_CONF_VALUE_free(conf->data);
215
2982
}
216
217
static void
218
value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
219
{
220
34296
	if (a->name != NULL)
221
12986
		(void)lh_CONF_VALUE_delete(conf, a);
222
17148
}
223
224
static void
225
value_free_stack_doall(CONF_VALUE *a)
226
{
227
	CONF_VALUE *vv;
228
	STACK_OF(CONF_VALUE) *sk;
229
	int i;
230
231
8324
	if (a->name != NULL)
232
		return;
233
234
4162
	sk = (STACK_OF(CONF_VALUE) *)a->value;
235
34296
	for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
236
12986
		vv = sk_CONF_VALUE_value(sk, i);
237
12986
		free(vv->value);
238
12986
		free(vv->name);
239
12986
		free(vv);
240
	}
241
4162
	if (sk != NULL)
242
4162
		sk_CONF_VALUE_free(sk);
243
4162
	free(a->section);
244
4162
	free(a);
245
8324
}
246
247
/* Up until OpenSSL 0.9.5a, this was new_section */
248
CONF_VALUE *
249
_CONF_new_section(CONF *conf, const char *section)
250
{
251
	STACK_OF(CONF_VALUE) *sk = NULL;
252
	int ok = 0, i;
253
	CONF_VALUE *v = NULL, *vv;
254
255
8324
	if ((sk = sk_CONF_VALUE_new_null()) == NULL)
256
		goto err;
257
4162
	if ((v = malloc(sizeof(CONF_VALUE))) == NULL)
258
		goto err;
259
4162
	i = strlen(section) + 1;
260
4162
	if ((v->section = malloc(i)) == NULL)
261
		goto err;
262
263
4162
	memcpy(v->section, section, i);
264
4162
	v->name = NULL;
265
4162
	v->value = (char *)sk;
266
267
4162
	vv = lh_CONF_VALUE_insert(conf->data, v);
268
4162
	OPENSSL_assert(vv == NULL);
269
4162
	ok = 1;
270
271
err:
272
4162
	if (!ok) {
273
		if (sk != NULL)
274
			sk_CONF_VALUE_free(sk);
275
		free(v);
276
		v = NULL;
277
	}
278
4162
	return (v);
279
}