Annotation of embedaddon/strongswan/src/libimcv/plugins/imv_attestation/attest.c, revision 1.1.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>