Annotation of embedaddon/strongswan/src/libimcv/plugins/imv_attestation/attest.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2011-2014 Andreas Steffen
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #define _GNU_SOURCE
! 17: #include <getopt.h>
! 18: #include <unistd.h>
! 19: #include <stdio.h>
! 20: #include <string.h>
! 21: #include <errno.h>
! 22: #include <libgen.h>
! 23: #ifdef HAVE_SYSLOG
! 24: # include <syslog.h>
! 25: #endif
! 26:
! 27: #include <library.h>
! 28: #include <utils/debug.h>
! 29:
! 30: #include <imcv.h>
! 31: #include <pts/pts_meas_algo.h>
! 32:
! 33: #include "attest_db.h"
! 34: #include "attest_usage.h"
! 35:
! 36: /**
! 37: * global debug output variables
! 38: */
! 39: static int debug_level = 1;
! 40: static bool stderr_quiet = TRUE;
! 41:
! 42: /**
! 43: * attest dbg function
! 44: */
! 45: static void attest_dbg(debug_t group, level_t level, char *fmt, ...)
! 46: {
! 47: va_list args;
! 48:
! 49: if (level <= debug_level)
! 50: {
! 51: if (!stderr_quiet)
! 52: {
! 53: va_start(args, fmt);
! 54: vfprintf(stderr, fmt, args);
! 55: fprintf(stderr, "\n");
! 56: va_end(args);
! 57: }
! 58:
! 59: #ifdef HAVE_SYSLOG
! 60: {
! 61: int priority = LOG_INFO;
! 62: char buffer[8192];
! 63: char *current = buffer, *next;
! 64:
! 65: /* write in memory buffer first */
! 66: va_start(args, fmt);
! 67: vsnprintf(buffer, sizeof(buffer), fmt, args);
! 68: va_end(args);
! 69:
! 70: /* do a syslog with every line */
! 71: while (current)
! 72: {
! 73: next = strchr(current, '\n');
! 74: if (next)
! 75: {
! 76: *(next++) = '\0';
! 77: }
! 78: syslog(priority, "%s\n", current);
! 79: current = next;
! 80: }
! 81: }
! 82: #endif /* HAVE_SYSLOG */
! 83: }
! 84: }
! 85:
! 86: /**
! 87: * global attestation database object
! 88: */
! 89: attest_db_t *attest;
! 90:
! 91:
! 92: /**
! 93: * atexit handler to close db on shutdown
! 94: */
! 95: static void cleanup(void)
! 96: {
! 97: attest->destroy(attest);
! 98: libimcv_deinit();
! 99: #ifdef HAVE_SYSLOG
! 100: closelog();
! 101: #endif
! 102: }
! 103:
! 104: static void do_args(int argc, char *argv[])
! 105: {
! 106: enum {
! 107: OP_UNDEF,
! 108: OP_USAGE,
! 109: OP_KEYS,
! 110: OP_COMPONENTS,
! 111: OP_DEVICES,
! 112: OP_DIRECTORIES,
! 113: OP_FILES,
! 114: OP_HASHES,
! 115: OP_MEASUREMENTS,
! 116: OP_PACKAGES,
! 117: OP_PRODUCTS,
! 118: OP_SESSIONS,
! 119: OP_ADD,
! 120: OP_DEL,
! 121: } op = OP_UNDEF;
! 122:
! 123: /* reinit getopt state */
! 124: optind = 0;
! 125:
! 126: while (TRUE)
! 127: {
! 128: int c;
! 129:
! 130: struct option long_opts[] = {
! 131: { "help", no_argument, NULL, 'h' },
! 132: { "components", no_argument, NULL, 'c' },
! 133: { "devices", no_argument, NULL, 'e' },
! 134: { "directories", no_argument, NULL, 'd' },
! 135: { "dirs", no_argument, NULL, 'd' },
! 136: { "files", no_argument, NULL, 'f' },
! 137: { "keys", no_argument, NULL, 'k' },
! 138: { "packages", no_argument, NULL, 'g' },
! 139: { "products", no_argument, NULL, 'p' },
! 140: { "hashes", no_argument, NULL, 'H' },
! 141: { "measurements", no_argument, NULL, 'm' },
! 142: { "sessions", no_argument, NULL, 's' },
! 143: { "add", no_argument, NULL, 'a' },
! 144: { "delete", no_argument, NULL, 'r' },
! 145: { "del", no_argument, NULL, 'r' },
! 146: { "remove", no_argument, NULL, 'r' },
! 147: { "aik", required_argument, NULL, 'A' },
! 148: { "blacklist", no_argument, NULL, 'B' },
! 149: { "component", required_argument, NULL, 'C' },
! 150: { "comp", required_argument, NULL, 'C' },
! 151: { "directory", required_argument, NULL, 'D' },
! 152: { "dir", required_argument, NULL, 'D' },
! 153: { "file", required_argument, NULL, 'F' },
! 154: { "package", required_argument, NULL, 'G' },
! 155: { "key", required_argument, NULL, 'K' },
! 156: { "measdir", required_argument, NULL, 'M' },
! 157: { "owner", required_argument, NULL, 'O' },
! 158: { "product", required_argument, NULL, 'P' },
! 159: { "relative", no_argument, NULL, 'R' },
! 160: { "rel", no_argument, NULL, 'R' },
! 161: { "sequence", required_argument, NULL, 'S' },
! 162: { "seq", required_argument, NULL, 'S' },
! 163: { "utc", no_argument, NULL, 'U' },
! 164: { "version", required_argument, NULL, 'V' },
! 165: { "security", no_argument, NULL, 'Y' },
! 166: { "sha1", no_argument, NULL, '1' },
! 167: { "sha256", no_argument, NULL, '2' },
! 168: { "sha384", no_argument, NULL, '3' },
! 169: { "did", required_argument, NULL, '4' },
! 170: { "fid", required_argument, NULL, '5' },
! 171: { "pid", required_argument, NULL, '6' },
! 172: { "cid", required_argument, NULL, '7' },
! 173: { "kid", required_argument, NULL, '8' },
! 174: { "gid", required_argument, NULL, '9' },
! 175: { 0,0,0,0 }
! 176: };
! 177:
! 178: c = getopt_long(argc, argv, "", long_opts, NULL);
! 179: switch (c)
! 180: {
! 181: case EOF:
! 182: break;
! 183: case 'h':
! 184: op = OP_USAGE;
! 185: break;
! 186: case 'c':
! 187: op = OP_COMPONENTS;
! 188: continue;
! 189: case 'd':
! 190: op = OP_DIRECTORIES;
! 191: continue;
! 192: case 'e':
! 193: op = OP_DEVICES;
! 194: continue;
! 195: case 'f':
! 196: op = OP_FILES;
! 197: continue;
! 198: case 'g':
! 199: op = OP_PACKAGES;
! 200: continue;
! 201: case 'k':
! 202: op = OP_KEYS;
! 203: continue;
! 204: case 'p':
! 205: op = OP_PRODUCTS;
! 206: continue;
! 207: case 'H':
! 208: op = OP_HASHES;
! 209: continue;
! 210: case 'm':
! 211: op = OP_MEASUREMENTS;
! 212: continue;
! 213: case 's':
! 214: op = OP_SESSIONS;
! 215: continue;
! 216: case 'a':
! 217: op = OP_ADD;
! 218: continue;
! 219: case 'r':
! 220: op = OP_DEL;
! 221: continue;
! 222: case 'A':
! 223: {
! 224: certificate_t *aik_cert;
! 225: public_key_t *aik_key;
! 226: chunk_t aik;
! 227:
! 228: aik_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
! 229: CERT_X509, BUILD_FROM_FILE, optarg, BUILD_END);
! 230: if (!aik_cert)
! 231: {
! 232: printf("AIK certificate '%s' could not be loaded\n", optarg);
! 233: exit(EXIT_FAILURE);
! 234: }
! 235: aik_key = aik_cert->get_public_key(aik_cert);
! 236: aik_cert->destroy(aik_cert);
! 237:
! 238: if (!aik_key)
! 239: {
! 240: printf("AIK public key could not be retrieved\n");
! 241: exit(EXIT_FAILURE);
! 242: }
! 243: if (!aik_key->get_fingerprint(aik_key, KEYID_PUBKEY_INFO_SHA1,
! 244: &aik))
! 245: {
! 246: printf("AIK fingerprint could not be computed\n");
! 247: aik_key->destroy(aik_key);
! 248: exit(EXIT_FAILURE);
! 249: }
! 250: aik = chunk_clone(aik);
! 251: aik_key->destroy(aik_key);
! 252:
! 253: if (!attest->set_key(attest, aik, op == OP_ADD))
! 254: {
! 255: exit(EXIT_FAILURE);
! 256: }
! 257: continue;
! 258: }
! 259: case 'B':
! 260: attest->set_package_state(attest, OS_PACKAGE_STATE_BLACKLIST);
! 261: continue;
! 262: case 'C':
! 263: if (!attest->set_component(attest, optarg, op == OP_ADD))
! 264: {
! 265: exit(EXIT_FAILURE);
! 266: }
! 267: continue;
! 268: case 'D':
! 269: if (!attest->set_directory(attest, optarg, op == OP_ADD))
! 270: {
! 271: exit(EXIT_FAILURE);
! 272: }
! 273: continue;
! 274: case 'F':
! 275: {
! 276: char *dir = path_dirname(optarg);
! 277: char *file = path_basename(optarg);
! 278:
! 279: if (*dir != '.')
! 280: {
! 281: if (!attest->set_directory(attest, dir, op == OP_ADD))
! 282: {
! 283: free(file);
! 284: free(dir);
! 285: exit(EXIT_FAILURE);
! 286: }
! 287: }
! 288: free(dir);
! 289:
! 290: if (!attest->set_file(attest, file, op == OP_ADD))
! 291: {
! 292: free(file);
! 293: exit(EXIT_FAILURE);
! 294: }
! 295: free(file);
! 296: continue;
! 297: }
! 298: case 'G':
! 299: if (!attest->set_package(attest, optarg, op == OP_ADD))
! 300: {
! 301: exit(EXIT_FAILURE);
! 302: }
! 303: continue;
! 304: case 'K':
! 305: {
! 306: chunk_t aik;
! 307:
! 308: aik = chunk_from_hex(chunk_create(optarg, strlen(optarg)), NULL);
! 309: if (!attest->set_key(attest, aik, op == OP_ADD))
! 310: {
! 311: exit(EXIT_FAILURE);
! 312: }
! 313: continue;
! 314: }
! 315: case 'M':
! 316: if (!attest->set_meas_directory(attest, optarg))
! 317: {
! 318: exit(EXIT_FAILURE);
! 319: }
! 320: continue;
! 321: case 'O':
! 322: attest->set_owner(attest, optarg);
! 323: continue;
! 324: case 'P':
! 325: if (!attest->set_product(attest, optarg, op == OP_ADD))
! 326: {
! 327: exit(EXIT_FAILURE);
! 328: }
! 329: continue;
! 330: case 'R':
! 331: attest->set_relative(attest);
! 332: continue;
! 333: case 'S':
! 334: attest->set_sequence(attest, atoi(optarg));
! 335: continue;
! 336: case 'U':
! 337: attest->set_utc(attest);
! 338: continue;
! 339: case 'V':
! 340: if (!attest->set_version(attest, optarg))
! 341: {
! 342: exit(EXIT_FAILURE);
! 343: }
! 344: continue;
! 345: case 'Y':
! 346: attest->set_package_state(attest, OS_PACKAGE_STATE_SECURITY);
! 347: continue;
! 348: case '1':
! 349: attest->set_algo(attest, PTS_MEAS_ALGO_SHA1);
! 350: continue;
! 351: case '2':
! 352: attest->set_algo(attest, PTS_MEAS_ALGO_SHA256);
! 353: continue;
! 354: case '3':
! 355: attest->set_algo(attest, PTS_MEAS_ALGO_SHA384);
! 356: continue;
! 357: case '4':
! 358: if (!attest->set_did(attest, atoi(optarg)))
! 359: {
! 360: exit(EXIT_FAILURE);
! 361: }
! 362: continue;
! 363: case '5':
! 364: if (!attest->set_fid(attest, atoi(optarg)))
! 365: {
! 366: exit(EXIT_FAILURE);
! 367: }
! 368: continue;
! 369: case '6':
! 370: if (!attest->set_pid(attest, atoi(optarg)))
! 371: {
! 372: exit(EXIT_FAILURE);
! 373: }
! 374: continue;
! 375: case '7':
! 376: if (!attest->set_cid(attest, atoi(optarg)))
! 377: {
! 378: exit(EXIT_FAILURE);
! 379: }
! 380: continue;
! 381: case '8':
! 382: if (!attest->set_kid(attest, atoi(optarg)))
! 383: {
! 384: exit(EXIT_FAILURE);
! 385: }
! 386: continue;
! 387: case '9':
! 388: if (!attest->set_gid(attest, atoi(optarg)))
! 389: {
! 390: exit(EXIT_FAILURE);
! 391: }
! 392: continue;
! 393: }
! 394: break;
! 395: }
! 396:
! 397: switch (op)
! 398: {
! 399: case OP_USAGE:
! 400: usage();
! 401: break;
! 402: case OP_PACKAGES:
! 403: attest->list_packages(attest);
! 404: break;
! 405: case OP_PRODUCTS:
! 406: attest->list_products(attest);
! 407: break;
! 408: case OP_KEYS:
! 409: attest->list_keys(attest);
! 410: break;
! 411: case OP_COMPONENTS:
! 412: attest->list_components(attest);
! 413: break;
! 414: case OP_DEVICES:
! 415: attest->list_devices(attest);
! 416: break;
! 417: case OP_DIRECTORIES:
! 418: attest->list_directories(attest);
! 419: break;
! 420: case OP_FILES:
! 421: attest->list_files(attest);
! 422: break;
! 423: case OP_HASHES:
! 424: attest->list_hashes(attest);
! 425: break;
! 426: case OP_MEASUREMENTS:
! 427: attest->list_measurements(attest);
! 428: break;
! 429: case OP_SESSIONS:
! 430: attest->list_sessions(attest);
! 431: break;
! 432: case OP_ADD:
! 433: attest->add(attest);
! 434: break;
! 435: case OP_DEL:
! 436: attest->delete(attest);
! 437: break;
! 438: default:
! 439: usage();
! 440: exit(EXIT_FAILURE);
! 441: }
! 442: }
! 443:
! 444: int main(int argc, char *argv[])
! 445: {
! 446: char *uri;
! 447:
! 448: /* enable attest debugging hook */
! 449: dbg = attest_dbg;
! 450: #ifdef HAVE_SYSLOG
! 451: openlog("attest", 0, LOG_DEBUG);
! 452: #endif
! 453:
! 454: atexit(library_deinit);
! 455:
! 456: /* initialize library */
! 457: if (!library_init(NULL, "attest"))
! 458: {
! 459: exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
! 460: }
! 461: if (!lib->plugins->load(lib->plugins,
! 462: lib->settings->get_str(lib->settings, "attest.load", PLUGINS)))
! 463: {
! 464: exit(SS_RC_INITIALIZATION_FAILED);
! 465: }
! 466:
! 467: uri = lib->settings->get_str(lib->settings, "attest.database", NULL);
! 468: if (!uri)
! 469: {
! 470: fprintf(stderr, "database URI attest.database not set.\n");
! 471: exit(SS_RC_INITIALIZATION_FAILED);
! 472: }
! 473: attest = attest_db_create(uri);
! 474: if (!attest)
! 475: {
! 476: exit(SS_RC_INITIALIZATION_FAILED);
! 477: }
! 478: atexit(cleanup);
! 479: libimcv_init(FALSE);
! 480:
! 481: do_args(argc, argv);
! 482:
! 483: exit(EXIT_SUCCESS);
! 484: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>