2 * Copyright (C) 2013 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "imv_policy_manager_usage.h"
17 #include "imv_workitem.h"
20 #include <utils/debug.h>
26 /* The default policy group #1 is assumed to always exist */
27 #define DEFAULT_GROUP_ID 1
30 * global debug output variables
32 static int debug_level
= 1;
33 static bool stderr_quiet
= FALSE
;
38 static void stderr_dbg(debug_t group
, level_t level
, char *fmt
, ...)
42 if (level
<= debug_level
)
47 vfprintf(stderr
, fmt
, args
);
48 fprintf(stderr
, "\n");
55 * Collect all enforcements by iterating up through parent groups
57 static bool iterate_enforcements(database_t
*db
, int device_id
, int session_id
,
60 int id
, type
, file
, dir
, arg_int
, parent
, policy
, max_age
;
61 int p_rec_fail
, p_rec_noresult
, e_rec_fail
, e_rec_noresult
, latest_rec
;
65 enumerator_t
*e
, *e1
, *e2
;
72 "SELECT e.id, p.type, p.argument, p.file, p.dir, p.rec_fail, "
73 "p.rec_noresult, e.policy, e.max_age, e.rec_fail, e.rec_noresult "
74 "FROM enforcements AS e JOIN policies as p ON e.policy = p.id "
75 "WHERE e.group_id = ?", DB_INT
, group_id
,
76 DB_INT
, DB_INT
, DB_TEXT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
77 DB_INT
, DB_INT
, DB_INT
, DB_INT
);
82 while (e1
->enumerate(e1
, &id
, &type
, &argument
, &file
, &dir
,
83 &p_rec_fail
, &p_rec_noresult
, &policy
, &max_age
,
84 &e_rec_fail
, &e_rec_noresult
))
86 /* check if the latest measurement of the device was successful */
87 latest_success
= FALSE
;
92 "SELECT r.rec FROM results AS r "
93 "JOIN sessions AS s ON s.id = r.session "
94 "WHERE r.policy = ? AND s.device = ? AND s.time > ? "
95 "ORDER BY s.time DESC",
96 DB_INT
, policy
, DB_INT
, device_id
,
97 DB_UINT
, now
- max_age
, DB_INT
);
103 if (e2
->enumerate(e2
, &latest_rec
) &&
104 latest_rec
== TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
106 latest_success
= TRUE
;
113 /*skipping enforcement */
114 printf("skipping enforcment %d\n", id
);
118 /* determine arg_int */
119 switch ((imv_workitem_type_t
)type
)
121 case IMV_WORKITEM_FILE_REF_MEAS
:
122 case IMV_WORKITEM_FILE_MEAS
:
123 case IMV_WORKITEM_FILE_META
:
126 case IMV_WORKITEM_DIR_REF_MEAS
:
127 case IMV_WORKITEM_DIR_MEAS
:
128 case IMV_WORKITEM_DIR_META
:
135 /* insert a workitem */
136 if (db
->execute(db
, NULL
,
137 "INSERT INTO workitems (session, enforcement, type, arg_str, "
138 "arg_int, rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?, ?, ?)",
139 DB_INT
, session_id
, DB_INT
, id
, DB_INT
, type
, DB_TEXT
, argument
,
140 DB_INT
, arg_int
, DB_INT
, e_rec_fail ? e_rec_fail
: p_rec_fail
,
141 DB_INT
, e_rec_noresult ? e_rec_noresult
: p_rec_noresult
) != 1)
144 fprintf(stderr
, "could not insert workitem\n");
151 "SELECT parent FROM groups WHERE id = ?",
152 DB_INT
, group_id
, DB_INT
);
157 if (e
->enumerate(e
, &parent
))
163 fprintf(stderr
, "group information not found\n");
171 static bool policy_start(database_t
*db
, int session_id
)
174 int device_id
, product_id
, gid
, group_id
= DEFAULT_GROUP_ID
;
177 /* get session data */
179 "SELECT s.device, s.product, d.created FROM sessions AS s "
180 "LEFT JOIN devices AS d ON s.device = d.id WHERE s.id = ?",
181 DB_INT
, session_id
, DB_INT
, DB_INT
, DB_UINT
);
182 if (!e
|| !e
->enumerate(e
, &device_id
, &product_id
, &created
))
185 fprintf(stderr
, "session %d not found\n", session_id
);
190 /* if a device ID with a creation date exists, get all group memberships */
191 if (device_id
& created
)
194 "SELECT group_id FROM groups_members WHERE device_id = ?",
195 DB_INT
, device_id
, DB_INT
);
200 while (e
->enumerate(e
, &group_id
))
202 if (!iterate_enforcements(db
, device_id
, session_id
, group_id
))
213 /* determine if a default product group exists */
215 "SELECT group_id FROM groups_product_defaults "
216 "WHERE product_id = ?", DB_INT
, product_id
, DB_INT
);
221 if (e
->enumerate(e
, &gid
))
227 if (device_id
&& !created
)
229 /* assign a newly created device to a default group */
230 if (db
->execute(db
, NULL
,
231 "INSERT INTO groups_members (device_id, group_id) "
232 "VALUES (?, ?)", DB_INT
, device_id
, DB_INT
, group_id
) != 1)
234 fprintf(stderr
, "could not assign device to a default group\n");
238 /* set the creation date if it hasn't been set yet */
239 if (db
->execute(db
, NULL
,
240 "UPDATE devices SET created = ? WHERE id = ?",
241 DB_UINT
, time(NULL
), DB_INT
, device_id
) != 1)
243 fprintf(stderr
, "creation date of device could not be set\n");
248 return iterate_enforcements(db
, device_id
, session_id
, group_id
);
251 static bool policy_stop(database_t
*db
, int session_id
)
258 "SELECT w.rec_final, w.result, e.policy FROM workitems AS w "
259 "JOIN enforcements AS e ON w.enforcement = e.id "
260 "WHERE w.session = ? AND w.result IS NOT NULL",
261 DB_INT
, session_id
, DB_INT
, DB_TEXT
, DB_INT
);
264 while (e
->enumerate(e
, &rec
, &result
, &policy
))
266 db
->execute(db
, NULL
,
267 "INSERT INTO results (session, policy, rec, result) "
268 "VALUES (?, ?, ?, ?)", DB_INT
, session_id
, DB_INT
, policy
,
269 DB_INT
, rec
, DB_TEXT
, result
);
273 return db
->execute(db
, NULL
,
274 "DELETE FROM workitems WHERE session = ?",
275 DB_UINT
, session_id
) >= 0;
278 int main(int argc
, char *argv
[])
281 char *uri
, *tnc_session_id
;
285 /* enable attest debugging hook */
288 atexit(library_deinit
);
290 /* initialize library */
291 if (!library_init(NULL
, "imv_policy_manager"))
293 exit(SS_RC_LIBSTRONGSWAN_INTEGRITY
);
295 if (!lib
->plugins
->load(lib
->plugins
,
296 lib
->settings
->get_str(lib
->settings
, "imv_policy_manager.load",
299 exit(SS_RC_INITIALIZATION_FAILED
);
305 exit(SS_RC_INITIALIZATION_FAILED
);
307 if (streq(argv
[1], "start"))
311 else if (streq(argv
[1], "stop"))
318 exit(SS_RC_INITIALIZATION_FAILED
);
322 tnc_session_id
= getenv("TNC_SESSION_ID");
325 fprintf(stderr
, "environment variable TNC_SESSION_ID is not defined\n");
326 exit(SS_RC_INITIALIZATION_FAILED
);
328 session_id
= atoi(tnc_session_id
);
330 /* attach IMV database */
331 uri
= lib
->settings
->get_str(lib
->settings
, "libimcv.database", NULL
);
334 fprintf(stderr
, "database uri not defined.\n");
335 exit(SS_RC_INITIALIZATION_FAILED
);
338 db
= lib
->db
->create(lib
->db
, uri
);
341 fprintf(stderr
, "opening database failed.\n");
342 exit(SS_RC_INITIALIZATION_FAILED
);
347 success
= policy_start(db
, session_id
);
351 success
= policy_stop(db
, session_id
);
355 fprintf(stderr
, "imv_policy_manager %s %s\n", start ?
"start" : "stop",
356 success ?
"successful" : "failed");