ipsec attest lists data stored in an attestation database
[strongswan.git] / src / libimcv / plugins / imv_attestation / attest.c
1 /*
2 * Copyright (C) 2011 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
23 #include <debug.h>
24 #include <library.h>
25
26 #include "attest_usage.h"
27
28 /**
29 * global database handle
30 */
31 database_t *db;
32
33 /**
34 * forward declarations
35 */
36 static void do_args(int argc, char *argv[]);
37
38 /**
39 * ipsec attest --files - show files
40 */
41 static void list_files(char *product, int pid)
42 {
43 enumerator_t *e;
44 char *file;
45 bool select = TRUE;
46 int fid, is_dir, count = 0;
47
48 if (pid)
49 {
50 e = db->query(db,
51 "SELECT name FROM products WHERE id = ?",
52 DB_INT, pid, DB_TEXT);
53 if (e)
54 {
55 if (e->enumerate(e, &product))
56 {
57 product = strdup(product);
58 e->destroy(e);
59 }
60 else
61 {
62 printf("no product found with pid %d\n", pid);
63 e->destroy(e);
64 return;
65 }
66 }
67 e = db->query(db,
68 "SELECT f.id, f.type, f.path FROM files AS f "
69 "JOIN product_file AS pf ON f.id = pf.file "
70 "JOIN products AS p ON p.id = pf.product "
71 "WHERE p.id = ? ORDER BY f.path",
72 DB_INT, pid, DB_INT, DB_INT, DB_TEXT);
73 }
74 else if (!product || *product == '\0')
75 {
76 select = FALSE;
77 e = db->query(db,
78 "SELECT id, type, path FROM files "
79 "ORDER BY path",
80 DB_INT, DB_INT, DB_TEXT);
81 }
82 else
83 {
84 e = db->query(db,
85 "SELECT f.id, f.type, f.path FROM files AS f "
86 "JOIN product_file AS pf ON f.id = pf.file "
87 "JOIN products AS p ON p.id = pf.product "
88 "WHERE p.name = ? ORDER BY f.path",
89 DB_TEXT, product, DB_INT, DB_INT, DB_TEXT);
90 }
91 if (e)
92 {
93 while (e->enumerate(e, &fid, &is_dir, &file))
94 {
95 printf("%3d: %s %s\n", fid, is_dir ? "d":"f", file);
96 count++;
97 }
98 e->destroy(e);
99
100 printf("%d file%s found", count, (count == 1) ? "" : "s");
101 if (select)
102 {
103 printf(" for product '%s'", product);
104 }
105 printf("\n");
106 if (pid)
107 {
108 free(product);
109 }
110 }
111 }
112
113 /**
114 * ipsec attest --products - show products
115 */
116 static void list_products(char *file, int fid)
117 {
118 enumerator_t *e;
119 char *product;
120 bool select = TRUE;
121 int pid, count = 0;
122
123 if (fid)
124 {
125 e = db->query(db,
126 "SELECT path FROM files WHERE id = ?",
127 DB_INT, fid, DB_TEXT);
128 if (e)
129 {
130 if (e->enumerate(e, &file))
131 {
132 file = strdup(file);
133 e->destroy(e);
134 }
135 else
136 {
137 printf("no file found with fid %d\n", fid);
138 e->destroy(e);
139 return;
140 }
141 }
142 e = db->query(db,
143 "SELECT p.id, p.name FROM products AS p "
144 "JOIN product_file AS pf ON p.id = pf.product "
145 "JOIN files AS f ON f.id = pf.file "
146 "WHERE f.id = ? ORDER BY p.name",
147 DB_INT, fid, DB_INT, DB_TEXT);
148 }
149 else if (!file || *file == '\0')
150 {
151 select = FALSE;
152 e = db->query(db, "SELECT id, name FROM products "
153 "ORDER BY name",
154 DB_INT, DB_TEXT);
155 }
156 else
157 {
158 e = db->query(db,
159 "SELECT p.id, p.name FROM products AS p "
160 "JOIN product_file AS pf ON p.id = pf.product "
161 "JOIN files AS f ON f.id = pf.file "
162 "WHERE f.path = ? ORDER BY p.name",
163 DB_TEXT, file, DB_INT, DB_TEXT);
164 }
165 if (e)
166 {
167 while (e->enumerate(e, &pid, &product))
168 {
169 printf("%3d: %s\n", pid, product);
170 count++;
171 }
172 e->destroy(e);
173
174 printf("%d product%s found", count, (count == 1) ? "" : "s");
175 if (select)
176 {
177 printf(" for file '%s'", file);
178 }
179 printf("\n");
180 if (fid)
181 {
182 free(file);
183 }
184 }
185 }
186
187 /**
188 * atexit handler to close db on shutdown
189 */
190 static void cleanup(void)
191 {
192 db->destroy(db);
193 }
194
195 static void do_args(int argc, char *argv[])
196 {
197 char *product = NULL, *file = NULL;
198 int fid = 0, pid = 0;
199
200 enum {
201 OP_UNDEF,
202 OP_USAGE,
203 OP_PRODUCTS,
204 OP_FILES,
205 } operation = OP_UNDEF;
206
207 /* reinit getopt state */
208 optind = 0;
209
210 while (TRUE)
211 {
212 int c;
213
214 struct option long_opts[] = {
215 { "help", no_argument, NULL, 'h' },
216 { "files", no_argument, NULL, 'f' },
217 { "products", no_argument, NULL, 'p' },
218 { "file", required_argument, NULL, 'F' },
219 { "product", required_argument, NULL, 'P' },
220 { "fid", required_argument, NULL, '1' },
221 { "pid", required_argument, NULL, '2' },
222 { 0,0,0,0 }
223 };
224
225 c = getopt_long(argc, argv, "", long_opts, NULL);
226 switch (c)
227 {
228 case EOF:
229 break;
230 case 'h':
231 operation = OP_USAGE;
232 break;
233 case 'f':
234 operation = OP_FILES;
235 continue;
236 case 'p':
237 operation = OP_PRODUCTS;
238 continue;
239 case 'F':
240 file = optarg;
241 continue;
242 case 'P':
243 product = optarg;
244 continue;
245 case '1':
246 fid = atoi(optarg);
247 continue;
248 case '2':
249 pid = atoi(optarg);
250 continue;
251 }
252 break;
253 }
254
255 switch (operation)
256 {
257 case OP_USAGE:
258 usage();
259 break;
260 case OP_PRODUCTS:
261 list_products(file, fid);
262 break;
263 case OP_FILES:
264 list_files(product, pid);
265 break;
266 default:
267 usage();
268 exit(EXIT_FAILURE);
269 }
270 }
271
272 int main(int argc, char *argv[])
273 {
274 char *uri;
275
276 atexit(library_deinit);
277
278 /* initialize library */
279 if (!library_init(NULL))
280 {
281 exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
282 }
283 if (!lib->plugins->load(lib->plugins, NULL,
284 lib->settings->get_str(lib->settings, "attest.load", "sqlite")))
285 {
286 exit(SS_RC_INITIALIZATION_FAILED);
287 }
288
289 uri = lib->settings->get_str(lib->settings, "attest.database", NULL);
290 if (!uri)
291 {
292 fprintf(stderr, "database URI attest.database not set.\n");
293 exit(SS_RC_INITIALIZATION_FAILED);
294 }
295 db = lib->db->create(lib->db, uri);
296 if (!db)
297 {
298 fprintf(stderr, "opening database failed.\n");
299 exit(SS_RC_INITIALIZATION_FAILED);
300 }
301 atexit(cleanup);
302
303 do_args(argc, argv);
304
305 exit(EXIT_SUCCESS);
306 }
307