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