xref: /freebsd-src/crypto/heimdal/lib/hx509/env.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov  * Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson  *    without specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson  * SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34c19800e8SDoug Rabson #include "hx_locl.h"
35c19800e8SDoug Rabson 
36c19800e8SDoug Rabson /**
37c19800e8SDoug Rabson  * @page page_env Hx509 enviroment functions
38c19800e8SDoug Rabson  *
39c19800e8SDoug Rabson  * See the library functions here: @ref hx509_env
40c19800e8SDoug Rabson  */
41c19800e8SDoug Rabson 
42c19800e8SDoug Rabson /**
43c19800e8SDoug Rabson  * Add a new key/value pair to the hx509_env.
44c19800e8SDoug Rabson  *
45c19800e8SDoug Rabson  * @param context A hx509 context.
46c19800e8SDoug Rabson  * @param env enviroment to add the enviroment variable too.
47c19800e8SDoug Rabson  * @param key key to add
48c19800e8SDoug Rabson  * @param value value to add
49c19800e8SDoug Rabson  *
50c19800e8SDoug Rabson  * @return An hx509 error code, see hx509_get_error_string().
51c19800e8SDoug Rabson  *
52c19800e8SDoug Rabson  * @ingroup hx509_env
53c19800e8SDoug Rabson  */
54c19800e8SDoug Rabson 
55c19800e8SDoug Rabson int
hx509_env_add(hx509_context context,hx509_env * env,const char * key,const char * value)56*ae771770SStanislav Sedov hx509_env_add(hx509_context context, hx509_env *env,
57c19800e8SDoug Rabson 	      const char *key, const char *value)
58c19800e8SDoug Rabson {
59*ae771770SStanislav Sedov     hx509_env n;
60c19800e8SDoug Rabson 
61*ae771770SStanislav Sedov     n = malloc(sizeof(*n));
62*ae771770SStanislav Sedov     if (n == NULL) {
63c19800e8SDoug Rabson 	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
64c19800e8SDoug Rabson 	return ENOMEM;
65c19800e8SDoug Rabson     }
66*ae771770SStanislav Sedov 
67*ae771770SStanislav Sedov     n->type = env_string;
68*ae771770SStanislav Sedov     n->next = NULL;
69*ae771770SStanislav Sedov     n->name = strdup(key);
70*ae771770SStanislav Sedov     if (n->name == NULL) {
71*ae771770SStanislav Sedov 	free(n);
72c19800e8SDoug Rabson 	return ENOMEM;
73c19800e8SDoug Rabson     }
74*ae771770SStanislav Sedov     n->u.string = strdup(value);
75*ae771770SStanislav Sedov     if (n->u.string == NULL) {
76*ae771770SStanislav Sedov 	free(n->name);
77*ae771770SStanislav Sedov 	free(n);
78c19800e8SDoug Rabson 	return ENOMEM;
79c19800e8SDoug Rabson     }
80*ae771770SStanislav Sedov 
81*ae771770SStanislav Sedov     /* add to tail */
82*ae771770SStanislav Sedov     if (*env) {
83*ae771770SStanislav Sedov 	hx509_env e = *env;
84*ae771770SStanislav Sedov 	while (e->next)
85*ae771770SStanislav Sedov 	    e = e->next;
86*ae771770SStanislav Sedov 	e->next = n;
87*ae771770SStanislav Sedov     } else
88*ae771770SStanislav Sedov 	*env = n;
89*ae771770SStanislav Sedov 
90c19800e8SDoug Rabson     return 0;
91c19800e8SDoug Rabson }
92c19800e8SDoug Rabson 
93c19800e8SDoug Rabson /**
94*ae771770SStanislav Sedov  * Add a new key/binding pair to the hx509_env.
95*ae771770SStanislav Sedov  *
96*ae771770SStanislav Sedov  * @param context A hx509 context.
97*ae771770SStanislav Sedov  * @param env enviroment to add the enviroment variable too.
98*ae771770SStanislav Sedov  * @param key key to add
99*ae771770SStanislav Sedov  * @param list binding list to add
100*ae771770SStanislav Sedov  *
101*ae771770SStanislav Sedov  * @return An hx509 error code, see hx509_get_error_string().
102*ae771770SStanislav Sedov  *
103*ae771770SStanislav Sedov  * @ingroup hx509_env
104*ae771770SStanislav Sedov  */
105*ae771770SStanislav Sedov 
106*ae771770SStanislav Sedov int
hx509_env_add_binding(hx509_context context,hx509_env * env,const char * key,hx509_env list)107*ae771770SStanislav Sedov hx509_env_add_binding(hx509_context context, hx509_env *env,
108*ae771770SStanislav Sedov 		      const char *key, hx509_env list)
109*ae771770SStanislav Sedov {
110*ae771770SStanislav Sedov     hx509_env n;
111*ae771770SStanislav Sedov 
112*ae771770SStanislav Sedov     n = malloc(sizeof(*n));
113*ae771770SStanislav Sedov     if (n == NULL) {
114*ae771770SStanislav Sedov 	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
115*ae771770SStanislav Sedov 	return ENOMEM;
116*ae771770SStanislav Sedov     }
117*ae771770SStanislav Sedov 
118*ae771770SStanislav Sedov     n->type = env_list;
119*ae771770SStanislav Sedov     n->next = NULL;
120*ae771770SStanislav Sedov     n->name = strdup(key);
121*ae771770SStanislav Sedov     if (n->name == NULL) {
122*ae771770SStanislav Sedov 	free(n);
123*ae771770SStanislav Sedov 	return ENOMEM;
124*ae771770SStanislav Sedov     }
125*ae771770SStanislav Sedov     n->u.list = list;
126*ae771770SStanislav Sedov 
127*ae771770SStanislav Sedov     /* add to tail */
128*ae771770SStanislav Sedov     if (*env) {
129*ae771770SStanislav Sedov 	hx509_env e = *env;
130*ae771770SStanislav Sedov 	while (e->next)
131*ae771770SStanislav Sedov 	    e = e->next;
132*ae771770SStanislav Sedov 	e->next = n;
133*ae771770SStanislav Sedov     } else
134*ae771770SStanislav Sedov 	*env = n;
135*ae771770SStanislav Sedov 
136*ae771770SStanislav Sedov     return 0;
137*ae771770SStanislav Sedov }
138*ae771770SStanislav Sedov 
139*ae771770SStanislav Sedov 
140*ae771770SStanislav Sedov /**
141*ae771770SStanislav Sedov  * Search the hx509_env for a length based key.
142c19800e8SDoug Rabson  *
143c19800e8SDoug Rabson  * @param context A hx509 context.
144c19800e8SDoug Rabson  * @param env enviroment to add the enviroment variable too.
145c19800e8SDoug Rabson  * @param key key to search for.
146c19800e8SDoug Rabson  * @param len length of key.
147c19800e8SDoug Rabson  *
148c19800e8SDoug Rabson  * @return the value if the key is found, NULL otherwise.
149c19800e8SDoug Rabson  *
150c19800e8SDoug Rabson  * @ingroup hx509_env
151c19800e8SDoug Rabson  */
152c19800e8SDoug Rabson 
153c19800e8SDoug Rabson const char *
hx509_env_lfind(hx509_context context,hx509_env env,const char * key,size_t len)154c19800e8SDoug Rabson hx509_env_lfind(hx509_context context, hx509_env env,
155c19800e8SDoug Rabson 		const char *key, size_t len)
156c19800e8SDoug Rabson {
157*ae771770SStanislav Sedov     while(env) {
158*ae771770SStanislav Sedov 	if (strncmp(key, env->name ,len) == 0
159*ae771770SStanislav Sedov 	    && env->name[len] == '\0' && env->type == env_string)
160*ae771770SStanislav Sedov 	    return env->u.string;
161*ae771770SStanislav Sedov 	env = env->next;
162c19800e8SDoug Rabson     }
163c19800e8SDoug Rabson     return NULL;
164c19800e8SDoug Rabson }
165c19800e8SDoug Rabson 
166c19800e8SDoug Rabson /**
167*ae771770SStanislav Sedov  * Search the hx509_env for a key.
168*ae771770SStanislav Sedov  *
169*ae771770SStanislav Sedov  * @param context A hx509 context.
170*ae771770SStanislav Sedov  * @param env enviroment to add the enviroment variable too.
171*ae771770SStanislav Sedov  * @param key key to search for.
172*ae771770SStanislav Sedov  *
173*ae771770SStanislav Sedov  * @return the value if the key is found, NULL otherwise.
174*ae771770SStanislav Sedov  *
175*ae771770SStanislav Sedov  * @ingroup hx509_env
176*ae771770SStanislav Sedov  */
177*ae771770SStanislav Sedov 
178*ae771770SStanislav Sedov const char *
hx509_env_find(hx509_context context,hx509_env env,const char * key)179*ae771770SStanislav Sedov hx509_env_find(hx509_context context, hx509_env env, const char *key)
180*ae771770SStanislav Sedov {
181*ae771770SStanislav Sedov     while(env) {
182*ae771770SStanislav Sedov 	if (strcmp(key, env->name) == 0 && env->type == env_string)
183*ae771770SStanislav Sedov 	    return env->u.string;
184*ae771770SStanislav Sedov 	env = env->next;
185*ae771770SStanislav Sedov     }
186*ae771770SStanislav Sedov     return NULL;
187*ae771770SStanislav Sedov }
188*ae771770SStanislav Sedov 
189*ae771770SStanislav Sedov /**
190*ae771770SStanislav Sedov  * Search the hx509_env for a binding.
191*ae771770SStanislav Sedov  *
192*ae771770SStanislav Sedov  * @param context A hx509 context.
193*ae771770SStanislav Sedov  * @param env enviroment to add the enviroment variable too.
194*ae771770SStanislav Sedov  * @param key key to search for.
195*ae771770SStanislav Sedov  *
196*ae771770SStanislav Sedov  * @return the binding if the key is found, NULL if not found.
197*ae771770SStanislav Sedov  *
198*ae771770SStanislav Sedov  * @ingroup hx509_env
199*ae771770SStanislav Sedov  */
200*ae771770SStanislav Sedov 
201*ae771770SStanislav Sedov hx509_env
hx509_env_find_binding(hx509_context context,hx509_env env,const char * key)202*ae771770SStanislav Sedov hx509_env_find_binding(hx509_context context,
203*ae771770SStanislav Sedov 		       hx509_env env,
204*ae771770SStanislav Sedov 		       const char *key)
205*ae771770SStanislav Sedov {
206*ae771770SStanislav Sedov     while(env) {
207*ae771770SStanislav Sedov 	if (strcmp(key, env->name) == 0 && env->type == env_list)
208*ae771770SStanislav Sedov 	    return env->u.list;
209*ae771770SStanislav Sedov 	env = env->next;
210*ae771770SStanislav Sedov     }
211*ae771770SStanislav Sedov     return NULL;
212*ae771770SStanislav Sedov }
213*ae771770SStanislav Sedov 
214*ae771770SStanislav Sedov static void
env_free(hx509_env b)215*ae771770SStanislav Sedov env_free(hx509_env b)
216*ae771770SStanislav Sedov {
217*ae771770SStanislav Sedov     while(b) {
218*ae771770SStanislav Sedov 	hx509_env next = b->next;
219*ae771770SStanislav Sedov 
220*ae771770SStanislav Sedov 	if (b->type == env_string)
221*ae771770SStanislav Sedov 	    free(b->u.string);
222*ae771770SStanislav Sedov 	else if (b->type == env_list)
223*ae771770SStanislav Sedov 	    env_free(b->u.list);
224*ae771770SStanislav Sedov 
225*ae771770SStanislav Sedov 	free(b->name);
226*ae771770SStanislav Sedov 	free(b);
227*ae771770SStanislav Sedov 	b = next;
228*ae771770SStanislav Sedov     }
229*ae771770SStanislav Sedov }
230*ae771770SStanislav Sedov 
231*ae771770SStanislav Sedov /**
232c19800e8SDoug Rabson  * Free an hx509_env enviroment context.
233c19800e8SDoug Rabson  *
234c19800e8SDoug Rabson  * @param env the enviroment to free.
235c19800e8SDoug Rabson  *
236c19800e8SDoug Rabson  * @ingroup hx509_env
237c19800e8SDoug Rabson  */
238c19800e8SDoug Rabson 
239c19800e8SDoug Rabson void
hx509_env_free(hx509_env * env)240c19800e8SDoug Rabson hx509_env_free(hx509_env *env)
241c19800e8SDoug Rabson {
242*ae771770SStanislav Sedov     if (*env)
243*ae771770SStanislav Sedov 	env_free(*env);
244c19800e8SDoug Rabson     *env = NULL;
245c19800e8SDoug Rabson }
246