add and delete components
[strongswan.git] / src / libimcv / plugins / imv_attestation / attest_db.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 #include "attest_db.h"
17
18 #include "libpts.h"
19 #include "pts/components/pts_comp_func_name.h"
20
21 typedef struct private_attest_db_t private_attest_db_t;
22
23 /**
24 * Private data of an attest_db_t object.
25 */
26 struct private_attest_db_t {
27
28 /**
29 * Public members of attest_db_state_t
30 */
31 attest_db_t public;
32
33 /**
34 * Software product to be queried
35 */
36 char *product;
37
38 /**
39 * Primary key of software product to be queried
40 */
41 int pid;
42
43 /**
44 * TRUE if product has been set
45 */
46 bool product_set;
47
48 /**
49 * Measurement file to be queried
50 */
51 char *file;
52
53 /**
54 * Primary key of measurement file to be queried
55 */
56 int fid;
57
58 /**
59 * TRUE if file has been set
60 */
61 bool file_set;
62
63 /**
64 * Directory containing the Measurement file to be queried
65 */
66 char *dir;
67
68 /**
69 * Primary key of the directory to be queried
70 */
71 int did;
72
73 /**
74 * TRUE if directory has been set
75 */
76 bool dir_set;
77
78 /**
79 * Component Functional Name to be queried
80 */
81 pts_comp_func_name_t *cfn;
82
83 /**
84 * Primary key of the Component Functional Name to be queried
85 */
86 int cid;
87
88 /**
89 * TRUE if Component Functional Name has been set
90 */
91 bool comp_set;
92
93 /**
94 * File measurement hash algorithm
95 */
96 pts_meas_algorithms_t algo;
97
98 /**
99 * Attestation database
100 */
101 database_t *db;
102
103 };
104
105 char* print_cfn(pts_comp_func_name_t *cfn)
106 {
107 static char buf[BUF_LEN];
108 char flags[8];
109 int type, vid, name, qualifier, n;
110 enum_name_t *names, *types;
111
112 vid = cfn->get_vendor_id(cfn),
113 name = cfn->get_name(cfn);
114 qualifier = cfn->get_qualifier(cfn);
115 n = snprintf(buf, BUF_LEN, "0x%06x/0x%08x-0x%02x", vid, name, qualifier);
116
117 names = pts_components->get_comp_func_names(pts_components, vid);
118 types = pts_components->get_qualifier_type_names(pts_components, vid);
119 type = pts_components->get_qualifier(pts_components, cfn, flags);
120 if (names && types)
121 {
122 n = snprintf(buf + n, BUF_LEN - n, " %N/%N [%s] %N",
123 pen_names, vid, names, name, flags, types, type);
124 }
125 return buf;
126 }
127
128 METHOD(attest_db_t, set_product, bool,
129 private_attest_db_t *this, char *product, bool create)
130 {
131 enumerator_t *e;
132
133 if (this->product_set)
134 {
135 printf("product has already been set\n");
136 return FALSE;
137 }
138 this->product = strdup(product);
139
140 e = this->db->query(this->db, "SELECT id FROM products WHERE name = ?",
141 DB_TEXT, product, DB_INT);
142 if (e)
143 {
144 if (e->enumerate(e, &this->pid))
145 {
146 this->product_set = TRUE;
147 }
148 e->destroy(e);
149 }
150 if (this->product_set)
151 {
152 return TRUE;
153 }
154
155 if (!create)
156 {
157 printf("product '%s' not found in database\n", product);
158 return FALSE;
159 }
160
161 /* Add a new database entry */
162 this->product_set = this->db->execute(this->db, &this->pid,
163 "INSERT INTO products (name) VALUES (?)",
164 DB_TEXT, product) == 1;
165
166 printf("product '%s' %sinserted into database\n", product,
167 this->product_set ? "" : "could not be ");
168
169 return this->product_set;
170 }
171
172 METHOD(attest_db_t, set_pid, bool,
173 private_attest_db_t *this, int pid)
174 {
175 enumerator_t *e;
176 char *product;
177
178 if (this->product_set)
179 {
180 printf("product has already been set\n");
181 return FALSE;
182 }
183 this->pid = pid;
184
185 e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
186 DB_INT, pid, DB_TEXT);
187 if (e)
188 {
189 if (e->enumerate(e, &product))
190 {
191 this->product = strdup(product);
192 this->product_set = TRUE;
193 }
194 else
195 {
196 printf("no product found with pid %d in database\n", pid);
197 }
198 e->destroy(e);
199 }
200 return this->product_set;
201 }
202
203 METHOD(attest_db_t, set_file, bool,
204 private_attest_db_t *this, char *file, bool create)
205 {
206 enumerator_t *e;
207
208 if (this->file_set)
209 {
210 printf("file has already been set\n");
211 return FALSE;
212 }
213 this->file = strdup(file);
214
215 e = this->db->query(this->db, "SELECT id FROM files WHERE path = ?",
216 DB_TEXT, file, DB_INT);
217 if (e)
218 {
219 if (e->enumerate(e, &this->fid))
220 {
221 this->file_set = TRUE;
222 }
223 e->destroy(e);
224 }
225 if (this->file_set)
226 {
227 return TRUE;
228 }
229
230 if (!create)
231 {
232 printf("file '%s' not found in database\n", file);
233 return FALSE;
234 }
235
236 /* Add a new database entry */
237 this->file_set = this->db->execute(this->db, &this->fid,
238 "INSERT INTO files (type, path) VALUES (0, ?)",
239 DB_TEXT, file) == 1;
240
241 printf("file '%s' %sinserted into database\n", file,
242 this->file_set ? "" : "could not be ");
243
244 return this->file_set;
245 }
246
247 METHOD(attest_db_t, set_fid, bool,
248 private_attest_db_t *this, int fid)
249 {
250 enumerator_t *e;
251 char *file;
252
253 if (this->file_set)
254 {
255 printf("file has already been set\n");
256 return FALSE;
257 }
258 this->fid = fid;
259
260 e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
261 DB_INT, fid, DB_TEXT);
262 if (e)
263 {
264 if (e->enumerate(e, &file))
265 {
266 this->file = strdup(file);
267 this->file_set = TRUE;
268 }
269 else
270 {
271 printf("no file found with fid %d\n", fid);
272 }
273 e->destroy(e);
274 }
275 return this->file_set;
276 }
277
278 METHOD(attest_db_t, set_directory, bool,
279 private_attest_db_t *this, char *dir, bool create)
280 {
281 enumerator_t *e;
282
283 if (this->dir_set)
284 {
285 printf("directory has already been set\n");
286 return FALSE;
287 }
288 free(this->dir);
289 this->dir = strdup(dir);
290
291 e = this->db->query(this->db,
292 "SELECT id FROM files WHERE type = 1 AND path = ?",
293 DB_TEXT, dir, DB_INT);
294 if (e)
295 {
296 if (e->enumerate(e, &this->did))
297 {
298 this->dir_set = TRUE;
299 }
300 e->destroy(e);
301 }
302 if (this->dir_set)
303 {
304 return TRUE;
305 }
306
307 if (!create)
308 {
309 printf("directory '%s' not found in database\n", dir);
310 return FALSE;
311 }
312
313 /* Add a new database entry */
314 this->dir_set = this->db->execute(this->db, &this->did,
315 "INSERT INTO files (type, path) VALUES (1, ?)",
316 DB_TEXT, dir) == 1;
317
318 printf("directory '%s' %sinserted into database\n", dir,
319 this->dir_set ? "" : "could not be ");
320
321 return this->dir_set;
322 }
323
324 METHOD(attest_db_t, set_did, bool,
325 private_attest_db_t *this, int did)
326 {
327 enumerator_t *e;
328 char *dir;
329
330 if (this->dir_set)
331 {
332 printf("directory has already been set\n");
333 return FALSE;
334 }
335 this->did = did;
336
337 e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
338 DB_INT, did, DB_TEXT);
339 if (e)
340 {
341 if (e->enumerate(e, &dir))
342 {
343 free(this->dir);
344 this->dir = strdup(dir);
345 this->dir_set = TRUE;
346 }
347 else
348 {
349 printf("no directory found with did %d\n", did);
350 }
351 e->destroy(e);
352 }
353 return this->dir_set;
354 }
355
356 METHOD(attest_db_t, set_component, bool,
357 private_attest_db_t *this, char *comp, bool create)
358 {
359 enumerator_t *e;
360 char *pos1, *pos2;
361 int vid, name, qualifier;
362 pts_comp_func_name_t *cfn;
363
364 if (this->comp_set)
365 {
366 printf("component has already been set\n");
367 return FALSE;
368 }
369
370 /* parse component string */
371 pos1 = strchr(comp, '/');
372 pos2 = strchr(comp, '-');
373 if (!pos1 || !pos2)
374 {
375 printf("component string must have the form \"vendor_id/name-qualifier\"\n");
376 return FALSE;
377 }
378 vid = atoi(comp);
379 name = atoi(pos1 + 1);
380 qualifier = atoi(pos2 + 1);
381 cfn = pts_comp_func_name_create(vid, name, qualifier);
382
383 e = this->db->query(this->db,
384 "SELECT id FROM components "
385 "WHERE vendor_id = ? AND name = ? AND qualifier = ?",
386 DB_INT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
387 if (e)
388 {
389 if (e->enumerate(e, &this->cid))
390 {
391 this->comp_set = TRUE;
392 this->cfn = cfn;
393 }
394 e->destroy(e);
395 }
396 if (this->comp_set)
397 {
398 return TRUE;
399 }
400
401 if (!create)
402 {
403 printf("component '%s' not found in database\n", print_cfn(cfn));
404 cfn->destroy(cfn);
405 return FALSE;
406 }
407
408 /* Add a new database entry */
409 this->comp_set = this->db->execute(this->db, &this->cid,
410 "INSERT INTO components (vendor_id, name, qualifier) "
411 "VALUES (?, ?, ?)",
412 DB_INT, vid, DB_INT, name, DB_INT, qualifier) == 1;
413
414 printf("component '%s' %sinserted into database\n", print_cfn(cfn),
415 this->comp_set ? "" : "could not be ");
416 if (this->comp_set)
417 {
418 this->cfn = cfn;
419 }
420 else
421 {
422 cfn->destroy(cfn);
423 }
424 return this->comp_set;
425 }
426
427 METHOD(attest_db_t, set_cid, bool,
428 private_attest_db_t *this, int cid)
429 {
430 enumerator_t *e;
431 int vid, name, qualifier;
432
433 if (this->comp_set)
434 {
435 printf("component has already been set\n");
436 return FALSE;
437 }
438 this->cid = cid;
439
440 e = this->db->query(this->db, "SELECT vendor_id, name, qualifier "
441 "FROM components WHERE id = ?",
442 DB_INT, cid, DB_INT, DB_INT, DB_INT);
443 if (e)
444 {
445 if (e->enumerate(e, &vid, &name, &qualifier))
446 {
447 this->cfn = pts_comp_func_name_create(vid, name, qualifier);
448 this->comp_set = TRUE;
449 }
450 else
451 {
452 printf("no component found with cid %d\n", cid);
453 }
454 e->destroy(e);
455 }
456 return this->comp_set;
457 }
458
459 METHOD(attest_db_t, set_algo, void,
460 private_attest_db_t *this, pts_meas_algorithms_t algo)
461 {
462 this->algo = algo;
463 }
464
465 METHOD(attest_db_t, list_components, void,
466 private_attest_db_t *this)
467 {
468 enumerator_t *e;
469 pts_comp_func_name_t *cfn;
470 int cid, vid, name, qualifier, count = 0;
471
472 if (this->pid)
473 {
474 e = this->db->query(this->db,
475 "SELECT c.id, c.vendor_id, c.name, c.qualifier "
476 "FROM components AS c "
477 "JOIN product_component AS pc ON c.id = pc.component "
478 "WHERE pc.product = ? ORDER BY c.vendor_id, c.name, c.qualifier",
479 DB_INT, this->pid, DB_INT, DB_INT, DB_INT, DB_INT);
480 }
481 else
482 {
483 e = this->db->query(this->db,
484 "SELECT id, vendor_id, name, qualifier FROM components "
485 "ORDER BY vendor_id, name, qualifier",
486 DB_INT, DB_INT, DB_INT, DB_INT);
487 }
488 if (e)
489 {
490 while (e->enumerate(e, &cid, &vid, &name, &qualifier))
491 {
492 cfn = pts_comp_func_name_create(vid, name, qualifier);
493 printf("%3d: %s\n", cid, print_cfn(cfn));
494 cfn->destroy(cfn);
495 count++;
496 }
497 e->destroy(e);
498
499 printf("%d component%s found", count, (count == 1) ? "" : "s");
500 if (this->product_set)
501 {
502 printf(" for product '%s'", this->product);
503 }
504 printf("\n");
505 }
506 }
507
508 METHOD(attest_db_t, list_files, void,
509 private_attest_db_t *this)
510 {
511 enumerator_t *e;
512 char *file, *file_type[] = { " ", "d", "r" };
513 int fid, type, meas, meta, count = 0;
514
515 if (this->pid)
516 {
517 e = this->db->query(this->db,
518 "SELECT f.id, f.type, f.path, pf.measurement, pf.metadata "
519 "FROM files AS f "
520 "JOIN product_file AS pf ON f.id = pf.file "
521 "WHERE pf.product = ? ORDER BY f.path",
522 DB_INT, this->pid, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
523 if (e)
524 {
525 while (e->enumerate(e, &fid, &type, &file, &meas, &meta))
526 {
527 type = (type < 0 || type > 2) ? 0 : type;
528 printf("%3d: |%s%s| %s %s\n", fid, meas ? "M":" ", meta ? "T":" ",
529 file_type[type], file);
530 count++;
531 }
532 e->destroy(e);
533 }
534 }
535 else
536 {
537 e = this->db->query(this->db,
538 "SELECT id, type, path FROM files "
539 "ORDER BY path",
540 DB_INT, DB_INT, DB_TEXT);
541 if (e)
542 {
543 while (e->enumerate(e, &fid, &type, &file))
544 {
545 type = (type < 0 || type > 2) ? 0 : type;
546 printf("%3d: %s %s\n", fid, file_type[type], file);
547 count++;
548 }
549 e->destroy(e);
550 }
551 }
552
553 printf("%d file%s found", count, (count == 1) ? "" : "s");
554 if (this->product_set)
555 {
556 printf(" for product '%s'", this->product);
557 }
558 printf("\n");
559 }
560
561 METHOD(attest_db_t, list_products, void,
562 private_attest_db_t *this)
563 {
564 enumerator_t *e;
565 char *product;
566 int pid, meas, meta, count = 0;
567
568 if (this->fid)
569 {
570 e = this->db->query(this->db,
571 "SELECT p.id, p.name, pf.measurement, pf.metadata "
572 "FROM products AS p "
573 "JOIN product_file AS pf ON p.id = pf.product "
574 "WHERE pf.file = ? ORDER BY p.name",
575 DB_INT, this->fid, DB_INT, DB_TEXT, DB_INT, DB_INT);
576 if (e)
577 {
578 while (e->enumerate(e, &pid, &product, &meas, &meta))
579 {
580 printf("%3d: |%s%s| %s\n", pid, meas ? "M":" ", meta ? "T":" ",
581 product);
582 count++;
583 }
584 e->destroy(e);
585 }
586 }
587 else if (this->cid)
588 {
589 e = this->db->query(this->db,
590 "SELECT p.id, p.name FROM products AS p "
591 "JOIN product_component AS pc ON p.id = pc.product "
592 "WHERE pc.component = ? ORDER BY p.name",
593 DB_INT, this->cid, DB_INT, DB_TEXT);
594 if (e)
595 {
596 while (e->enumerate(e, &pid, &product, &meas, &meta))
597 {
598 printf("%3d: %s\n", pid, product);
599 count++;
600 }
601 e->destroy(e);
602 }
603 }
604 else
605 {
606 e = this->db->query(this->db, "SELECT id, name FROM products "
607 "ORDER BY name",
608 DB_INT, DB_TEXT);
609 if (e)
610 {
611 while (e->enumerate(e, &pid, &product))
612 {
613 printf("%3d: %s\n", pid, product);
614 count++;
615 }
616 e->destroy(e);
617 }
618 }
619
620 printf("%d product%s found", count, (count == 1) ? "" : "s");
621 if (this->file_set)
622 {
623 printf(" for file '%s'", this->file);
624 }
625 else if (this->comp_set)
626 {
627 printf(" for component '%s'", print_cfn(this->cfn));
628 }
629 printf("\n");
630 }
631
632 /**
633 * get the directory if there is one from the files tables
634 */
635 static void get_directory(private_attest_db_t *this, int did, char **directory)
636 {
637 enumerator_t *e;
638 char *dir;
639
640 free(*directory);
641 *directory = strdup("");
642
643 if (did)
644 {
645 e = this->db->query(this->db,
646 "SELECT path from files WHERE id = ?",
647 DB_INT, did, DB_TEXT);
648 if (e)
649 {
650 if (e->enumerate(e, &dir))
651 {
652 free(*directory);
653 *directory = strdup(dir);
654 }
655 e->destroy(e);
656 }
657 }
658 }
659
660 static bool slash(char *directory, char *file)
661 {
662 return *file != '/' && directory[max(0, strlen(directory)-1)] != '/';
663 }
664
665 METHOD(attest_db_t, list_hashes, void,
666 private_attest_db_t *this)
667 {
668 enumerator_t *e;
669 chunk_t hash;
670 char *file, *dir, *product;
671 int fid, fid_old = 0, did, did_old = 0, count = 0;
672
673 dir = strdup("");
674
675 if (this->pid && this->fid && this->cid)
676 {
677 e = this->db->query(this->db,
678 "SELECT hash FROM file_hashes "
679 "WHERE algo = ? AND file = ? AND component = ? AND product = ?",
680 DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->cid,
681 DB_INT, this->pid, DB_BLOB);
682 if (e)
683 {
684 while (e->enumerate(e, &hash))
685 {
686 if (this->fid != fid_old)
687 {
688 printf("%3d: %s%s%s\n", this->fid, this->dir,
689 slash(this->dir, this->file) ? "/" : "", this->file);
690 fid_old = this->fid;
691 }
692 printf(" %#B '%s'\n", &hash, this->product);
693 count++;
694 }
695 e->destroy(e);
696
697 printf("%d %N value%s found for component '%s'\n", count,
698 hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
699 (count == 1) ? "" : "s", print_cfn(this->cfn));
700 }
701 }
702 else if (this->pid && this->fid)
703 {
704 e = this->db->query(this->db,
705 "SELECT hash FROM file_hashes "
706 "WHERE algo = ? AND file = ? AND directory = ? AND product = ?",
707 DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
708 DB_INT, this->pid, DB_BLOB);
709 if (e)
710 {
711 while (e->enumerate(e, &hash))
712 {
713 if (this->fid != fid_old)
714 {
715 printf("%3d: %s%s%s\n", this->fid, this->dir,
716 slash(this->dir, this->file) ? "/" : "", this->file);
717 fid_old = this->fid;
718 }
719 printf(" %#B\n", &hash);
720 count++;
721 }
722 e->destroy(e);
723
724 printf("%d %N value%s found for product '%s'\n", count,
725 hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
726 (count == 1) ? "" : "s", this->product);
727 }
728 }
729 else if (this->pid)
730 {
731 e = this->db->query(this->db,
732 "SELECT f.id, f. f.path, fh.hash, fh.directory "
733 "FROM file_hashes AS fh "
734 "JOIN files AS f ON f.id = fh.file "
735 "WHERE fh.algo = ? AND fh.product = ? "
736 "ORDER BY fh.directory, f.path",
737 DB_INT, this->algo, DB_INT, this->pid,
738 DB_INT, DB_TEXT, DB_BLOB, DB_INT);
739 if (e)
740 {
741 while (e->enumerate(e, &fid, &file, &hash, &did))
742 {
743 if (fid != fid_old || did != did_old)
744 {
745 if (did != did_old)
746 {
747 get_directory(this, did, &dir);
748 }
749 printf("%3d: %s%s%s\n", fid,
750 dir, slash(dir, file) ? "/" : "", file);
751 fid_old = fid;
752 did_old = did;
753 }
754 printf(" %#B\n", &hash);
755 count++;
756 }
757 e->destroy(e);
758
759 printf("%d %N value%s found for product '%s'\n", count,
760 hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
761 (count == 1) ? "" : "s", this->product);
762 }
763 }
764 else if (this->fid)
765 {
766 e = this->db->query(this->db,
767 "SELECT p.name, fh.hash, fh.directory "
768 "FROM file_hashes AS fh "
769 "JOIN products AS p ON p.id = fh.product "
770 "WHERE fh.algo = ? AND fh.file = ? AND fh.directory = ?"
771 "ORDER BY p.name",
772 DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
773 DB_TEXT, DB_BLOB, DB_INT);
774 if (e)
775 {
776 while (e->enumerate(e, &product, &hash, &did))
777 {
778 printf("%#B '%s'\n", &hash, product);
779 count++;
780 }
781 e->destroy(e);
782
783 printf("%d %N value%s found for file '%s%s%s'\n",
784 count, hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
785 (count == 1) ? "" : "s", this->dir,
786 slash(this->dir, this->file) ? "/" : "", this->file);
787 }
788 }
789 else
790 {
791 e = this->db->query(this->db,
792 "SELECT f.id, f.path, p.name, fh.hash, fh.directory "
793 "FROM file_hashes AS fh "
794 "JOIN files AS f ON f.id = fh.file "
795 "JOIN products AS p ON p.id = fh.product "
796 "WHERE fh.algo = ? "
797 "ORDER BY fh.directory, f.path, p.name",
798 DB_INT, this->algo,
799 DB_INT, DB_TEXT, DB_TEXT, DB_BLOB, DB_INT);
800 if (e)
801 {
802 while (e->enumerate(e, &fid, &file, &product, &hash, &did))
803 {
804 if (fid != fid_old || did != did_old)
805 {
806 if (did != did_old)
807 {
808 get_directory(this, did, &dir);
809 did_old = did;
810 }
811 printf("%3d: %s%s%s\n", fid,
812 dir, slash(dir, file) ? "/" : "", file);
813 fid_old = fid;
814 }
815 printf(" %#B '%s'\n", &hash, product);
816 count++;
817 }
818 e->destroy(e);
819
820 printf("%d %N value%s found\n", count, hash_algorithm_names,
821 pts_meas_algo_to_hash(this->algo), (count == 1) ? "" : "s");
822 }
823 }
824 free(dir);
825 }
826
827 METHOD(attest_db_t, add, bool,
828 private_attest_db_t *this)
829 {
830 return FALSE;
831 }
832
833 METHOD(attest_db_t, delete, bool,
834 private_attest_db_t *this)
835 {
836 bool success;
837
838 if (this->pid && (this->fid || this->did))
839 {
840 printf("deletion of product/file entries not supported yet\n");
841 return FALSE;
842 }
843
844 if (this->pid)
845 {
846 success = this->db->execute(this->db, NULL,
847 "DELETE FROM products WHERE id = ?",
848 DB_UINT, this->pid) > 0;
849
850 printf("product '%s' %sdeleted from database\n", this->product,
851 success ? "" : "could not be ");
852 return success;
853 }
854
855 if (this->fid)
856 {
857 success = this->db->execute(this->db, NULL,
858 "DELETE FROM files WHERE id = ?",
859 DB_UINT, this->fid) > 0;
860
861 printf("file '%s' %sdeleted from database\n", this->file,
862 success ? "" : "could not be ");
863 return success;
864 }
865
866 if (this->did)
867 {
868 success = this->db->execute(this->db, NULL,
869 "DELETE FROM files WHERE type = 1 AND id = ?",
870 DB_UINT, this->did) > 0;
871
872 printf("directory '%s' %sdeleted from database\n", this->dir,
873 success ? "" : "could not be ");
874 return success;
875 }
876
877 if (this->cid)
878 {
879 success = this->db->execute(this->db, NULL,
880 "DELETE FROM components WHERE id = ?",
881 DB_UINT, this->cid) > 0;
882
883 printf("component '%s' %sdeleted from database\n", print_cfn(this->cfn),
884 success ? "" : "could not be ");
885 return success;
886 }
887
888 printf("empty delete command\n");
889 return FALSE;
890 }
891
892 METHOD(attest_db_t, destroy, void,
893 private_attest_db_t *this)
894 {
895 DESTROY_IF(this->db);
896 DESTROY_IF(this->cfn);
897 free(this->product);
898 free(this->file);
899 free(this->dir);
900 free(this);
901 }
902
903 /**
904 * Described in header.
905 */
906 attest_db_t *attest_db_create(char *uri)
907 {
908 private_attest_db_t *this;
909
910 INIT(this,
911 .public = {
912 .set_product = _set_product,
913 .set_pid = _set_pid,
914 .set_file = _set_file,
915 .set_fid = _set_fid,
916 .set_directory = _set_directory,
917 .set_did = _set_did,
918 .set_component = _set_component,
919 .set_cid = _set_cid,
920 .set_algo = _set_algo,
921 .list_products = _list_products,
922 .list_files = _list_files,
923 .list_components = _list_components,
924 .list_hashes = _list_hashes,
925 .add = _add,
926 .delete = _delete,
927 .destroy = _destroy,
928 },
929 .dir = strdup(""),
930 .algo = PTS_MEAS_ALGO_SHA256,
931 .db = lib->db->create(lib->db, uri),
932 );
933
934 if (!this->db)
935 {
936 fprintf(stderr, "opening database failed.\n");
937 destroy(this);
938 return NULL;
939 }
940
941 return &this->public;
942 }