1 /*
2 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
3 *
4 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
5 * in April-May 1998
6 *
7 * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
8 *
9 * Permission to use, copy, and modify this software without fee
10 * is hereby granted, provided that this entire notice is included in
11 * all copies of any software which is or includes a copy or
12 * modification of this software.
13 *
14 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
16 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
17 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
18 * PURPOSE.
19 */
20
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <ctype.h>
30
31 #if STDC_HEADERS
32 #include <string.h>
33 #if !defined(HAVE_MEMCPY)
34 #define memcpy(d, s, n) bcopy ((s), (d), (n))
35 #endif /* !HAVE_MEMCPY */
36 #endif /* STDC_HEADERS */
37
38 #if HAVE_MEMORY_H
39 #include <memory.h>
40 #endif /* HAVE_MEMORY_H */
41
42 #if HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif /* HAVE_FCNTL_H */
45
46 #if !defined(HAVE_GETOPT)
47 #include <getopt.h>
48 #endif /* HAVE_GETOPT */
49
50 #if HAVE_IO_H
51 #include <io.h>
52 #elif HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif /* HAVE_IO_H */
55
56 #include "header.h"
57 #include "keynote.h"
58
59 void
verifyusage(void)60 verifyusage(void)
61 {
62 fprintf(stderr, "Arguments:\n");
63 fprintf(stderr, "\t-h: This message\n");
64 fprintf(stderr,
65 "\t-r <valuelist>: Comma separated, ordered return-value list\n");
66 fprintf(stderr, "\t-e <filename>: Environment settings\n");
67 fprintf(stderr, "\t-l <filename>: Trusted (local) assertion\n");
68 fprintf(stderr, "\t-k <filename>: File containing key\n");
69 fprintf(stderr, "Followed by a list of:\n");
70 fprintf(stderr, "\t<filename>: Non-local assertion\n");
71 }
72
73 void
keynote_verify(int argc,char * argv[])74 keynote_verify(int argc, char *argv[])
75 {
76 #ifdef LoopTesting
77 int loopvar = 1000;
78 #endif /* LoopTesting */
79 int fd, i, ch, se = 0, cl = 8192, sk = 0, sl = 0, p, ac = argc;
80 char *buf, **av = argv, **retv, **foov, *ptr;
81 int numretv = 16, numret = 0, sn;
82 struct stat sb;
83
84 if (argc == 1)
85 {
86 verifyusage();
87 exit(-1);
88 }
89
90 if ((buf = (char *) calloc(cl, sizeof(char))) == (char *) NULL)
91 {
92 perror("calloc()");
93 exit(-1);
94 }
95
96 #ifdef LoopTesting
97 while(loopvar--) {
98 #endif /* LoopTesting */
99
100 if ((retv = (char **) calloc(numretv, sizeof(char *))) == (char **) NULL)
101 {
102 perror("calloc()");
103 exit(-1);
104 }
105
106 /* "ac" and "av" are used for stress-testing, ignore otherwise */
107 argv = av;
108 argc = ac;
109 sn = 0;
110 opterr = 0;
111
112 sessid = kn_init();
113 if (sessid == -1)
114 {
115 fprintf(stderr, "kn_init() failed (errno %d).\n", keynote_errno);
116 exit(keynote_errno);
117 }
118
119 while ((ch = getopt(argc, argv, "hqistl:e:k:r:")) != -1)
120 {
121 switch (ch)
122 {
123 case 'e':
124 if (read_environment(optarg) == -1)
125 exit(-1);
126 se = 1;
127 break;
128
129 case 'k':
130 sk = 1;
131
132 if ((fd = open(optarg, O_RDONLY, 0)) < 0)
133 {
134 perror(optarg);
135 exit(-1);
136 }
137
138 if (fstat(fd, &sb) < 0)
139 {
140 perror("fstat()");
141 exit(-1);
142 }
143
144 if (sb.st_size > cl - 1)
145 {
146 free(buf);
147 cl = sb.st_size + 1;
148 buf = (char *) calloc(cl, sizeof(char));
149 if (buf == (char *) NULL)
150 {
151 perror("calloc()");
152 exit(-1);
153 }
154 }
155
156 i = read(fd, buf, sb.st_size);
157 if (i < 0)
158 {
159 perror("read()");
160 exit(-1);
161 }
162
163 close(fd);
164
165 parse_key(buf);
166 switch (keynote_errno)
167 {
168 case 0: /* No errors */
169 break;
170
171 case ERROR_SYNTAX:
172 fprintf(stderr, "Syntax error adding authorizer "
173 "%s\n", optarg);
174 exit(-1);
175
176 case ERROR_MEMORY:
177 perror("Out of memory.\n");
178 exit(-1);
179
180 default:
181 fprintf(stderr, "Unknown error (%d).\n",
182 keynote_errno);
183 }
184
185 break;
186
187 case 'h':
188 verifyusage();
189 exit(0);
190
191 case 'r':
192 if (sn != 0)
193 {
194 fprintf(stderr,
195 "Do not define two sets of return values.\n");
196 exit(-1);
197 }
198
199 sn = 1;
200
201 for (numret = 0;
202 (ptr = index(optarg, ',')) != (char *) NULL;
203 numret++)
204 {
205 /* Running out of memory */
206 if (numret > numretv - 3)
207 {
208 numretv *= 2;
209 foov = (char **) calloc(numretv, sizeof(char **));
210 if (foov == (char **) NULL)
211 {
212 /*
213 * If this were a real program, we 'd be freeing
214 * retv here. Since we're exiting, we can be a
215 * little sloppy.
216 */
217 perror("calloc()");
218 exit(-1);
219 }
220
221 memcpy(foov, retv, numretv * sizeof(char **));
222 free(retv);
223 retv = foov;
224 }
225
226 retv[numret] = (char *) calloc((ptr - optarg) + 1,
227 sizeof(char));
228 if (retv[numret] == (char *) NULL)
229 {
230 /* Comment from above applies here as well */
231 perror("calloc()");
232 exit(-1);
233 }
234
235 /* Copy */
236 memcpy(retv[numret], optarg, ptr - optarg);
237 optarg = ptr + 1;
238 }
239
240 /* Last component */
241 retv[numret] = (char *) strdup(optarg);
242 if (retv[numret] == (char *) NULL)
243 {
244 perror("calloc()");
245 exit(-1);
246 }
247
248 numret++;
249 break;
250
251 case 'l':
252 if ((fd = open(optarg, O_RDONLY, 0)) < 0)
253 {
254 perror(optarg);
255 exit(-1);
256 }
257
258 if (fstat(fd, &sb) < 0)
259 {
260 perror("fstat()");
261 exit(-1);
262 }
263
264 if (sb.st_size > cl - 1)
265 {
266 free(buf);
267 cl = sb.st_size + 1;
268 buf = (char *) calloc(cl, sizeof(char));
269 if (buf == (char *) NULL)
270 {
271 perror("calloc()");
272 exit(-1);
273 }
274 }
275
276 i = read(fd, buf, sb.st_size);
277 if (i < 0)
278 {
279 perror("read()");
280 exit(-1);
281 }
282
283 close(fd);
284 p = kn_add_assertion(sessid, buf, i, ASSERT_FLAG_LOCAL);
285 if (p == -1)
286 {
287 fprintf(stderr,
288 "Error for assertion in file <%s>, errno %d.\n",
289 optarg, keynote_errno);
290 keynote_errno = 0;
291 }
292
293 memset(buf, 0, sb.st_size);
294 sl = 1;
295 break;
296
297 case '?':
298 default:
299 verifyusage();
300 exit(-1);
301 }
302 }
303
304 argc -= optind;
305 argv += optind;
306 optind = 1;
307
308 #ifdef LoopTesting
309 optreset = 1;
310 #endif /* LoopTesting */
311
312 if (sn == 0)
313 {
314 fprintf(stderr,
315 "Should set return values before evaluations begin.\n");
316 exit(-1);
317 }
318
319 if (se == 0)
320 {
321 fprintf(stderr, "Should set environment before evaluations begin.\n");
322 exit(-1);
323 }
324
325 if (sk == 0)
326 {
327 fprintf(stderr, "Should specify at least one action authorizer.\n");
328 exit(-1);
329 }
330
331 if (sl == 0)
332 {
333 fprintf(stderr,
334 "Should specify at least one trusted assertion (POLICY).\n");
335 exit(-1);
336 }
337
338 while (argc--)
339 {
340 if ((fd = open(argv[argc], O_RDONLY, 0)) < 0)
341 {
342 perror(argv[argc]);
343 exit(-1);
344 }
345
346 if (fstat(fd, &sb) < 0)
347 {
348 perror("fstat()");
349 exit(-1);
350 }
351
352 if (sb.st_size > cl - 1)
353 {
354 free(buf);
355 cl = sb.st_size + 1;
356 buf = (char *) calloc(cl, sizeof(char));
357 if (buf == (char *) NULL)
358 {
359 perror("calloc()");
360 exit(-1);
361 }
362 }
363
364 i = read(fd, buf, sb.st_size);
365 if (i < 0)
366 {
367 perror("read()");
368 exit(-1);
369 }
370
371 close(fd);
372 p = kn_add_assertion(sessid, buf, i, 0);
373 if (p == -1)
374 {
375 fprintf(stderr, "Error for assertion in file <%s>, errno %d.\n",
376 argv[argc], keynote_errno);
377 keynote_errno = 0;
378 }
379
380 memset(buf, 0, sb.st_size);
381 }
382
383 p = kn_do_query(sessid, retv, numret); /* Evaluation time */
384
385 #ifndef LoopTesting
386 printf("Query result = ");
387
388 switch (keynote_errno)
389 {
390 case ERROR_MEMORY:
391 printf("<out of memory>\n");
392 exit(-1);
393
394 case ERROR_SYNTAX:
395 printf("<uninitialized authorizers or all POLICY "
396 "assertions are malformed!>\n");
397 exit(-1);
398
399 case ERROR_NOTFOUND:
400 printf("<session or other information not found!>\n");
401 exit(-1);
402
403 case 0: /* No errors */
404 break;
405
406 default:
407 printf("<should never happen (%d)!>\n", keynote_errno);
408 exit(-1);
409 }
410
411 printf("%s\n", retv[p]);
412 #endif /* LoopTesting */
413
414 keynote_errno = 0;
415
416 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_MEMORY, 0)) != -1)
417 {
418 printf("Failed assertion %d due to memory error.\n", i);
419 kn_remove_assertion(sessid, i);
420 }
421
422 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_SYNTAX, 0)) != -1)
423 {
424 printf("Failed assertion %d due to syntax or semantic error.\n", i);
425 kn_remove_assertion(sessid, i);
426 }
427
428 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_SIGNATURE, 0)) != -1)
429 {
430 printf("Failed assertion %d due to signature verification failure.\n",
431 i);
432 kn_remove_assertion(sessid, i);
433 }
434
435 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_ANY, 0)) != -1)
436 {
437 printf("Failed assertion %d due to unspecified error.\n", i);
438 kn_remove_assertion(sessid, i);
439 }
440
441 kn_close(sessid);
442
443 #ifdef LoopTesting
444 }
445 #endif /* LoopTesting */
446
447 /* This is a reminder that return values are not free'ed by KeyNote */
448 for (sn = 0; sn < numret; sn++)
449 free(retv[sn]);
450 free(retv);
451 retv = (char **) NULL;
452
453 exit(0);
454 }
455