From: Andreas Steffen Date: Thu, 23 May 2013 20:12:10 +0000 (+0200) Subject: generate workitems based on group policy X-Git-Tag: 5.1.0dr1~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65148217b0757bd5f8ab2aac3fe44b30147666b4;p=thirdparty%2Fstrongswan.git generate workitems based on group policy --- diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql index dfab9e2850..4df72be8eb 100644 --- a/src/libimcv/imv/data.sql +++ b/src/libimcv/imv/data.sql @@ -144,6 +144,18 @@ INSERT INTO products ( /* 24 */ 'Ubuntu 13.04 x86_64' ); +INSERT INTO products ( /* 25 */ + name +) VALUES ( + 'Android 4.1.1' +); + +INSERT INTO products ( /* 26 */ + name +) VALUES ( + 'Android 4.2.1' +); + /* Directories */ INSERT INTO directories ( /* 1 */ @@ -250,26 +262,6 @@ INSERT INTO files ( /* 5 */ 'openssl', 8 ); -/* Product-File */ - -INSERT INTO product_file ( - product, file, measurement -) VALUES ( - 3, 1, 1 -); - -INSERT INTO product_file ( - product, file, measurement -) VALUES ( - 3, 3, 1 -); - -INSERT INTO product_file ( - product, file, measurement -) VALUES ( - 3, 5, 1 -); - /* Algorithms */ INSERT INTO algorithms ( @@ -436,24 +428,363 @@ INSERT INTO packages ( /* 4 */ INSERT INTO versions ( package, product, release, time -) values ( +) VALUES ( 1, 1, '1.0.1e-2', 1366531494 ); INSERT INTO versions ( package, product, release, time -) values ( +) VALUES ( 2, 1, '1.0.1e-2', 1366531494 ); INSERT INTO versions ( package, product, release, time -) values ( +) VALUES ( 3, 1, '1.0.1e-2', 1366531494 ); INSERT INTO versions ( package, product, release, time -) values ( +) VALUES ( 4, 1, '1.0.1e-2', 1366531494 ); + +/* Groups */ + +INSERT INTO groups ( /* 1 */ + name +) VALUES ( + 'Default Debian i686' +); + +INSERT INTO groups ( /* 2 */ + name +) VALUES ( + 'Default Debian x86_64' +); + +INSERT INTO groups ( /* 3 */ + name +) VALUES ( + 'Default Ubuntu i686' +); + +INSERT INTO groups ( /* 4 */ + name +) VALUES ( + 'Default Ubuntu x86_64' +); + +INSERT INTO groups ( /* 5 */ + name +) VALUES ( + 'Default Android' +); + +/* Default Product Groups */ + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 1, 2 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 2, 3 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 5 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 8 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 11 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 14 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 17 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 20 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 3, 23 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 6 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 9 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 12 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 15 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 18 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 21 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 4, 24 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 5, 25 +); + +INSERT INTO default_product_groups ( + group_id, product +) VALUES ( + 5, 26 +); + +/* Policies */ + +INSERT INTO policies ( /* 1 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 1, 'Installed Packages', 2, 2 +); + +INSERT INTO policies ( /* 2 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 2, 'Unknown Source', 2, 2 +); + +INSERT INTO policies ( /* 3 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 3, 'IP Forwarding Enabled', 1, 1 +); + +INSERT INTO policies ( /* 4 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 4, 'Default Factory Password Enabled', 1, 1 +); + +INSERT INTO policies ( /* 5 */ + type, name, file, rec_fail, rec_noresult +) VALUES ( + 6, 'Measure /lib/x86_64-linux-gnu/libcrypto.so.1.0.0', 1, 2, 2 +); + +INSERT INTO policies ( /* 6 */ + type, name, file, rec_fail, rec_noresult +) VALUES ( + 6, 'Measure /lib/x86_64-linux-gnu/libssl.so.1.0.0', 3, 2, 2 +); + +INSERT INTO policies ( /* 7 */ + type, name, file, rec_fail, rec_noresult +) VALUES ( + 6, 'Measure /usr/bin/openssl', 5, 2, 2 +); + +INSERT INTO policies ( /* 8 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 9, 'No Open TCP Ports', 1, 1 +); + +INSERT INTO policies ( /* 9 */ + type, name, rec_fail, rec_noresult +) VALUES ( + 10, 'No Open UDP Ports', 1, 1 +); + +/* Enforcements */ + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 1, 1, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 1, 2, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 1, 3, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 1, 4, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 1, 5, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 2, 5, 0 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 3, 1, 0 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 3, 2, 0 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 3, 3, 0 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 3, 4, 0 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 5, 2, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 6, 2, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 7, 2, 86400 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 8, 1, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 8, 2, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 8, 3, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 8, 4, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 8, 5, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 9, 1, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 9, 2, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 9, 3, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 9, 4, 60 +); + +INSERT INTO enforcements ( + policy, group_id, max_age +) VALUES ( + 9, 5, 60 +); + diff --git a/src/libimcv/imv/imv_policy_manager.c b/src/libimcv/imv/imv_policy_manager.c index 7819a10907..a91deec057 100644 --- a/src/libimcv/imv/imv_policy_manager.c +++ b/src/libimcv/imv/imv_policy_manager.c @@ -49,42 +49,121 @@ static void stderr_dbg(debug_t group, level_t level, char *fmt, ...) bool policy_start(database_t *db, int session_id) { - if (db->execute(db, NULL, - "INSERT INTO workitems (session, type, argument, " - "rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?)", - DB_INT, session_id, DB_INT, IMV_WORKITEM_PACKAGES, - DB_TEXT, "", - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS) != 1) + enumerator_t *e; + int id, gid, device_id, product_id, group_id = 0; + int type, rec_fail, rec_noresult; + char *argument; + + /* get session data */ + e = db->query(db, + "SELECT device, product FROM sessions WHERE id = ? ", + DB_INT, session_id, DB_INT, DB_INT); + if (!e || !e->enumerate(e, &device_id, &product_id)) { + DESTROY_IF(e); + fprintf(stderr, "session %d not found\n", session_id); return FALSE; } - if (db->execute(db, NULL, - "INSERT INTO workitems (session, type, argument, " - "rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?)", - DB_INT, session_id, DB_INT, IMV_WORKITEM_FORWARDING, - DB_TEXT, "", - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS) != 1) + e->destroy(e); + + /* if a device ID exists, check if device belongs to a group */ + if (device_id) { - return FALSE; + e = db->query(db, + "SELECT group_id FROM group_members WHERE device = ?", + DB_INT, device_id, DB_INT); + if (e) + { + if (e->enumerate(e, &gid)) + { + group_id = gid; + } + e->destroy(e); + } } - if (db->execute(db, NULL, - "INSERT INTO workitems (session, type, argument, " - "rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?)", - DB_INT, session_id, DB_INT, IMV_WORKITEM_TCP_SCAN, - DB_TEXT, "22", - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS, - DB_INT, TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS) != 1) + + /* if no group membership found, try default product group */ + if (!group_id) + { + e = db->query(db, + "SELECT group_id FROM default_product_groups WHERE product = ?", + DB_INT, product_id, DB_INT); + if (e) + { + if (e->enumerate(e, &gid)) + { + group_id = gid; + } + e->destroy(e); + } + } + + /* if still no group membership found, leave */ + if (!group_id) + { + fprintf(stderr, "no group membership found\n"); + return TRUE; + } + + /* get enforcements for given group */ + e = db->query(db, + "SELECT e.id, p.type, p.argument, p.rec_fail, p.rec_noresult " + "FROM enforcements AS e JOIN policies as p ON e.policy = p.id " + "WHERE e.group_id = ?", + DB_INT, group_id, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT); + if (!e) { return FALSE; } + while (e->enumerate(e, &id, &type, &argument, &rec_fail, &rec_noresult)) + { + /* insert a workitem */ + if (db->execute(db, NULL, + "INSERT INTO workitems (session, enforcement, type, argument, " + "rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?, ?)", + DB_INT, session_id, DB_INT, id, DB_INT, type, DB_TEXT, argument, + DB_INT, rec_fail, DB_INT, rec_noresult) != 1) + { + e->destroy(e); + fprintf(stderr, "could not insert workitem\n"); + return FALSE; + } + } + e->destroy(e); return TRUE; } bool policy_stop(database_t *db, int session_id) { + enumerator_t *e; + int rec, policy; + char *result; + bool no_worklists = TRUE; + + e = db->query(db, + "SELECT w.rec_final, w.result, e.policy FROM workitems AS w " + "JOIN enforcements AS e ON w.enforcement = e.id WHERE w.id = ?", + DB_INT, session_id, DB_INT, DB_TEXT, DB_INT); + if (e) + { + while (e->enumerate(e, &rec, &result, &policy)) + { + no_worklists = FALSE; + + /* insert result */ + db->execute(db, NULL, + "INSERT INTO results (session, policy, rec, result) " + "VALUES (?, ?, ?, ?)", DB_INT, session_id, DB_INT, policy, + DB_INT, rec, DB_TEXT, result); + } + e->destroy(e); + + if (no_worklists) + { + return TRUE; + } + } return db->execute(db, NULL, "DELETE FROM workitems WHERE session = ?", DB_UINT, session_id) > 0; diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql index 5377322d8a..c65de682f1 100644 --- a/src/libimcv/imv/tables.sql +++ b/src/libimcv/imv/tables.sql @@ -31,15 +31,6 @@ CREATE INDEX products_name ON products ( name ); -DROP TABLE IF EXISTS product_file; -CREATE TABLE product_file ( - product INTEGER NOT NULL REFERENCES products(id), - file INTEGER NOT NULL REFERENCES files(id), - measurement INTEGER DEFAULT 0, - metadata INTEGER DEFAULT 0, - PRIMARY KEY (product, file) -); - DROP TABLE IF EXISTS algorithms; CREATE TABLE algorithms ( id INTEGER PRIMARY KEY, @@ -56,6 +47,49 @@ CREATE TABLE file_hashes ( hash BLOB NOT NULL ); +DROP TABLE IF EXISTS groups; +CREATE TABLE groups ( + id integer NOT NULL PRIMARY KEY, + name varchar(50) NOT NULL UNIQUE +); + +DROP TABLE IF EXISTS group_members; +CREATE TABLE group_members ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + group_id integer NOT NULL REFERENCES groups(id), + device integer NOT NULL REFERENCES devices(id), + UNIQUE (group_id, device) +); + +DROP TABLE IF EXISTS default_product_groups; +CREATE TABLE default_product_groups ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + group_id integer NOT NULL REFERENCES groups(id), + product integer NOT NULL REFERENCES products(id), + UNIQUE (group_id, product) +); + +DROP TABLE IF EXISTS policies; +CREATE TABLE policies ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + type integer NOT NULL, + name varchar(100) NOT NULL UNIQUE, + argument text DEFAULT '' NOT NULL, + rec_fail integer NOT NULL, + rec_noresult integer NOT NULL, + file integer DEFAULT 0 REFERENCES files(id), + dir integer DEFAULT 0 REFERENCES directories(id) +); + +DROP TABLE IF EXISTS enforcements; +CREATE TABLE enforcements ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + policy integer NOT NULL REFERENCES policies(id), + group_id integer NOT NULL REFERENCES groups(id), + max_age integer NOT NULL, + UNIQUE (policy, group_id) +); + DROP TABLE IF EXISTS sessions; CREATE TABLE sessions ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, @@ -69,20 +103,34 @@ CREATE TABLE sessions ( DROP TABLE IF EXISTS workitems; CREATE TABLE workitems ( - id integer NOT NULL PRIMARY KEY AUTOINCREMENT, - session integer NOT NULL REFERENCES sessions(id), - type integer DEFAULT 0, - argument text NOT NULL, - rec_fail integer DEFAULT 1, - rec_noresult integer DEFAULT 1, - rec_final integer DEFAULT 3, - result text + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + session integer NOT NULL REFERENCES sessions(id), + enforcement integer NOT NULL REFERENCES enforcements(id), + type integer NOT NULL, + argument text NOT NULL, + rec_fail integer NOT NULL, + rec_noresult integer NOT NULL, + rec_final integer DEFAULT 3, + result text ); DROP INDEX IF EXISTS workitems_session; CREATE INDEX workitems_sessions ON workitems ( session ); +DROP TABLE IF EXISTS results; +CREATE TABLE results ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + session integer NOT NULL REFERENCES measurements(id), + policy integer NOT NULL REFERENCES policies(id), + rec integer NOT NULL, + result text NOT NULL +); +DROP INDEX IF EXISTS results_session; +CREATE INDEX results_session ON results ( + session +); + DROP TABLE IF EXISTS components; CREATE TABLE components ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, @@ -158,3 +206,4 @@ CREATE TABLE identities ( value BLOB NOT NULL, UNIQUE (type, value) ); + diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index c0ce8051ab..edffdb3eb7 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -576,6 +576,7 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, TNC_ConnectionID connection_id) imv_os_handshake_state_t handshake_state; pa_tnc_attr_t *attr; TNC_Result result = TNC_RESULT_SUCCESS; + bool no_workitems = TRUE; enumerator_t *enumerator; u_int received; @@ -620,7 +621,7 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, TNC_ConnectionID connection_id) } else { - /* just gather information without evaluation */ + DBG2(DBG_IMV, "no workitems available - no evaluation possible"); state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_ALLOW, TNC_IMV_EVALUATION_RESULT_DONT_KNOW); @@ -665,6 +666,8 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, TNC_ConnectionID connection_id) { continue; } + no_workitems = FALSE; + switch (workitem->get_type(workitem)) { case IMV_WORKITEM_PACKAGES: @@ -686,6 +689,13 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, TNC_ConnectionID connection_id) } enumerator->destroy(enumerator); + if (no_workitems) + { + DBG2(DBG_IMV, "no workitems generated - no evaluation requested"); + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_ALLOW, + TNC_IMV_EVALUATION_RESULT_DONT_KNOW); + } handshake_state = IMV_OS_STATE_WORKITEMS; os_state->set_handshake_state(os_state, handshake_state); }