ff193cb3d0d84cb217918442227d44cee3ea2403
[strongswan.git] / src / libpts / pts / pts_database.c
1 /*
2 * Copyright (C) 2011 Sansar Choinyambuu
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 "pts_database.h"
17
18 #include <debug.h>
19 #include <crypto/hashers/hasher.h>
20
21
22 typedef struct private_pts_database_t private_pts_database_t;
23
24 /**
25 * Private data of a pts_database_t object.
26 *
27 */
28 struct private_pts_database_t {
29
30 /**
31 * Public pts_database_t interface.
32 */
33 pts_database_t public;
34
35 /**
36 * database instance
37 */
38 database_t *db;
39
40 };
41
42 METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
43 private_pts_database_t *this, char *product)
44 {
45 enumerator_t *e;
46
47 /* look for all entries belonging to a product in the files table */
48 e = this->db->query(this->db,
49 "SELECT f.id, f.type, f.path FROM files AS f "
50 "JOIN product_file AS pf ON f.id = pf.file "
51 "JOIN products AS p ON p.id = pf.product "
52 "WHERE p.name = ? AND pf.measurement = 1",
53 DB_TEXT, product, DB_INT, DB_INT, DB_TEXT);
54 return e;
55 }
56
57 METHOD(pts_database_t, create_file_meta_enumerator, enumerator_t*,
58 private_pts_database_t *this, char *product)
59 {
60 enumerator_t *e;
61
62 /* look for all entries belonging to a product in the files table */
63 e = this->db->query(this->db,
64 "SELECT f.type, f.path FROM files AS f "
65 "JOIN product_file AS pf ON f.id = pf.file "
66 "JOIN products AS p ON p.id = pf.product "
67 "WHERE p.name = ? AND pf.metadata = 1",
68 DB_TEXT, product, DB_INT, DB_TEXT);
69 return e;
70 }
71
72 METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
73 private_pts_database_t *this, char *product)
74 {
75 enumerator_t *e;
76
77 /* look for all entries belonging to a product in the components table */
78 e = this->db->query(this->db,
79 "SELECT c.vendor_id, c.name, c.qualifier, pc.depth "
80 "FROM components AS c "
81 "JOIN product_component AS pc ON c.id = pc.component "
82 "JOIN products AS p ON p.id = pc.product "
83 "WHERE p.name = ? ORDER BY pc.sequence",
84 DB_TEXT, product, DB_INT, DB_INT, DB_INT, DB_INT);
85 return e;
86 }
87
88
89 METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
90 private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
91 int id, bool is_dir)
92 {
93 enumerator_t *e;
94
95 if (is_dir)
96 {
97 e = this->db->query(this->db,
98 "SELECT f.path, fh.hash FROM file_hashes AS fh "
99 "JOIN files AS f ON fh.file = f.id "
100 "JOIN products AS p ON fh.product = p.id "
101 "WHERE p.name = ? AND fh.directory = ? AND fh.algo = ? "
102 "ORDER BY f.path",
103 DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
104 }
105 else
106 {
107 e = this->db->query(this->db,
108 "SELECT f.path, fh.hash FROM file_hashes AS fh "
109 "JOIN files AS f ON fh.file = f.id "
110 "JOIN products AS p ON fh.product = p.id "
111 "WHERE p.name = ? AND fh.file = ? AND fh.algo = ?",
112 DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
113 }
114 return e;
115 }
116
117 METHOD(pts_database_t, create_comp_hash_enumerator, enumerator_t*,
118 private_pts_database_t *this, char *file, char *product,
119 pts_comp_func_name_t *comp_name, pts_meas_algorithms_t algo)
120 {
121 enumerator_t *e;
122
123 e = this->db->query(this->db,
124 "SELECT fh.hash FROM file_hashes AS fh "
125 "JOIN files AS f ON fh.file = f.id "
126 "JOIN products AS p ON fh.product = p.id "
127 "JOIN components AS c ON fh.component = c.id "
128 "WHERE f.path = ? AND p.name = ? AND c.vendor_id = ? "
129 "AND c.name = ? AND c.qualifier = ? AND fh.algo = ? ",
130 DB_TEXT, file, DB_TEXT, product,
131 DB_INT, comp_name->get_vendor_id(comp_name),
132 DB_INT, comp_name->get_name(comp_name),
133 DB_INT, comp_name->get_qualifier(comp_name),
134 DB_INT, algo, DB_BLOB);
135
136 return e;
137 }
138
139 METHOD(pts_database_t, destroy, void,
140 private_pts_database_t *this)
141 {
142 this->db->destroy(this->db);
143 free(this);
144 }
145
146 /**
147 * See header
148 */
149 pts_database_t *pts_database_create(char *uri)
150 {
151 private_pts_database_t *this;
152
153 INIT(this,
154 .public = {
155 .create_file_meas_enumerator = _create_file_meas_enumerator,
156 .create_file_meta_enumerator = _create_file_meta_enumerator,
157 .create_comp_evid_enumerator = _create_comp_evid_enumerator,
158 .create_file_hash_enumerator = _create_file_hash_enumerator,
159 .create_comp_hash_enumerator = _create_comp_hash_enumerator,
160 .destroy = _destroy,
161 },
162 .db = lib->db->create(lib->db, uri),
163 );
164
165 if (!this->db)
166 {
167 DBG1(DBG_PTS,
168 "failed to connect to PTS file measurement database '%s'", uri);
169 free(this);
170 return NULL;
171 }
172
173 return &this->public;
174 }
175