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