Bug Summary

File:src/lib/libkeynote/environment.c
Warning:line 173, column 7
Called function pointer is null (null dereference)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name environment.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libkeynote/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/lib/libkeynote -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libkeynote/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libkeynote/environment.c
1/* $OpenBSD: environment.c,v 1.29 2015/12/23 20:28:15 mmcc Exp $ */
2/*
3 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
4 *
5 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
6 * in April-May 1998
7 *
8 * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
9 *
10 * Permission to use, copy, and modify this software with or without fee
11 * is hereby granted, provided that this entire notice is included in
12 * all copies of any software which is or includes a copy or
13 * modification of this software.
14 *
15 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
17 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
18 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
19 * PURPOSE.
20 */
21
22
23#include <sys/types.h>
24
25#include <ctype.h>
26#include <fcntl.h>
27#include <regex.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <unistd.h>
32
33#include "keynote.h"
34#include "assertion.h"
35
36static int sessioncounter = 0;
37
38char **keynote_values = NULL((void *)0);
39char *keynote_privkey = NULL((void *)0);
40
41struct assertion *keynote_current_assertion = NULL((void *)0);
42
43struct environment *keynote_init_list = NULL((void *)0);
44struct environment *keynote_temp_list = NULL((void *)0);
45
46struct keylist *keynote_keypred_keylist = NULL((void *)0);
47
48struct keynote_session *keynote_sessions[SESSIONTABLESIZE37];
49struct keynote_session *keynote_current_session = NULL((void *)0);
50
51int keynote_exceptionflag = 0;
52int keynote_used_variable = 0;
53int keynote_returnvalue = 0;
54int keynote_justrecord = 0;
55int keynote_donteval = 0;
56int keynote_errno = 0;
57
58/*
59 * Construct the _ACTION_AUTHORIZERS variable value.
60 */
61static char *
62keynote_get_action_authorizers(char *name)
63{
64 struct keylist *kl;
65 size_t cachesize;
66 int len;
67
68 if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP"_KEYNOTE_CALLBACK_CLEANUP") ||
69 !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE"_KEYNOTE_CALLBACK_INITIALIZE"))
70 {
71 free(keynote_current_session->ks_authorizers_cache);
72 keynote_current_session->ks_authorizers_cache = NULL((void *)0);
73
74 return "";
75 }
76
77 if (keynote_current_session->ks_authorizers_cache != NULL((void *)0))
78 return keynote_current_session->ks_authorizers_cache;
79
80 for (cachesize = 0, kl = keynote_current_session->ks_action_authorizers;
81 kl != NULL((void *)0);
82 kl = kl->key_next)
83 if (kl->key_stringkey != NULL((void *)0))
84 cachesize += strlen(kl->key_stringkey) + 1;
85
86 if (cachesize == 0)
87 return "";
88
89 keynote_current_session->ks_authorizers_cache =
90 calloc(cachesize, sizeof(char));
91 if (keynote_current_session->ks_authorizers_cache == NULL((void *)0)) {
92 keynote_errno = ERROR_MEMORY-1;
93 return NULL((void *)0);
94 }
95
96 for (len = 0, kl = keynote_current_session->ks_action_authorizers;
97 kl != NULL((void *)0);
98 kl = kl->key_next)
99 if (kl->key_stringkey != NULL((void *)0)) {
100 snprintf(keynote_current_session->ks_authorizers_cache + len,
101 cachesize - len, "%s,", kl->key_stringkey);
102 len += strlen(kl->key_stringkey) + 1;
103 }
104
105 keynote_current_session->ks_authorizers_cache[len - 1] = '\0';
106 return keynote_current_session->ks_authorizers_cache;
107}
108
109/*
110 * Construct the _VALUES variable value.
111 */
112static char *
113keynote_get_values(char *name)
114{
115 int i, len;
116 size_t cachesize;
117
118 if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP"_KEYNOTE_CALLBACK_CLEANUP") ||
119 !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE"_KEYNOTE_CALLBACK_INITIALIZE"))
120 {
121 free(keynote_current_session->ks_values_cache);
122 keynote_current_session->ks_values_cache = NULL((void *)0);
123
124 return "";
125 }
126
127 if (keynote_current_session->ks_values_cache != NULL((void *)0))
128 return keynote_current_session->ks_values_cache;
129
130 for (cachesize = 0, i = 0; i < keynote_current_session->ks_values_num; i++)
131 cachesize += strlen(keynote_current_session->ks_values[i]) + 1;
132
133 if (cachesize == 0)
134 return "";
135
136 keynote_current_session->ks_values_cache =
137 calloc(cachesize, sizeof(char));
138 if (keynote_current_session->ks_values_cache == NULL((void *)0)) {
139 keynote_errno = ERROR_MEMORY-1;
140 return NULL((void *)0);
141 }
142
143 for (len = 0, i = 0; i < keynote_current_session->ks_values_num; i++)
144 {
145 snprintf(keynote_current_session->ks_values_cache + len,
146 cachesize - len, "%s,", keynote_current_session->ks_values[i]);
147 len += strlen(keynote_current_session->ks_values[i]) + 1;
148 }
149
150 keynote_current_session->ks_values_cache[len - 1] = '\0';
151 return keynote_current_session->ks_values_cache;
152}
153
154/*
155 * Free an environment structure.
156 */
157void
158keynote_free_env(struct environment *en)
159{
160 if (en
26.1
'en' is not equal to NULL
== NULL((void *)0))
27
Taking false branch
161 return;
162
163 free(en->env_name);
164
165 if (en->env_flags & ENVIRONMENT_FLAG_REGEX0x0002)
28
Assuming the condition is false
29
Taking false branch
166 regfree(&(en->env_regex));
167
168 if (!(en->env_flags & ENVIRONMENT_FLAG_FUNC0x0001))
30
Assuming the condition is false
31
Taking false branch
169 {
170 free(en->env_value);
171 }
172 else
173 ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_CLEANUP"_KEYNOTE_CALLBACK_CLEANUP");
32
Called function pointer is null (null dereference)
174
175 free(en);
176}
177
178/*
179 * Lookup for variable "name" in the hash table. If hashsize is 1,
180 * then the second argument is actually a pointer to a list. Last
181 * argument specifies case-insensitivity.
182 */
183char *
184keynote_env_lookup(char *name, struct environment **table,
185 unsigned int hashsize)
186{
187 struct environment *en;
188
189 for (en = table[keynote_stringhash(name, hashsize)];
190 en != NULL((void *)0);
191 en = en->env_next)
192 if (((en->env_flags & ENVIRONMENT_FLAG_REGEX0x0002) &&
193 (regexec(&(en->env_regex), name, 0, NULL((void *)0), 0) == 0)) ||
194 (!strcmp(name, en->env_name)))
195 {
196 if ((en->env_flags & ENVIRONMENT_FLAG_FUNC0x0001) &&
197 (en->env_value != NULL((void *)0)))
198 return ((char * (*) (char *)) en->env_value)(name);
199 else
200 return en->env_value;
201 }
202
203 return NULL((void *)0);
204}
205
206/*
207 * Delete a variable from hash table. Return RESULT_TRUE if the deletion was
208 * successful, and RESULT_FALSE if the variable was not found.
209 */
210int
211keynote_env_delete(char *name, struct environment **table,
212 unsigned int hashsize)
213{
214 struct environment *en, *en2;
215 unsigned int h;
216
217 h = keynote_stringhash(name, hashsize);
218
219 if (table[h] != NULL((void *)0))
220 {
221 if (!strcmp(table[h]->env_name, name))
222 {
223 en = table[h];
224 table[h] = en->env_next;
225 keynote_free_env(en);
226 return RESULT_TRUE1;
227 }
228 else
229 for (en = table[h];
230 en->env_next != NULL((void *)0);
231 en = en->env_next)
232 if (!strcmp(en->env_next->env_name, name))
233 {
234 en2 = en->env_next;
235 en->env_next = en2->env_next;
236 keynote_free_env(en2);
237 return RESULT_TRUE1;
238 }
239 }
240
241 return RESULT_FALSE0;
242}
243
244/*
245 * Add a new variable in hash table. Return RESULT_TRUE on success,
246 * ERROR_MEMORY on failure. If hashsize is 1, second argument is
247 * actually a pointer to a list. The arguments are duplicated.
248 */
249int
250keynote_env_add(char *name, char *value, struct environment **table,
251 unsigned int hashsize, int flags)
252{
253 struct environment *en;
254 unsigned int h, i;
255
256 en = calloc(1, sizeof(struct environment));
257 if (en == NULL((void *)0)) {
14
Assuming 'en' is not equal to NULL
15
Taking false branch
258 keynote_errno = ERROR_MEMORY-1;
259 return -1;
260 }
261
262 en->env_name = strdup(name);
263 if (en->env_name == NULL((void *)0)) {
16
Assuming field 'env_name' is not equal to NULL
17
Taking false branch
264 keynote_free_env(en);
265 keynote_errno = ERROR_MEMORY-1;
266 return -1;
267 }
268
269 if (flags & ENVIRONMENT_FLAG_REGEX0x0002) /* Regular expression for name */
18
Taking true branch
270 {
271 if ((i = regcomp(&(en->env_regex), name, REG_EXTENDED0001)) != 0)
19
Assuming the condition is false
20
Taking false branch
272 {
273 keynote_free_env(en);
274 if (i == REG_ESPACE12)
275 keynote_errno = ERROR_MEMORY-1;
276 else
277 keynote_errno = ERROR_SYNTAX-2;
278 return -1;
279 }
280 en->env_flags |= ENVIRONMENT_FLAG_REGEX0x0002;
281 }
282
283 if (flags & ENVIRONMENT_FLAG_FUNC0x0001) /* Callback registration */
21
Assuming the condition is false
22
Taking false branch
284 {
285 en->env_value = value;
286 en->env_flags |= ENVIRONMENT_FLAG_FUNC0x0001;
287 ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_INITIALIZE"_KEYNOTE_CALLBACK_INITIALIZE");
288 if (keynote_errno != 0)
289 {
290 keynote_free_env(en);
291 return -1;
292 }
293 }
294 else
295 {
296 en->env_value = strdup(value);
23
Value assigned to field 'env_value'
297 if (en->env_value == NULL((void *)0)) {
24
Assuming field 'env_value' is equal to NULL
25
Taking true branch
298 keynote_free_env(en);
26
Calling 'keynote_free_env'
299 keynote_errno = ERROR_MEMORY-1;
300 return -1;
301 }
302 }
303
304 /*
305 * This means that new assignments of existing variable will override
306 * the old ones.
307 */
308 h = keynote_stringhash(name, hashsize);
309 en->env_next = table[h];
310 table[h] = en;
311 return RESULT_TRUE1;
312}
313
314/*
315 * Cleanup an environment table.
316 */
317void
318keynote_env_cleanup(struct environment **table, unsigned int hashsize)
319{
320 struct environment *en2;
321
322 if ((hashsize == 0) || (table == NULL((void *)0)))
323 return;
324
325 while (hashsize > 0)
326 {
327 while (table[hashsize - 1] != NULL((void *)0)) {
328 en2 = table[hashsize - 1]->env_next;
329 keynote_free_env(table[hashsize - 1]);
330 table[hashsize - 1] = en2;
331 }
332
333 hashsize--;
334 }
335}
336
337/*
338 * Zero out the attribute structures, seed the RNG.
339 */
340static int
341keynote_init_environment(void)
342{
343 memset(keynote_current_session->ks_env_table, 0,
344 HASHTABLESIZE37 * sizeof(struct environment *));
345 memset(keynote_current_session->ks_assertion_table, 0,
346 HASHTABLESIZE37 * sizeof(struct assertion *));
347 keynote_current_session->ks_env_regex = NULL((void *)0);
348
349 if (keynote_env_add("_ACTION_AUTHORIZERS",
350 (char *) keynote_get_action_authorizers,
351 keynote_current_session->ks_env_table, HASHTABLESIZE37,
352 ENVIRONMENT_FLAG_FUNC0x0001) != RESULT_TRUE1)
353 return -1;
354
355 if (keynote_env_add("_VALUES", (char *) keynote_get_values,
356 keynote_current_session->ks_env_table, HASHTABLESIZE37,
357 ENVIRONMENT_FLAG_FUNC0x0001) != RESULT_TRUE1)
358 return -1;
359
360 return RESULT_TRUE1;
361}
362
363/*
364 * Return the index of argument in keynote_values[].
365 */
366int
367keynote_retindex(char *s)
368{
369 int i;
370
371 for (i = 0; i < keynote_current_session->ks_values_num; i++)
372 if (!strcmp(s, keynote_current_session->ks_values[i]))
373 return i;
374
375 return -1;
376}
377
378/*
379 * Find a session by its id.
380 */
381struct keynote_session *
382keynote_find_session(int sessid)
383{
384 unsigned int h = sessid % SESSIONTABLESIZE37;
385 struct keynote_session *ks;
386
387 for (ks = keynote_sessions[h];
388 ks != NULL((void *)0);
389 ks = ks->ks_next)
390 if (ks->ks_id == sessid)
391 return ks;
392
393 return NULL((void *)0);
394}
395
396/*
397 * Add a session in the hash table.
398 */
399static void
400keynote_add_session(struct keynote_session *ks)
401{
402 unsigned int h = ks->ks_id % SESSIONTABLESIZE37;
403
404 ks->ks_next = keynote_sessions[h];
405 if (ks->ks_next != NULL((void *)0))
406 ks->ks_next->ks_prev = ks;
407
408 keynote_sessions[h] = ks;
409}
410
411/*
412 * Initialize a KeyNote session.
413 */
414int
415kn_init(void)
416{
417 keynote_errno = 0;
418 keynote_current_session = calloc(1, sizeof(struct keynote_session));
419 if (keynote_current_session == NULL((void *)0)) {
420 keynote_errno = ERROR_MEMORY-1;
421 return -1;
422 }
423
424 while (keynote_find_session(sessioncounter) != NULL((void *)0)) {
425 sessioncounter++;
426 if (sessioncounter < 0)
427 sessioncounter = 0;
428 }
429
430 keynote_current_session->ks_id = sessioncounter++;
431 keynote_init_environment();
432 keynote_add_session(keynote_current_session);
433 return keynote_current_session->ks_id;
434}
435
436/*
437 * Cleanup the action environment.
438 */
439int
440kn_cleanup_action_environment(int sessid)
441{
442 struct keynote_session *ks;
443
444 keynote_errno = 0;
445 if ((keynote_current_session == NULL((void *)0)) ||
446 (keynote_current_session->ks_id != sessid))
447 {
448 keynote_current_session = keynote_find_session(sessid);
449 if (keynote_current_session == NULL((void *)0)) {
450 keynote_errno = ERROR_NOTFOUND-3;
451 return -1;
452 }
453 }
454
455 ks = keynote_current_session;
456
457 /* Cleanup environment */
458 keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE37);
459 keynote_env_cleanup(&(ks->ks_env_regex), 1);
460
461 return 0;
462}
463
464/*
465 * Close a session.
466 */
467int
468kn_close(int sessid)
469{
470 struct keynote_session *ks;
471 struct assertion *as, *as2;
472 int i;
473
474 keynote_errno = 0;
475 if ((keynote_current_session == NULL((void *)0)) ||
476 (keynote_current_session->ks_id != sessid))
477 {
478 keynote_current_session = keynote_find_session(sessid);
479 if (keynote_current_session == NULL((void *)0)) {
480 keynote_errno = ERROR_NOTFOUND-3;
481 return -1;
482 }
483 }
484
485 ks = keynote_current_session;
486
487 /* Cleanup environment -- no point using kn_cleanup_action_environment() */
488 keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE37);
489 keynote_env_cleanup(&(ks->ks_env_regex), 1);
490
491 /* Cleanup assertions */
492 for (i = 0; i < HASHTABLESIZE37; i++)
493 for (as = ks->ks_assertion_table[i];
494 as != NULL((void *)0);
495 as = as2)
496 {
497 as2 = as->as_next;
498 keynote_free_assertion(as);
499 }
500
501 /* Cleanup action authorizers */
502 keynote_keylist_free(ks->ks_action_authorizers);
503
504 /* Unlink from chain */
505 if (ks->ks_prev == NULL((void *)0)) {
506 keynote_sessions[ks->ks_id % SESSIONTABLESIZE37] = ks->ks_next;
507 if (ks->ks_next != NULL((void *)0))
508 ks->ks_next->ks_prev = NULL((void *)0);
509
510 }
511 else
512 {
513 ks->ks_prev->ks_next = ks->ks_next;
514 if (ks->ks_next != NULL((void *)0))
515 ks->ks_next->ks_prev = ks->ks_prev;
516 }
517
518 free(ks);
519 keynote_current_session = NULL((void *)0);
520 return 0;
521}
522
523/*
524 * Add an action attribute.
525 */
526int
527kn_add_action(int sessid, char *name, char *value, int flags)
528{
529 int i;
530
531 keynote_errno = 0;
532 if (name == NULL((void *)0) || value == NULL((void *)0) || name[0] == '_') {
6
Assuming 'name' is not equal to NULL
7
Assuming 'value' is not equal to NULL
8
Assuming the condition is false
9
Taking false branch
533 keynote_errno = ERROR_SYNTAX-2;
534 return -1;
535 }
536
537 if (keynote_current_session
9.1
'keynote_current_session' is not equal to NULL
== NULL((void *)0) ||
10
Taking false branch
538 keynote_current_session->ks_id != sessid
9.2
'sessid' is equal to field 'ks_id'
)
539 {
540 keynote_current_session = keynote_find_session(sessid);
541 if (keynote_current_session == NULL((void *)0)) {
542 keynote_errno = ERROR_NOTFOUND-3;
543 return -1;
544 }
545 }
546
547 if (flags & ENVIRONMENT_FLAG_REGEX0x0002)
11
Assuming the condition is true
12
Taking true branch
548 i = keynote_env_add(name, value,
13
Calling 'keynote_env_add'
549 &(keynote_current_session->ks_env_regex), 1, flags);
550 else
551 i = keynote_env_add(name, value, keynote_current_session->ks_env_table,
552 HASHTABLESIZE37, flags);
553
554 if (i == RESULT_TRUE1)
555 return 0;
556 else
557 return -1;
558}
559
560/*
561 * Remove an action attribute.
562 */
563int
564kn_remove_action(int sessid, char *name)
565{
566 int i;
567
568 keynote_errno = 0;
569 if (name == NULL((void *)0) || name[0] == '_') {
570 keynote_errno = ERROR_SYNTAX-2;
571 return -1;
572 }
573
574 if (keynote_current_session == NULL((void *)0) ||
575 keynote_current_session->ks_id != sessid)
576 {
577 keynote_current_session = keynote_find_session(sessid);
578 if (keynote_current_session == NULL((void *)0)) {
579 keynote_errno = ERROR_NOTFOUND-3;
580 return -1;
581 }
582 }
583
584 i = keynote_env_delete(name, keynote_current_session->ks_env_table,
585 HASHTABLESIZE37);
586 if (i == RESULT_TRUE1)
587 return 0;
588
589 i = keynote_env_delete(name, &(keynote_current_session->ks_env_regex),
590 HASHTABLESIZE37);
591 if (i == RESULT_TRUE1)
592 return 0;
593
594 keynote_errno = ERROR_NOTFOUND-3;
595 return -1;
596}
597
598/*
599 * Execute a query.
600 */
601int
602kn_do_query(int sessid, char **returnvalues, int numvalues)
603{
604 struct assertion *as;
605 int i;
606
607 keynote_errno = 0;
608 if (keynote_current_session == NULL((void *)0) ||
609 keynote_current_session->ks_id != sessid)
610 {
611 keynote_current_session = keynote_find_session(sessid);
612 if (keynote_current_session == NULL((void *)0)) {
613 keynote_errno = ERROR_NOTFOUND-3;
614 return -1;
615 }
616 }
617
618 /* Check that we have at least one action authorizer */
619 if (keynote_current_session->ks_action_authorizers == NULL((void *)0)) {
620 keynote_errno = ERROR_NOTFOUND-3;
621 return -1;
622 }
623
624 /*
625 * We may use already set returnvalues, or use new ones,
626 * but we must have some before we can evaluate.
627 */
628 if (returnvalues == NULL((void *)0) &&
629 keynote_current_session->ks_values == NULL((void *)0))
630 {
631 keynote_errno = ERROR_SYNTAX-2;
632 return -1;
633 }
634
635 /* Replace any existing returnvalues */
636 if (returnvalues != NULL((void *)0)) {
637 keynote_current_session->ks_values = returnvalues;
638 keynote_current_session->ks_values_num = numvalues;
639 }
640
641 /* Reset assertion state from any previous queries */
642 for (i = 0; i < HASHTABLESIZE37; i++)
643 for (as = keynote_current_session->ks_assertion_table[i];
644 as != NULL((void *)0);
645 as = as->as_next)
646 {
647 as->as_kresult = KRESULT_UNTOUCHED0;
648 as->as_result = 0;
649 as->as_internalflags &= ~ASSERT_IFLAG_PROCESSED0x0010;
650 as->as_error = 0;
651 if (as->as_internalflags & ASSERT_IFLAG_WEIRDSIG0x0004)
652 as->as_sigresult = SIGRESULT_UNTOUCHED0;
653 }
654
655 return keynote_evaluate_query();
656}
657
658/*
659 * Return assertions that failed, by error type.
660 */
661int
662kn_get_failed(int sessid, int type, int num)
663{
664 struct assertion *as;
665 int i;
666
667 keynote_errno = 0;
668 if (keynote_current_session == NULL((void *)0) ||
669 keynote_current_session->ks_id != sessid)
670 {
671 keynote_current_session = keynote_find_session(sessid);
672 if (keynote_current_session == NULL((void *)0)) {
673 keynote_errno = ERROR_NOTFOUND-3;
674 return -1;
675 }
676 }
677
678 for (i = 0; i < HASHTABLESIZE37; i++)
679 for (as = keynote_current_session->ks_assertion_table[i];
680 as != NULL((void *)0);
681 as = as->as_next)
682 switch (type)
683 {
684 case KEYNOTE_ERROR_ANY0:
685 if ((as->as_error != 0) ||
686 ((as->as_sigresult != SIGRESULT_TRUE2) &&
687 !(as->as_sigresult == SIGRESULT_UNTOUCHED0) &&
688 !(as->as_flags & ASSERT_FLAG_LOCAL0x0001)))
689 if (num-- == 0) /* Return it if it's the num-th found */
690 return as->as_id;
691 break;
692
693 case KEYNOTE_ERROR_MEMORY2:
694 if (as->as_error == ERROR_MEMORY-1)
695 if (num-- == 0)
696 return as->as_id;
697 break;
698
699 case KEYNOTE_ERROR_SYNTAX1:
700 if (as->as_error == ERROR_SYNTAX-2)
701 if (num-- == 0)
702 return as->as_id;
703 break;
704
705 case KEYNOTE_ERROR_SIGNATURE3:
706 if ((as->as_sigresult != SIGRESULT_TRUE2) &&
707 !(as->as_sigresult == SIGRESULT_UNTOUCHED0) &&
708 !(as->as_flags & ASSERT_FLAG_LOCAL0x0001))
709 if (num-- == 0)
710 return as->as_id;
711 break;
712 }
713
714 keynote_errno = ERROR_NOTFOUND-3;
715 return -1;
716}
717
718/*
719 * Simple API for doing a single KeyNote query.
720 */
721int
722kn_query(struct environment *env, char **retvalues, int numval,
723 char **trusted, int *trustedlen, int numtrusted,
724 char **untrusted, int *untrustedlen, int numuntrusted,
725 char **authorizers, int numauthorizers)
726{
727 struct environment *en;
728 int sessid, i, serrno;
729
730 keynote_errno = 0;
731 if ((sessid = kn_init()) == -1)
1
Assuming the condition is false
2
Taking false branch
732 return -1;
733
734 /* Action set */
735 for (en = env; en != NULL((void *)0); en = en->env_next)
3
Assuming 'en' is not equal to NULL
4
Loop condition is true. Entering loop body
736 if (kn_add_action(sessid, en->env_name, en->env_value,
5
Calling 'kn_add_action'
737 en->env_flags) == -1)
738 {
739 serrno = keynote_errno;
740 kn_close(sessid);
741 keynote_errno = serrno;
742 return -1;
743 }
744
745 /* Locally trusted assertions */
746 for (i = 0; i < numtrusted; i++)
747 if ((kn_add_assertion(sessid, trusted[i], trustedlen[i],
748 ASSERT_FLAG_LOCAL0x0001) == -1) && (keynote_errno == ERROR_MEMORY-1))
749 {
750 serrno = keynote_errno;
751 kn_close(sessid);
752 keynote_errno = serrno;
753 return -1;
754 }
755
756 /* Untrusted assertions */
757 for (i = 0; i < numuntrusted; i++)
758 if ((kn_add_assertion(sessid, untrusted[i], untrustedlen[i], 0) == -1)
759 && (keynote_errno == ERROR_MEMORY-1))
760 {
761 serrno = keynote_errno;
762 kn_close(sessid);
763 keynote_errno = serrno;
764 return -1;
765 }
766
767 /* Authorizers */
768 for (i = 0; i < numauthorizers; i++)
769 if (kn_add_authorizer(sessid, authorizers[i]) == -1)
770 {
771 serrno = keynote_errno;
772 kn_close(sessid);
773 keynote_errno = serrno;
774 return -1;
775 }
776
777 i = kn_do_query(sessid, retvalues, numval);
778 serrno = keynote_errno;
779 kn_close(sessid);
780
781 if (serrno)
782 keynote_errno = serrno;
783
784 return i;
785}
786
787/*
788 * Read a buffer, break it up in assertions.
789 */
790char **
791kn_read_asserts(char *buffer, int bufferlen, int *numassertions)
792{
793 int bufsize = 32, i, flag, valid;
794 char **buf, **tempbuf, *ptr;
795
796 keynote_errno = 0;
797 if (buffer == NULL((void *)0)) {
798 keynote_errno = ERROR_SYNTAX-2;
799 return NULL((void *)0);
800 }
801
802 if ((buf = calloc(bufsize, sizeof(char *))) == NULL((void *)0)) {
803 keynote_errno = ERROR_MEMORY-1;
804 return NULL((void *)0);
805 }
806
807 /*
808 * We'll go through the whole buffer looking for consecutive newlines,
809 * which imply newline separation. We use the valid flag to keep
810 * track of whether there may be an assertion after the last pair of
811 * newlines, or whether there may be an assertion in the buffer to
812 * begin with, if there are no consecutive newlines.
813 */
814 for (i = 0, flag = 0, valid = 0, *numassertions = 0, ptr = buffer;
815 i < bufferlen;
816 i++)
817 {
818 if (buffer[i] == '\n')
819 {
820 if (flag) /* Two newlines in a row, copy if there's anything */
821 {
822 if (valid) /* Something there */
823 {
824 /* Allocate enough memory */
825 buf[*numassertions] = calloc((buffer + i) - ptr
826 + 1, sizeof(char));
827 if (buf[*numassertions] == NULL((void *)0)) {
828 /* Free any already-allocated strings */
829 for (flag = 0; flag < *numassertions; flag++)
830 free(buf[flag]);
831 free(buf);
832 keynote_errno = ERROR_MEMORY-1;
833 return NULL((void *)0);
834 }
835
836 /* Copy string */
837 memcpy(buf[*numassertions], ptr, (buffer + i) - ptr);
838 (*numassertions)++;
839 }
840
841 valid = 0; /* Reset */
842 flag = 0;
843 ptr = buffer + i + 1; /* Point right after this newline */
844
845 /* See if we need to resize the buffer */
846 if (*numassertions > bufsize - 4)
847 {
848 /* Allocate twice the space */
849 tempbuf = reallocarray(buf, bufsize, 2 * sizeof(char *));
850 if (tempbuf == NULL((void *)0)) {
851 for (flag = 0; flag < *numassertions; flag++)
852 free(buf[flag]);
853 free(buf);
854 keynote_errno = ERROR_MEMORY-1;
855 return NULL((void *)0);
856 }
857
858 buf = tempbuf;
859 bufsize *= 2;
860 }
861 }
862 else
863 flag = 1; /* One newline so far */
864
865 continue;
866 }
867 else
868 flag = 0;
869
870 if (!isspace((unsigned char)buffer[i]))
871 valid = 1;
872 }
873
874 /*
875 * There may be a valid assertion after the last pair of newlines.
876 * Notice that because of the resizing check above, there will be
877 * a valid memory location to store this last string.
878 */
879 if (valid)
880 {
881 /* This one's easy, we can just use strdup() */
882 if ((buf[*numassertions] = strdup(ptr)) == NULL((void *)0)) {
883 for (flag = 0; flag < *numassertions; flag++)
884 free(buf[flag]);
885 free(buf);
886 keynote_errno = ERROR_MEMORY-1;
887 return NULL((void *)0);
888 }
889 (*numassertions)++;
890 }
891
892 return buf;
893}
894
895/*
896 * Return the authorizer key for a given assertion.
897 */
898void *
899kn_get_authorizer(int sessid, int assertid, int *algorithm)
900{
901 struct assertion *as;
902 int i;
903
904 keynote_errno = *algorithm = 0;
905 if (keynote_current_session == NULL((void *)0) ||
906 keynote_current_session->ks_id != sessid)
907 {
908 keynote_current_session = keynote_find_session(sessid);
909 if (keynote_current_session == NULL((void *)0)) {
910 keynote_errno = ERROR_NOTFOUND-3;
911 return NULL((void *)0);
912 }
913 }
914
915 /* Traverse the hash table looking for assertid */
916 for (i = 0; i < HASHTABLESIZE37; i++)
917 for (as = keynote_current_session->ks_assertion_table[i];
918 as != NULL((void *)0);
919 as = as->as_next)
920 if (as->as_id == assertid)
921 goto out;
922
923 out:
924 if (as == NULL((void *)0)) {
925 keynote_errno = ERROR_NOTFOUND-3;
926 return NULL((void *)0);
927 }
928
929 if (as->as_authorizer == NULL((void *)0))
930 if (keynote_evaluate_authorizer(as, 1) != RESULT_TRUE1)
931 return NULL((void *)0);
932
933 *algorithm = as->as_signeralgorithm;
934 return as->as_authorizer;
935}
936
937/*
938 * Return the licensees for a given assertion.
939 */
940struct keynote_keylist *
941kn_get_licensees(int sessid, int assertid)
942{
943 struct assertion *as;
944 int i;
945
946 keynote_errno = 0;
947 if (keynote_current_session == NULL((void *)0) ||
948 keynote_current_session->ks_id != sessid)
949 {
950 keynote_current_session = keynote_find_session(sessid);
951 if (keynote_current_session == NULL((void *)0)) {
952 keynote_errno = ERROR_NOTFOUND-3;
953 return NULL((void *)0);
954 }
955 }
956
957 /* Traverse the hash table looking for assertid */
958 for (i = 0; i < HASHTABLESIZE37; i++)
959 for (as = keynote_current_session->ks_assertion_table[i];
960 as != NULL((void *)0);
961 as = as->as_next)
962 if (as->as_id == assertid)
963 goto out;
964
965 out:
966 if (as == NULL((void *)0)) {
967 keynote_errno = ERROR_NOTFOUND-3;
968 return NULL((void *)0);
969 }
970
971 if (as->as_keylist == NULL((void *)0))
972 if (keynote_parse_keypred(as, 1) != RESULT_TRUE1)
973 return NULL((void *)0);
974
975 return (struct keynote_keylist *) as->as_keylist;
976}