xref: /openbsd/lib/libkeynote/environment.c (revision 8c119664)
1*8c119664Smmcc /* $OpenBSD: environment.c,v 1.29 2015/12/23 20:28:15 mmcc Exp $ */
2983e9580Sangelos /*
3983e9580Sangelos  * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
4983e9580Sangelos  *
5983e9580Sangelos  * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
6983e9580Sangelos  * in April-May 1998
7983e9580Sangelos  *
8983e9580Sangelos  * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
9983e9580Sangelos  *
105e4ac158Sderaadt  * Permission to use, copy, and modify this software with or without fee
11983e9580Sangelos  * is hereby granted, provided that this entire notice is included in
12983e9580Sangelos  * all copies of any software which is or includes a copy or
13983e9580Sangelos  * modification of this software.
14983e9580Sangelos  *
15983e9580Sangelos  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
16983e9580Sangelos  * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
17983e9580Sangelos  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
18983e9580Sangelos  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
19983e9580Sangelos  * PURPOSE.
20983e9580Sangelos  */
21983e9580Sangelos 
229186b70cSangelos 
239186b70cSangelos #include <sys/types.h>
24e0758482Smsf 
25e0758482Smsf #include <ctype.h>
26e0758482Smsf #include <fcntl.h>
2785616838Smsf #include <regex.h>
28983e9580Sangelos #include <stdlib.h>
299186b70cSangelos #include <stdio.h>
309186b70cSangelos #include <string.h>
31983e9580Sangelos #include <unistd.h>
32983e9580Sangelos 
33a8a6ad51Sangelos #include "keynote.h"
34a8a6ad51Sangelos #include "assertion.h"
35983e9580Sangelos 
36983e9580Sangelos static int sessioncounter = 0;
37983e9580Sangelos 
3871aaea62Smmcc char **keynote_values = NULL;
3971aaea62Smmcc char *keynote_privkey = NULL;
40a8a6ad51Sangelos 
4171aaea62Smmcc struct assertion *keynote_current_assertion = NULL;
42a8a6ad51Sangelos 
4371aaea62Smmcc struct environment *keynote_init_list = NULL;
4471aaea62Smmcc struct environment *keynote_temp_list = NULL;
45a8a6ad51Sangelos 
4671aaea62Smmcc struct keylist *keynote_keypred_keylist = NULL;
47a8a6ad51Sangelos 
48983e9580Sangelos struct keynote_session *keynote_sessions[SESSIONTABLESIZE];
49a8a6ad51Sangelos struct keynote_session *keynote_current_session = NULL;
50a8a6ad51Sangelos 
51a8a6ad51Sangelos int keynote_exceptionflag = 0;
52a8a6ad51Sangelos int keynote_used_variable = 0;
53983e9580Sangelos int keynote_returnvalue = 0;
54a8a6ad51Sangelos int keynote_justrecord = 0;
55a8a6ad51Sangelos int keynote_donteval = 0;
56a8a6ad51Sangelos int keynote_errno = 0;
57983e9580Sangelos 
58983e9580Sangelos /*
59983e9580Sangelos  * Construct the _ACTION_AUTHORIZERS variable value.
60983e9580Sangelos  */
61983e9580Sangelos static char *
keynote_get_action_authorizers(char * name)62983e9580Sangelos keynote_get_action_authorizers(char *name)
63983e9580Sangelos {
64983e9580Sangelos     struct keylist *kl;
65e74e4db0Smillert     size_t cachesize;
66983e9580Sangelos     int len;
67983e9580Sangelos 
68983e9580Sangelos     if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP) ||
69983e9580Sangelos         !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE))
70983e9580Sangelos     {
71983e9580Sangelos         free(keynote_current_session->ks_authorizers_cache);
7271aaea62Smmcc         keynote_current_session->ks_authorizers_cache = NULL;
73983e9580Sangelos 
74983e9580Sangelos 	return "";
75983e9580Sangelos     }
76983e9580Sangelos 
7771aaea62Smmcc     if (keynote_current_session->ks_authorizers_cache != NULL)
78983e9580Sangelos       return keynote_current_session->ks_authorizers_cache;
79983e9580Sangelos 
80e74e4db0Smillert     for (cachesize = 0, kl = keynote_current_session->ks_action_authorizers;
8171aaea62Smmcc 	 kl != NULL;
82983e9580Sangelos 	 kl = kl->key_next)
8371aaea62Smmcc       if (kl->key_stringkey != NULL)
84e74e4db0Smillert         cachesize += strlen(kl->key_stringkey) + 1;
85983e9580Sangelos 
86e74e4db0Smillert     if (cachesize == 0)
87983e9580Sangelos       return "";
88983e9580Sangelos 
89e74e4db0Smillert     keynote_current_session->ks_authorizers_cache =
9071aaea62Smmcc 	calloc(cachesize, sizeof(char));
9171aaea62Smmcc     if (keynote_current_session->ks_authorizers_cache == NULL) {
92983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
9371aaea62Smmcc 	return NULL;
94983e9580Sangelos     }
95983e9580Sangelos 
96983e9580Sangelos     for (len = 0, kl = keynote_current_session->ks_action_authorizers;
9771aaea62Smmcc 	 kl != NULL;
98983e9580Sangelos 	 kl = kl->key_next)
9971aaea62Smmcc       if (kl->key_stringkey != NULL) {
100e74e4db0Smillert 	  snprintf(keynote_current_session->ks_authorizers_cache + len,
101e74e4db0Smillert 		   cachesize - len, "%s,", kl->key_stringkey);
102983e9580Sangelos 	  len += strlen(kl->key_stringkey) + 1;
103983e9580Sangelos       }
104983e9580Sangelos 
105983e9580Sangelos     keynote_current_session->ks_authorizers_cache[len - 1] = '\0';
106983e9580Sangelos     return keynote_current_session->ks_authorizers_cache;
107983e9580Sangelos }
108983e9580Sangelos 
109983e9580Sangelos /*
110983e9580Sangelos  * Construct the _VALUES variable value.
111983e9580Sangelos  */
112983e9580Sangelos static char *
keynote_get_values(char * name)113983e9580Sangelos keynote_get_values(char *name)
114983e9580Sangelos {
115983e9580Sangelos     int i, len;
116e74e4db0Smillert     size_t cachesize;
117983e9580Sangelos 
118983e9580Sangelos     if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP) ||
119983e9580Sangelos         !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE))
120983e9580Sangelos     {
121983e9580Sangelos         free(keynote_current_session->ks_values_cache);
12271aaea62Smmcc         keynote_current_session->ks_values_cache = NULL;
123983e9580Sangelos 
124983e9580Sangelos 	return "";
125983e9580Sangelos     }
126983e9580Sangelos 
1276b3d627cSmmcc     if (keynote_current_session->ks_values_cache != NULL)
128983e9580Sangelos       return keynote_current_session->ks_values_cache;
129983e9580Sangelos 
130e74e4db0Smillert     for (cachesize = 0, i = 0; i < keynote_current_session->ks_values_num; i++)
131e74e4db0Smillert       cachesize += strlen(keynote_current_session->ks_values[i]) + 1;
132983e9580Sangelos 
133e74e4db0Smillert     if (cachesize == 0)
134e74e4db0Smillert       return "";
135e74e4db0Smillert 
136e74e4db0Smillert     keynote_current_session->ks_values_cache =
1376b3d627cSmmcc 	calloc(cachesize, sizeof(char));
1386b3d627cSmmcc     if (keynote_current_session->ks_values_cache == NULL) {
139983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
1406b3d627cSmmcc 	return NULL;
141983e9580Sangelos     }
142983e9580Sangelos 
143983e9580Sangelos     for (len = 0, i = 0; i < keynote_current_session->ks_values_num; i++)
144983e9580Sangelos     {
145e74e4db0Smillert 	snprintf(keynote_current_session->ks_values_cache + len,
146e74e4db0Smillert 		 cachesize - len, "%s,", keynote_current_session->ks_values[i]);
147983e9580Sangelos 	len += strlen(keynote_current_session->ks_values[i]) + 1;
148983e9580Sangelos     }
149983e9580Sangelos 
150983e9580Sangelos     keynote_current_session->ks_values_cache[len - 1] = '\0';
151983e9580Sangelos     return keynote_current_session->ks_values_cache;
152983e9580Sangelos }
153983e9580Sangelos 
154983e9580Sangelos /*
155983e9580Sangelos  * Free an environment structure.
156983e9580Sangelos  */
157983e9580Sangelos void
keynote_free_env(struct environment * en)158983e9580Sangelos keynote_free_env(struct environment *en)
159983e9580Sangelos {
1606b3d627cSmmcc     if (en == NULL)
161983e9580Sangelos       return;
162983e9580Sangelos 
163983e9580Sangelos     free(en->env_name);
164983e9580Sangelos 
165983e9580Sangelos     if (en->env_flags & ENVIRONMENT_FLAG_REGEX)
166983e9580Sangelos       regfree(&(en->env_regex));
167983e9580Sangelos 
168983e9580Sangelos     if (!(en->env_flags & ENVIRONMENT_FLAG_FUNC))
169983e9580Sangelos     {
170983e9580Sangelos         free(en->env_value);
171983e9580Sangelos     }
172983e9580Sangelos     else
173983e9580Sangelos       ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_CLEANUP);
174983e9580Sangelos 
175983e9580Sangelos     free(en);
176983e9580Sangelos }
177983e9580Sangelos 
178983e9580Sangelos /*
179983e9580Sangelos  * Lookup for variable "name" in the hash table. If hashsize is 1,
180983e9580Sangelos  * then the second argument is actually a pointer to a list. Last
181983e9580Sangelos  * argument specifies case-insensitivity.
182983e9580Sangelos  */
183983e9580Sangelos char *
keynote_env_lookup(char * name,struct environment ** table,unsigned int hashsize)184a8c336f3Sangelos keynote_env_lookup(char *name, struct environment **table,
185a8c336f3Sangelos                    unsigned int hashsize)
186983e9580Sangelos {
187983e9580Sangelos     struct environment *en;
188983e9580Sangelos 
189983e9580Sangelos     for (en = table[keynote_stringhash(name, hashsize)];
1906b3d627cSmmcc 	 en != NULL;
191983e9580Sangelos 	 en = en->env_next)
192983e9580Sangelos       if (((en->env_flags & ENVIRONMENT_FLAG_REGEX) &&
19370f56b17Smmcc 	   (regexec(&(en->env_regex), name, 0, NULL, 0) == 0)) ||
19470f56b17Smmcc 	    (!strcmp(name, en->env_name)))
195983e9580Sangelos       {
196983e9580Sangelos 	  if ((en->env_flags & ENVIRONMENT_FLAG_FUNC) &&
1976b3d627cSmmcc 	      (en->env_value != NULL))
198983e9580Sangelos 	    return ((char * (*) (char *)) en->env_value)(name);
199983e9580Sangelos 	  else
200983e9580Sangelos 	    return en->env_value;
201983e9580Sangelos       }
202983e9580Sangelos 
2036b3d627cSmmcc     return NULL;
204983e9580Sangelos }
205983e9580Sangelos 
206983e9580Sangelos /*
207983e9580Sangelos  * Delete a variable from hash table. Return RESULT_TRUE if the deletion was
208983e9580Sangelos  * successful, and RESULT_FALSE if the variable was not found.
209983e9580Sangelos  */
210983e9580Sangelos int
keynote_env_delete(char * name,struct environment ** table,unsigned int hashsize)211a8c336f3Sangelos keynote_env_delete(char *name, struct environment **table,
212a8c336f3Sangelos                    unsigned int hashsize)
213983e9580Sangelos {
214983e9580Sangelos     struct environment *en, *en2;
215a8c336f3Sangelos     unsigned int h;
216983e9580Sangelos 
217983e9580Sangelos     h = keynote_stringhash(name, hashsize);
218983e9580Sangelos 
2196b3d627cSmmcc     if (table[h] != NULL)
220983e9580Sangelos     {
221983e9580Sangelos 	if (!strcmp(table[h]->env_name, name))
222983e9580Sangelos 	{
223983e9580Sangelos 	    en = table[h];
224983e9580Sangelos 	    table[h] = en->env_next;
225983e9580Sangelos 	    keynote_free_env(en);
226983e9580Sangelos 	    return RESULT_TRUE;
227983e9580Sangelos 	}
228983e9580Sangelos 	else
229983e9580Sangelos 	  for (en = table[h];
2306b3d627cSmmcc 	       en->env_next != NULL;
231983e9580Sangelos 	       en = en->env_next)
232983e9580Sangelos 	    if (!strcmp(en->env_next->env_name, name))
233983e9580Sangelos 	    {
234983e9580Sangelos 		en2 = en->env_next;
235983e9580Sangelos 		en->env_next = en2->env_next;
236983e9580Sangelos 		keynote_free_env(en2);
237983e9580Sangelos 		return RESULT_TRUE;
238983e9580Sangelos 	    }
239983e9580Sangelos     }
240983e9580Sangelos 
241983e9580Sangelos    return RESULT_FALSE;
242983e9580Sangelos }
243983e9580Sangelos 
244983e9580Sangelos /*
245983e9580Sangelos  * Add a new variable in hash table. Return RESULT_TRUE on success,
246983e9580Sangelos  * ERROR_MEMORY on failure. If hashsize is 1, second argument is
247983e9580Sangelos  * actually a pointer to a list. The arguments are duplicated.
248983e9580Sangelos  */
249983e9580Sangelos int
keynote_env_add(char * name,char * value,struct environment ** table,unsigned int hashsize,int flags)250983e9580Sangelos keynote_env_add(char *name, char *value, struct environment **table,
251a8c336f3Sangelos 		unsigned int hashsize, int flags)
252983e9580Sangelos {
253983e9580Sangelos     struct environment *en;
254a8c336f3Sangelos     unsigned int h, i;
255983e9580Sangelos 
256983e9580Sangelos     en = calloc(1, sizeof(struct environment));
2576b3d627cSmmcc     if (en == NULL) {
258983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
259983e9580Sangelos 	return -1;
260983e9580Sangelos     }
261983e9580Sangelos 
262983e9580Sangelos     en->env_name = strdup(name);
2636b3d627cSmmcc     if (en->env_name == NULL) {
264983e9580Sangelos 	keynote_free_env(en);
265983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
266983e9580Sangelos 	return -1;
267983e9580Sangelos     }
268983e9580Sangelos 
269983e9580Sangelos     if (flags & ENVIRONMENT_FLAG_REGEX) /* Regular expression for name */
270983e9580Sangelos     {
271983e9580Sangelos 	if ((i = regcomp(&(en->env_regex), name, REG_EXTENDED)) != 0)
272983e9580Sangelos 	{
273983e9580Sangelos 	    keynote_free_env(en);
274983e9580Sangelos 	    if (i == REG_ESPACE)
275983e9580Sangelos 	      keynote_errno = ERROR_MEMORY;
276983e9580Sangelos 	    else
277983e9580Sangelos 	      keynote_errno = ERROR_SYNTAX;
278983e9580Sangelos 	    return -1;
279983e9580Sangelos 	}
280983e9580Sangelos         en->env_flags |= ENVIRONMENT_FLAG_REGEX;
281983e9580Sangelos     }
282983e9580Sangelos 
283983e9580Sangelos     if (flags & ENVIRONMENT_FLAG_FUNC) /* Callback registration */
284983e9580Sangelos     {
285983e9580Sangelos 	en->env_value = value;
286983e9580Sangelos 	en->env_flags |= ENVIRONMENT_FLAG_FUNC;
287983e9580Sangelos         ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_INITIALIZE);
288983e9580Sangelos 	if (keynote_errno != 0)
289983e9580Sangelos 	{
290983e9580Sangelos 	    keynote_free_env(en);
291983e9580Sangelos 	    return -1;
292983e9580Sangelos 	}
293983e9580Sangelos     }
294983e9580Sangelos     else
295983e9580Sangelos     {
296983e9580Sangelos 	en->env_value = strdup(value);
2976b3d627cSmmcc 	if (en->env_value == NULL) {
298983e9580Sangelos 	    keynote_free_env(en);
299983e9580Sangelos 	    keynote_errno = ERROR_MEMORY;
300983e9580Sangelos 	    return -1;
301983e9580Sangelos 	}
302983e9580Sangelos     }
303983e9580Sangelos 
304983e9580Sangelos     /*
305983e9580Sangelos      * This means that new assignments of existing variable will override
306983e9580Sangelos      * the old ones.
307983e9580Sangelos      */
308983e9580Sangelos     h = keynote_stringhash(name, hashsize);
309983e9580Sangelos     en->env_next = table[h];
310983e9580Sangelos     table[h] = en;
311983e9580Sangelos     return RESULT_TRUE;
312983e9580Sangelos }
313983e9580Sangelos 
314983e9580Sangelos /*
315983e9580Sangelos  * Cleanup an environment table.
316983e9580Sangelos  */
317983e9580Sangelos void
keynote_env_cleanup(struct environment ** table,unsigned int hashsize)318a8c336f3Sangelos keynote_env_cleanup(struct environment **table, unsigned int hashsize)
319983e9580Sangelos {
320983e9580Sangelos     struct environment *en2;
321983e9580Sangelos 
3226b3d627cSmmcc     if ((hashsize == 0) || (table == NULL))
323983e9580Sangelos       return;
324983e9580Sangelos 
325983e9580Sangelos     while (hashsize > 0)
326983e9580Sangelos     {
3276b3d627cSmmcc 	while (table[hashsize - 1] != NULL) {
328983e9580Sangelos 	    en2 = table[hashsize - 1]->env_next;
329983e9580Sangelos 	    keynote_free_env(table[hashsize - 1]);
330983e9580Sangelos 	    table[hashsize - 1] = en2;
331983e9580Sangelos 	}
332983e9580Sangelos 
333983e9580Sangelos 	hashsize--;
334983e9580Sangelos     }
335983e9580Sangelos }
336983e9580Sangelos 
337983e9580Sangelos /*
338983e9580Sangelos  * Zero out the attribute structures, seed the RNG.
339983e9580Sangelos  */
340983e9580Sangelos static int
keynote_init_environment(void)341983e9580Sangelos keynote_init_environment(void)
342983e9580Sangelos {
343983e9580Sangelos     memset(keynote_current_session->ks_env_table, 0,
344983e9580Sangelos 	   HASHTABLESIZE * sizeof(struct environment *));
345983e9580Sangelos     memset(keynote_current_session->ks_assertion_table, 0,
346983e9580Sangelos 	   HASHTABLESIZE * sizeof(struct assertion *));
3476b3d627cSmmcc     keynote_current_session->ks_env_regex = NULL;
348983e9580Sangelos 
349983e9580Sangelos     if (keynote_env_add("_ACTION_AUTHORIZERS",
350983e9580Sangelos 			(char *) keynote_get_action_authorizers,
351983e9580Sangelos 			keynote_current_session->ks_env_table, HASHTABLESIZE,
352983e9580Sangelos 			ENVIRONMENT_FLAG_FUNC) != RESULT_TRUE)
353983e9580Sangelos       return -1;
354983e9580Sangelos 
355983e9580Sangelos     if (keynote_env_add("_VALUES", (char *) keynote_get_values,
356983e9580Sangelos 			keynote_current_session->ks_env_table, HASHTABLESIZE,
357983e9580Sangelos 			ENVIRONMENT_FLAG_FUNC) != RESULT_TRUE)
358983e9580Sangelos       return -1;
359983e9580Sangelos 
360983e9580Sangelos     return RESULT_TRUE;
361983e9580Sangelos }
362983e9580Sangelos 
363983e9580Sangelos /*
364983e9580Sangelos  * Return the index of argument in keynote_values[].
365983e9580Sangelos  */
366983e9580Sangelos int
keynote_retindex(char * s)367983e9580Sangelos keynote_retindex(char *s)
368983e9580Sangelos {
369983e9580Sangelos     int i;
370983e9580Sangelos 
371983e9580Sangelos     for (i = 0; i < keynote_current_session->ks_values_num; i++)
372983e9580Sangelos       if (!strcmp(s, keynote_current_session->ks_values[i]))
373983e9580Sangelos 	return i;
374983e9580Sangelos 
375983e9580Sangelos     return -1;
376983e9580Sangelos }
377983e9580Sangelos 
378983e9580Sangelos /*
379983e9580Sangelos  * Find a session by its id.
380983e9580Sangelos  */
381983e9580Sangelos struct keynote_session *
keynote_find_session(int sessid)382983e9580Sangelos keynote_find_session(int sessid)
383983e9580Sangelos {
384983e9580Sangelos     unsigned int h = sessid % SESSIONTABLESIZE;
385983e9580Sangelos     struct keynote_session *ks;
386983e9580Sangelos 
387983e9580Sangelos     for (ks = keynote_sessions[h];
3886b3d627cSmmcc 	 ks != NULL;
389983e9580Sangelos 	 ks = ks->ks_next)
390983e9580Sangelos       if (ks->ks_id == sessid)
391983e9580Sangelos 	return ks;
392983e9580Sangelos 
3936b3d627cSmmcc     return NULL;
394983e9580Sangelos }
395983e9580Sangelos 
396983e9580Sangelos /*
397983e9580Sangelos  * Add a session in the hash table.
398983e9580Sangelos  */
399983e9580Sangelos static void
keynote_add_session(struct keynote_session * ks)400983e9580Sangelos keynote_add_session(struct keynote_session *ks)
401983e9580Sangelos {
402983e9580Sangelos     unsigned int h = ks->ks_id % SESSIONTABLESIZE;
403983e9580Sangelos 
404983e9580Sangelos     ks->ks_next = keynote_sessions[h];
4056b3d627cSmmcc     if (ks->ks_next != NULL)
406983e9580Sangelos       ks->ks_next->ks_prev = ks;
407983e9580Sangelos 
408983e9580Sangelos     keynote_sessions[h] = ks;
409983e9580Sangelos }
410983e9580Sangelos 
411983e9580Sangelos /*
412983e9580Sangelos  * Initialize a KeyNote session.
413983e9580Sangelos  */
414983e9580Sangelos int
kn_init(void)415983e9580Sangelos kn_init(void)
416983e9580Sangelos {
417983e9580Sangelos     keynote_errno = 0;
4186b3d627cSmmcc     keynote_current_session = calloc(1, sizeof(struct keynote_session));
4196b3d627cSmmcc     if (keynote_current_session == NULL) {
420983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
421983e9580Sangelos 	return -1;
422983e9580Sangelos     }
423983e9580Sangelos 
4246b3d627cSmmcc     while (keynote_find_session(sessioncounter) != NULL) {
425983e9580Sangelos 	sessioncounter++;
426983e9580Sangelos 	if (sessioncounter < 0)
427983e9580Sangelos 	  sessioncounter = 0;
428983e9580Sangelos     }
429983e9580Sangelos 
430983e9580Sangelos     keynote_current_session->ks_id = sessioncounter++;
431983e9580Sangelos     keynote_init_environment();
432983e9580Sangelos     keynote_add_session(keynote_current_session);
433983e9580Sangelos     return keynote_current_session->ks_id;
434983e9580Sangelos }
435983e9580Sangelos 
436983e9580Sangelos /*
4379186b70cSangelos  * Cleanup the action environment.
4389186b70cSangelos  */
4399186b70cSangelos int
kn_cleanup_action_environment(int sessid)4409186b70cSangelos kn_cleanup_action_environment(int sessid)
4419186b70cSangelos {
4429186b70cSangelos     struct keynote_session *ks;
4439186b70cSangelos 
4449186b70cSangelos     keynote_errno = 0;
4456b3d627cSmmcc     if ((keynote_current_session == NULL) ||
4469186b70cSangelos 	(keynote_current_session->ks_id != sessid))
4479186b70cSangelos     {
4489186b70cSangelos 	keynote_current_session = keynote_find_session(sessid);
4496b3d627cSmmcc 	if (keynote_current_session == NULL) {
4509186b70cSangelos 	    keynote_errno = ERROR_NOTFOUND;
4519186b70cSangelos 	    return -1;
4529186b70cSangelos 	}
4539186b70cSangelos     }
4549186b70cSangelos 
4559186b70cSangelos     ks = keynote_current_session;
4569186b70cSangelos 
4579186b70cSangelos     /* Cleanup environment */
4589186b70cSangelos     keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE);
4599186b70cSangelos     keynote_env_cleanup(&(ks->ks_env_regex), 1);
4609186b70cSangelos 
4619186b70cSangelos     return 0;
4629186b70cSangelos }
4639186b70cSangelos 
4649186b70cSangelos /*
465983e9580Sangelos  * Close a session.
466983e9580Sangelos  */
467983e9580Sangelos int
kn_close(int sessid)468983e9580Sangelos kn_close(int sessid)
469983e9580Sangelos {
470983e9580Sangelos     struct keynote_session *ks;
471983e9580Sangelos     struct assertion *as, *as2;
472983e9580Sangelos     int i;
473983e9580Sangelos 
474983e9580Sangelos     keynote_errno = 0;
4756b3d627cSmmcc     if ((keynote_current_session == NULL) ||
476983e9580Sangelos 	(keynote_current_session->ks_id != sessid))
477983e9580Sangelos     {
478983e9580Sangelos 	keynote_current_session = keynote_find_session(sessid);
4796b3d627cSmmcc 	if (keynote_current_session == NULL) {
480983e9580Sangelos 	    keynote_errno = ERROR_NOTFOUND;
481983e9580Sangelos 	    return -1;
482983e9580Sangelos 	}
483983e9580Sangelos     }
484983e9580Sangelos 
485983e9580Sangelos     ks = keynote_current_session;
486983e9580Sangelos 
4879186b70cSangelos     /* Cleanup environment -- no point using kn_cleanup_action_environment() */
488983e9580Sangelos     keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE);
489983e9580Sangelos     keynote_env_cleanup(&(ks->ks_env_regex), 1);
490983e9580Sangelos 
491983e9580Sangelos     /* Cleanup assertions */
492983e9580Sangelos     for (i = 0; i < HASHTABLESIZE; i++)
493983e9580Sangelos       for (as = ks->ks_assertion_table[i];
4946b3d627cSmmcc 	   as != NULL;
495983e9580Sangelos 	   as = as2)
496983e9580Sangelos       {
497983e9580Sangelos 	  as2 = as->as_next;
498983e9580Sangelos 	  keynote_free_assertion(as);
499983e9580Sangelos       }
500983e9580Sangelos 
501983e9580Sangelos     /* Cleanup action authorizers */
502983e9580Sangelos     keynote_keylist_free(ks->ks_action_authorizers);
503983e9580Sangelos 
504983e9580Sangelos     /* Unlink from chain */
5056b3d627cSmmcc     if (ks->ks_prev == NULL) {
506983e9580Sangelos 	keynote_sessions[ks->ks_id % SESSIONTABLESIZE] = ks->ks_next;
5076b3d627cSmmcc 	if (ks->ks_next != NULL)
5086b3d627cSmmcc 	  ks->ks_next->ks_prev = NULL;
509983e9580Sangelos 
510983e9580Sangelos     }
511983e9580Sangelos     else
512983e9580Sangelos     {
513983e9580Sangelos 	ks->ks_prev->ks_next = ks->ks_next;
5146b3d627cSmmcc 	if (ks->ks_next != NULL)
515983e9580Sangelos 	  ks->ks_next->ks_prev = ks->ks_prev;
516983e9580Sangelos     }
517983e9580Sangelos 
518983e9580Sangelos     free(ks);
5196b3d627cSmmcc     keynote_current_session = NULL;
520983e9580Sangelos     return 0;
521983e9580Sangelos }
522983e9580Sangelos 
523983e9580Sangelos /*
524983e9580Sangelos  * Add an action attribute.
525983e9580Sangelos  */
526983e9580Sangelos int
kn_add_action(int sessid,char * name,char * value,int flags)527983e9580Sangelos kn_add_action(int sessid, char *name, char *value, int flags)
528983e9580Sangelos {
529983e9580Sangelos     int i;
530983e9580Sangelos 
531983e9580Sangelos     keynote_errno = 0;
532037dc99cSmmcc     if (name == NULL || value == NULL || name[0] == '_') {
533983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
534983e9580Sangelos 	return -1;
535983e9580Sangelos     }
536983e9580Sangelos 
537037dc99cSmmcc     if (keynote_current_session == NULL ||
538037dc99cSmmcc 	keynote_current_session->ks_id != sessid)
539983e9580Sangelos     {
540983e9580Sangelos 	keynote_current_session = keynote_find_session(sessid);
541037dc99cSmmcc 	if (keynote_current_session == NULL) {
542983e9580Sangelos 	    keynote_errno = ERROR_NOTFOUND;
543983e9580Sangelos 	    return -1;
544983e9580Sangelos 	}
545983e9580Sangelos     }
546983e9580Sangelos 
547983e9580Sangelos     if (flags & ENVIRONMENT_FLAG_REGEX)
548983e9580Sangelos       i = keynote_env_add(name, value,
549983e9580Sangelos 			  &(keynote_current_session->ks_env_regex), 1, flags);
550983e9580Sangelos     else
551983e9580Sangelos       i = keynote_env_add(name, value, keynote_current_session->ks_env_table,
552983e9580Sangelos 			  HASHTABLESIZE, flags);
553983e9580Sangelos 
554983e9580Sangelos     if (i == RESULT_TRUE)
555983e9580Sangelos       return 0;
556983e9580Sangelos     else
557983e9580Sangelos       return -1;
558983e9580Sangelos }
559983e9580Sangelos 
560983e9580Sangelos /*
561983e9580Sangelos  * Remove an action attribute.
562983e9580Sangelos  */
563983e9580Sangelos int
kn_remove_action(int sessid,char * name)564983e9580Sangelos kn_remove_action(int sessid, char *name)
565983e9580Sangelos {
566983e9580Sangelos     int i;
567983e9580Sangelos 
568983e9580Sangelos     keynote_errno = 0;
569037dc99cSmmcc     if (name == NULL || name[0] == '_') {
570983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
571983e9580Sangelos 	return -1;
572983e9580Sangelos     }
573983e9580Sangelos 
574037dc99cSmmcc     if (keynote_current_session == NULL ||
575037dc99cSmmcc 	keynote_current_session->ks_id != sessid)
576983e9580Sangelos     {
577983e9580Sangelos 	keynote_current_session = keynote_find_session(sessid);
578037dc99cSmmcc 	if (keynote_current_session == NULL) {
579983e9580Sangelos 	    keynote_errno = ERROR_NOTFOUND;
580983e9580Sangelos 	    return -1;
581983e9580Sangelos 	}
582983e9580Sangelos     }
583983e9580Sangelos 
584983e9580Sangelos     i = keynote_env_delete(name, keynote_current_session->ks_env_table,
585983e9580Sangelos 			   HASHTABLESIZE);
586983e9580Sangelos     if (i == RESULT_TRUE)
587983e9580Sangelos       return 0;
588983e9580Sangelos 
589983e9580Sangelos     i = keynote_env_delete(name, &(keynote_current_session->ks_env_regex),
590983e9580Sangelos 			   HASHTABLESIZE);
591983e9580Sangelos     if (i == RESULT_TRUE)
592983e9580Sangelos       return 0;
593983e9580Sangelos 
594983e9580Sangelos     keynote_errno = ERROR_NOTFOUND;
595983e9580Sangelos     return -1;
596983e9580Sangelos }
597983e9580Sangelos 
598983e9580Sangelos /*
599983e9580Sangelos  * Execute a query.
600983e9580Sangelos  */
601983e9580Sangelos int
kn_do_query(int sessid,char ** returnvalues,int numvalues)602983e9580Sangelos kn_do_query(int sessid, char **returnvalues, int numvalues)
603983e9580Sangelos {
604983e9580Sangelos     struct assertion *as;
605983e9580Sangelos     int i;
606983e9580Sangelos 
607983e9580Sangelos     keynote_errno = 0;
608037dc99cSmmcc     if (keynote_current_session == NULL ||
609037dc99cSmmcc 	keynote_current_session->ks_id != sessid)
610983e9580Sangelos     {
611983e9580Sangelos 	keynote_current_session = keynote_find_session(sessid);
612037dc99cSmmcc 	if (keynote_current_session == NULL) {
613983e9580Sangelos 	    keynote_errno = ERROR_NOTFOUND;
614983e9580Sangelos 	    return -1;
615983e9580Sangelos 	}
616983e9580Sangelos     }
617983e9580Sangelos 
618983e9580Sangelos     /* Check that we have at least one action authorizer */
619037dc99cSmmcc     if (keynote_current_session->ks_action_authorizers == NULL) {
620983e9580Sangelos 	keynote_errno = ERROR_NOTFOUND;
621983e9580Sangelos 	return -1;
622983e9580Sangelos     }
623983e9580Sangelos 
624983e9580Sangelos     /*
625983e9580Sangelos      * We may use already set returnvalues, or use new ones,
626983e9580Sangelos      * but we must have some before we can evaluate.
627983e9580Sangelos      */
628037dc99cSmmcc     if (returnvalues == NULL &&
629037dc99cSmmcc 	keynote_current_session->ks_values == NULL)
630983e9580Sangelos     {
631983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
632983e9580Sangelos 	return -1;
633983e9580Sangelos     }
634983e9580Sangelos 
635983e9580Sangelos     /* Replace any existing returnvalues */
636037dc99cSmmcc     if (returnvalues != NULL) {
637983e9580Sangelos 	keynote_current_session->ks_values = returnvalues;
638983e9580Sangelos 	keynote_current_session->ks_values_num = numvalues;
639983e9580Sangelos     }
640983e9580Sangelos 
641983e9580Sangelos     /* Reset assertion state from any previous queries */
642983e9580Sangelos     for (i = 0; i < HASHTABLESIZE; i++)
643983e9580Sangelos       for (as = keynote_current_session->ks_assertion_table[i];
644037dc99cSmmcc 	   as != NULL;
645983e9580Sangelos 	   as = as->as_next)
646983e9580Sangelos       {
647983e9580Sangelos 	  as->as_kresult = KRESULT_UNTOUCHED;
648983e9580Sangelos 	  as->as_result = 0;
649983e9580Sangelos 	  as->as_internalflags &= ~ASSERT_IFLAG_PROCESSED;
650983e9580Sangelos 	  as->as_error = 0;
651983e9580Sangelos 	  if (as->as_internalflags & ASSERT_IFLAG_WEIRDSIG)
652983e9580Sangelos 	    as->as_sigresult = SIGRESULT_UNTOUCHED;
653983e9580Sangelos       }
654983e9580Sangelos 
655983e9580Sangelos     return keynote_evaluate_query();
656983e9580Sangelos }
657983e9580Sangelos 
658983e9580Sangelos /*
659983e9580Sangelos  * Return assertions that failed, by error type.
660983e9580Sangelos  */
661983e9580Sangelos int
kn_get_failed(int sessid,int type,int num)662983e9580Sangelos kn_get_failed(int sessid, int type, int num)
663983e9580Sangelos {
664983e9580Sangelos     struct assertion *as;
665983e9580Sangelos     int i;
666983e9580Sangelos 
667ca0ac210Sangelos     keynote_errno = 0;
668037dc99cSmmcc     if (keynote_current_session == NULL ||
669037dc99cSmmcc 	keynote_current_session->ks_id != sessid)
670983e9580Sangelos     {
671983e9580Sangelos 	keynote_current_session = keynote_find_session(sessid);
672037dc99cSmmcc 	if (keynote_current_session == NULL) {
673983e9580Sangelos 	    keynote_errno = ERROR_NOTFOUND;
674983e9580Sangelos 	    return -1;
675983e9580Sangelos 	}
676983e9580Sangelos     }
677983e9580Sangelos 
678983e9580Sangelos     for (i = 0; i < HASHTABLESIZE; i++)
679983e9580Sangelos       for (as = keynote_current_session->ks_assertion_table[i];
680037dc99cSmmcc 	   as != NULL;
681983e9580Sangelos 	   as = as->as_next)
682983e9580Sangelos 	switch (type)
683983e9580Sangelos 	{
684983e9580Sangelos 	    case KEYNOTE_ERROR_ANY:
685983e9580Sangelos 		if ((as->as_error != 0) ||
686983e9580Sangelos 		    ((as->as_sigresult != SIGRESULT_TRUE) &&
68781c71ef0Sangelos 		     !(as->as_sigresult == SIGRESULT_UNTOUCHED) &&
688983e9580Sangelos 		     !(as->as_flags & ASSERT_FLAG_LOCAL)))
689983e9580Sangelos 		  if (num-- == 0)  /* Return it if it's the num-th found */
690983e9580Sangelos 		    return as->as_id;
691983e9580Sangelos 		break;
692983e9580Sangelos 
693983e9580Sangelos 	    case KEYNOTE_ERROR_MEMORY:
694983e9580Sangelos 		if (as->as_error == ERROR_MEMORY)
695983e9580Sangelos 		  if (num-- == 0)
696983e9580Sangelos 		    return as->as_id;
697983e9580Sangelos 		break;
698983e9580Sangelos 
699983e9580Sangelos 	    case KEYNOTE_ERROR_SYNTAX:
700983e9580Sangelos 		if (as->as_error == ERROR_SYNTAX)
701983e9580Sangelos 		  if (num-- == 0)
702983e9580Sangelos 		    return as->as_id;
703983e9580Sangelos 		break;
704983e9580Sangelos 
705983e9580Sangelos 	    case KEYNOTE_ERROR_SIGNATURE:
706983e9580Sangelos 		if ((as->as_sigresult != SIGRESULT_TRUE) &&
70781c71ef0Sangelos 		    !(as->as_sigresult == SIGRESULT_UNTOUCHED) &&
708983e9580Sangelos 		    !(as->as_flags & ASSERT_FLAG_LOCAL))
709983e9580Sangelos 		  if (num-- == 0)
710983e9580Sangelos 		    return as->as_id;
711983e9580Sangelos 		break;
712983e9580Sangelos 	}
713983e9580Sangelos 
714983e9580Sangelos     keynote_errno = ERROR_NOTFOUND;
715983e9580Sangelos     return -1;
716983e9580Sangelos }
717983e9580Sangelos 
718983e9580Sangelos /*
719983e9580Sangelos  * Simple API for doing a single KeyNote query.
720983e9580Sangelos  */
721983e9580Sangelos int
kn_query(struct environment * env,char ** retvalues,int numval,char ** trusted,int * trustedlen,int numtrusted,char ** untrusted,int * untrustedlen,int numuntrusted,char ** authorizers,int numauthorizers)722983e9580Sangelos kn_query(struct environment *env, char **retvalues, int numval,
723983e9580Sangelos 	 char **trusted, int *trustedlen, int numtrusted,
724983e9580Sangelos 	 char **untrusted, int *untrustedlen, int numuntrusted,
725983e9580Sangelos 	 char **authorizers, int numauthorizers)
726983e9580Sangelos {
727983e9580Sangelos     struct environment *en;
728983e9580Sangelos     int sessid, i, serrno;
729983e9580Sangelos 
730983e9580Sangelos     keynote_errno = 0;
731983e9580Sangelos     if ((sessid = kn_init()) == -1)
732983e9580Sangelos       return -1;
733983e9580Sangelos 
734983e9580Sangelos     /* Action set */
735037dc99cSmmcc     for (en = env; en != NULL; en = en->env_next)
7361c338448Sangelos       if (kn_add_action(sessid, en->env_name, en->env_value,
7371c338448Sangelos           en->env_flags) == -1)
738ca0ac210Sangelos       {
739ca0ac210Sangelos 	  serrno = keynote_errno;
740ca0ac210Sangelos 	  kn_close(sessid);
741ca0ac210Sangelos 	  keynote_errno = serrno;
742ca0ac210Sangelos 	  return -1;
743ca0ac210Sangelos       }
744983e9580Sangelos 
745983e9580Sangelos     /* Locally trusted assertions */
746983e9580Sangelos     for (i = 0; i < numtrusted; i++)
7471c338448Sangelos       if ((kn_add_assertion(sessid, trusted[i], trustedlen[i],
7481c338448Sangelos 	  ASSERT_FLAG_LOCAL) == -1) && (keynote_errno == ERROR_MEMORY))
749ca0ac210Sangelos       {
750ca0ac210Sangelos 	  serrno = keynote_errno;
751ca0ac210Sangelos 	  kn_close(sessid);
752ca0ac210Sangelos 	  keynote_errno = serrno;
753ca0ac210Sangelos 	  return -1;
754ca0ac210Sangelos       }
755983e9580Sangelos 
756983e9580Sangelos     /* Untrusted assertions */
757983e9580Sangelos     for (i = 0; i < numuntrusted; i++)
7581c338448Sangelos       if ((kn_add_assertion(sessid, untrusted[i], untrustedlen[i], 0) == -1)
7591c338448Sangelos 	  && (keynote_errno == ERROR_MEMORY))
760ca0ac210Sangelos       {
761ca0ac210Sangelos 	  serrno = keynote_errno;
762ca0ac210Sangelos 	  kn_close(sessid);
763ca0ac210Sangelos 	  keynote_errno = serrno;
764ca0ac210Sangelos 	  return -1;
765ca0ac210Sangelos       }
766983e9580Sangelos 
767983e9580Sangelos     /* Authorizers */
768983e9580Sangelos     for (i = 0; i < numauthorizers; i++)
769ca0ac210Sangelos       if (kn_add_authorizer(sessid, authorizers[i]) == -1)
770ca0ac210Sangelos       {
771ca0ac210Sangelos 	  serrno = keynote_errno;
772ca0ac210Sangelos 	  kn_close(sessid);
773ca0ac210Sangelos 	  keynote_errno = serrno;
774ca0ac210Sangelos 	  return -1;
775ca0ac210Sangelos       }
776983e9580Sangelos 
777983e9580Sangelos     i = kn_do_query(sessid, retvalues, numval);
778983e9580Sangelos     serrno = keynote_errno;
779983e9580Sangelos     kn_close(sessid);
780983e9580Sangelos 
781983e9580Sangelos     if (serrno)
782983e9580Sangelos       keynote_errno = serrno;
783983e9580Sangelos 
784983e9580Sangelos     return i;
785983e9580Sangelos }
786983e9580Sangelos 
787983e9580Sangelos /*
788983e9580Sangelos  * Read a buffer, break it up in assertions.
789983e9580Sangelos  */
790983e9580Sangelos char **
kn_read_asserts(char * buffer,int bufferlen,int * numassertions)791983e9580Sangelos kn_read_asserts(char *buffer, int bufferlen, int *numassertions)
792983e9580Sangelos {
793983e9580Sangelos     int bufsize = 32, i, flag, valid;
794983e9580Sangelos     char **buf, **tempbuf, *ptr;
795983e9580Sangelos 
796983e9580Sangelos     keynote_errno = 0;
797037dc99cSmmcc     if (buffer == NULL) {
798983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
799037dc99cSmmcc 	return NULL;
800983e9580Sangelos     }
801983e9580Sangelos 
802037dc99cSmmcc     if ((buf = calloc(bufsize, sizeof(char *))) == NULL) {
803983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
804037dc99cSmmcc 	return NULL;
805983e9580Sangelos     }
806983e9580Sangelos 
807983e9580Sangelos     /*
808983e9580Sangelos      * We'll go through the whole buffer looking for consecutive newlines,
809983e9580Sangelos      * which imply newline separation. We use the valid flag to keep
810983e9580Sangelos      * track of whether there may be an assertion after the last pair of
811983e9580Sangelos      * newlines, or whether there may be an assertion in the buffer to
812983e9580Sangelos      * begin with, if there are no consecutive newlines.
813983e9580Sangelos      */
814983e9580Sangelos     for (i = 0, flag = 0, valid = 0, *numassertions = 0, ptr = buffer;
815983e9580Sangelos 	 i < bufferlen;
816983e9580Sangelos 	 i++)
817983e9580Sangelos     {
818983e9580Sangelos 	if (buffer[i] == '\n')
819983e9580Sangelos 	{
820983e9580Sangelos 	    if (flag)  /* Two newlines in a row, copy if there's anything */
821983e9580Sangelos 	    {
822983e9580Sangelos 		if (valid)  /* Something there */
823983e9580Sangelos 		{
824983e9580Sangelos 		    /* Allocate enough memory */
825037dc99cSmmcc 		    buf[*numassertions] = calloc((buffer + i) - ptr
826983e9580Sangelos 							  + 1, sizeof(char));
827037dc99cSmmcc 		    if (buf[*numassertions] == NULL) {
828983e9580Sangelos 			/* Free any already-allocated strings */
829983e9580Sangelos 			for (flag = 0; flag < *numassertions; flag++)
830983e9580Sangelos 			  free(buf[flag]);
831983e9580Sangelos 			free(buf);
832983e9580Sangelos 			keynote_errno = ERROR_MEMORY;
833037dc99cSmmcc 			return NULL;
834983e9580Sangelos 		    }
835983e9580Sangelos 
836983e9580Sangelos 		    /* Copy string */
8379186b70cSangelos 		    memcpy(buf[*numassertions], ptr, (buffer + i) - ptr);
838983e9580Sangelos 		    (*numassertions)++;
839983e9580Sangelos 		}
840983e9580Sangelos 
841983e9580Sangelos 		valid = 0; /* Reset */
842983e9580Sangelos 		flag = 0;
843983e9580Sangelos 		ptr = buffer + i + 1; /* Point right after this newline */
844983e9580Sangelos 
845983e9580Sangelos 		/* See if we need to resize the buffer */
846983e9580Sangelos 		if (*numassertions > bufsize - 4)
847983e9580Sangelos 		{
848983e9580Sangelos 		    /* Allocate twice the space */
849037dc99cSmmcc 		    tempbuf = reallocarray(buf, bufsize, 2 * sizeof(char *));
850037dc99cSmmcc 		    if (tempbuf == NULL) {
851983e9580Sangelos 			for (flag = 0; flag < *numassertions; flag++)
852983e9580Sangelos 			  free(buf[flag]);
853983e9580Sangelos 			free(buf);
854983e9580Sangelos 			keynote_errno = ERROR_MEMORY;
855037dc99cSmmcc 			return NULL;
856983e9580Sangelos 		    }
857983e9580Sangelos 
858983e9580Sangelos 		    buf = tempbuf;
859983e9580Sangelos 		    bufsize *= 2;
860983e9580Sangelos 		}
861983e9580Sangelos 	    }
862983e9580Sangelos 	    else
863983e9580Sangelos 	      flag = 1;  /* One newline so far */
864983e9580Sangelos 
865983e9580Sangelos 	    continue;
866983e9580Sangelos 	}
867983e9580Sangelos 	else
868983e9580Sangelos 	  flag = 0;
869983e9580Sangelos 
87080c62621Sderaadt 	if (!isspace((unsigned char)buffer[i]))
871983e9580Sangelos 	  valid = 1;
872983e9580Sangelos     }
873983e9580Sangelos 
874983e9580Sangelos     /*
875983e9580Sangelos      * There may be a valid assertion after the last pair of newlines.
876983e9580Sangelos      * Notice that because of the resizing check above, there will be
877983e9580Sangelos      * a valid memory location to store this last string.
878983e9580Sangelos      */
879983e9580Sangelos     if (valid)
880983e9580Sangelos     {
881983e9580Sangelos 	/* This one's easy, we can just use strdup() */
882037dc99cSmmcc 	if ((buf[*numassertions] = strdup(ptr)) == NULL) {
883983e9580Sangelos 	    for (flag = 0; flag < *numassertions; flag++)
884983e9580Sangelos 	      free(buf[flag]);
885983e9580Sangelos 	    free(buf);
886983e9580Sangelos 	    keynote_errno = ERROR_MEMORY;
887037dc99cSmmcc 	    return NULL;
888983e9580Sangelos 	}
889983e9580Sangelos 	(*numassertions)++;
890983e9580Sangelos     }
891983e9580Sangelos 
892983e9580Sangelos     return buf;
893983e9580Sangelos }
8949186b70cSangelos 
8959186b70cSangelos /*
8969186b70cSangelos  * Return the authorizer key for a given assertion.
8979186b70cSangelos  */
8989186b70cSangelos void *
kn_get_authorizer(int sessid,int assertid,int * algorithm)8999186b70cSangelos kn_get_authorizer(int sessid, int assertid, int *algorithm)
9009186b70cSangelos {
9019186b70cSangelos     struct assertion *as;
9029186b70cSangelos     int i;
9039186b70cSangelos 
904616f18cbSangelos     keynote_errno = *algorithm = 0;
905232b012bSmmcc     if (keynote_current_session == NULL ||
906232b012bSmmcc 	keynote_current_session->ks_id != sessid)
9079186b70cSangelos     {
9089186b70cSangelos 	keynote_current_session = keynote_find_session(sessid);
909232b012bSmmcc 	if (keynote_current_session == NULL) {
9109186b70cSangelos 	    keynote_errno = ERROR_NOTFOUND;
911232b012bSmmcc 	    return NULL;
9129186b70cSangelos 	}
9139186b70cSangelos     }
9149186b70cSangelos 
9159186b70cSangelos     /* Traverse the hash table looking for assertid */
9169186b70cSangelos     for (i = 0; i < HASHTABLESIZE; i++)
9179186b70cSangelos       for (as = keynote_current_session->ks_assertion_table[i];
918232b012bSmmcc 	   as != NULL;
9199186b70cSangelos 	   as = as->as_next)
9209186b70cSangelos 	if (as->as_id == assertid)
921616f18cbSangelos 	  goto out;
9229186b70cSangelos 
923616f18cbSangelos  out:
924232b012bSmmcc     if (as == NULL) {
9259186b70cSangelos 	keynote_errno = ERROR_NOTFOUND;
926232b012bSmmcc 	return NULL;
9279186b70cSangelos     }
9289186b70cSangelos 
929616f18cbSangelos     if (as->as_authorizer == NULL)
930616f18cbSangelos       if (keynote_evaluate_authorizer(as, 1) != RESULT_TRUE)
931616f18cbSangelos 	return NULL;
932616f18cbSangelos 
9339186b70cSangelos     *algorithm = as->as_signeralgorithm;
9349186b70cSangelos     return as->as_authorizer;
9359186b70cSangelos }
9369186b70cSangelos 
9379186b70cSangelos /*
9389186b70cSangelos  * Return the licensees for a given assertion.
9399186b70cSangelos  */
9409186b70cSangelos struct keynote_keylist *
kn_get_licensees(int sessid,int assertid)9419186b70cSangelos kn_get_licensees(int sessid, int assertid)
9429186b70cSangelos {
9439186b70cSangelos     struct assertion *as;
9449186b70cSangelos     int i;
9459186b70cSangelos 
946ca0ac210Sangelos     keynote_errno = 0;
947232b012bSmmcc     if (keynote_current_session == NULL ||
948232b012bSmmcc 	keynote_current_session->ks_id != sessid)
9499186b70cSangelos     {
9509186b70cSangelos 	keynote_current_session = keynote_find_session(sessid);
951232b012bSmmcc 	if (keynote_current_session == NULL) {
9529186b70cSangelos 	    keynote_errno = ERROR_NOTFOUND;
953232b012bSmmcc 	    return NULL;
9549186b70cSangelos 	}
9559186b70cSangelos     }
9569186b70cSangelos 
9579186b70cSangelos     /* Traverse the hash table looking for assertid */
9589186b70cSangelos     for (i = 0; i < HASHTABLESIZE; i++)
9599186b70cSangelos       for (as = keynote_current_session->ks_assertion_table[i];
960232b012bSmmcc 	   as != NULL;
9619186b70cSangelos 	   as = as->as_next)
9629186b70cSangelos 	if (as->as_id == assertid)
963616f18cbSangelos 	  goto out;
9649186b70cSangelos 
965616f18cbSangelos  out:
966232b012bSmmcc     if (as == NULL) {
9679186b70cSangelos 	keynote_errno = ERROR_NOTFOUND;
968232b012bSmmcc 	return NULL;
9699186b70cSangelos     }
9709186b70cSangelos 
971bdbb5d20Sangelos     if (as->as_keylist == NULL)
972bdbb5d20Sangelos       if (keynote_parse_keypred(as, 1) != RESULT_TRUE)
973232b012bSmmcc 	return NULL;
974bdbb5d20Sangelos 
9759186b70cSangelos     return (struct keynote_keylist *) as->as_keylist;
9769186b70cSangelos }
977