pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
+ipsec_SCRIPTS = imv/_imv_policy
+EXTRA_DIST = imv/_imv_policy
+
SUBDIRS = .
if USE_IMC_TEST
--- /dev/null
+#! /bin/sh
+# default TNC policy command script
+#
+# Copyright 2013 Andreas Steffen
+# HSR Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# CAUTION: Installing a new version of strongSwan will install a new
+# copy of this script, wiping out any custom changes you make. If
+# you need changes, make a copy of this under another name, and customize
+# that, and use the "libimcv.policy_script = " option in strongswan.conf
+# to make strongSwan use yours instead of this default one.
+
+# Environment variables that this script gets
+#
+# TNC_SESSION_ID
+# unique session ID used as a reference by the policy
+# manager.
+#
+case "$1" in
+start)
+ echo "start session $TNC_SESSION_ID"
+ ;;
+stop)
+ echo "stop session $TNC_SESSION_ID"
+ ;;
+*) echo "$0: unknown command '$1'"
+ exit 1
+ ;;
+esac
* for more details.
*/
-#include "imv_database.h"
-
-#include <utils/debug.h>
+#define _GNU_SOURCE
+#include <stdio.h>
#include <string.h>
#include <time.h>
+#include "imv_database.h"
+
+#include <utils/debug.h>
+
typedef struct private_imv_database_t private_imv_database_t;
#define SESSION_TIME_DELTA_MAX 2 /* seconds */
+#define DEFAULT_POLICY_SCRIPT "ipsec _imv_policy"
+
/**
* Private data of a imv_database_t object.
*
*/
database_t *db;
+ /**
+ * policy script
+ */
+ char *script;
+
};
METHOD(imv_database_t, get_session_id, int,
return did;
}
+METHOD(imv_database_t, policy_script, bool,
+ private_imv_database_t *this, int session_id, bool start)
+{
+ char command[512], resp[128], *last;
+ FILE *shell;
+
+ snprintf(command, sizeof(command), "2>&1 TNC_SESSION_ID='%d' %s %s",
+ session_id, this->script, start ? "start" : "stop");
+ DBG3(DBG_IMV, "running policy script: %s", command);
+
+ shell = popen(command, "r");
+ if (shell == NULL)
+ {
+ DBG1(DBG_IMV, "could not execute policy script '%s'",
+ this->script);
+ return FALSE;
+ }
+ while (TRUE)
+ {
+ if (fgets(resp, sizeof(resp), shell) == NULL)
+ {
+ if (ferror(shell))
+ {
+ DBG1(DBG_IMV, "error reading output from policy script");
+ }
+ break;
+ }
+ else
+ {
+ last = resp + strlen(resp) - 1;
+ if (last >= resp && *last == '\n')
+ {
+ /* replace trailing '\n' */
+ *last = '\0';
+ }
+ DBG1(DBG_IMV, "policy: %s", resp);
+ }
+ }
+ pclose(shell);
+
+ return TRUE;
+}
+
METHOD(imv_database_t, get_database, database_t*,
private_imv_database_t *this)
{
.get_session_id = _get_session_id,
.add_product = _add_product,
.add_device = _add_device,
+ .policy_script = _policy_script,
.get_database = _get_database,
.destroy = _destroy,
},
.db = lib->db->create(lib->db, uri),
+ .script = lib->settings->get_str(lib->settings,
+ "libimcv.policy_script", DEFAULT_POLICY_SCRIPT),
);
if (!this->db)
/**
* Add device identification to a session
*
- * @param session_id Sessiion ID
+ * @param session_id Session ID
* @param device Device identification
* @return Device ID or 0 if not available
*/
int (*add_device)(imv_database_t *this, int session_id, chunk_t device);
+ /**
+ * Announce session start/stop to policy script
+ *
+ * @param session_id Session ID
+ * @param start TRUE if session start, FALSE if session stop
+ * @return TRUE if command successful, FALSE otherwise
+ */
+ bool (*policy_script)(imv_database_t *this, int session_id, bool start);
+
/**
* Get database handle
*
TNC_ConnectionState new_state)
{
imv_state_t *state;
+ imv_database_t *imv_db;
+ int session_id;
if (!imv_os)
{
state = imv_os_state_create(connection_id);
return imv_os->create_state(imv_os, state);
case TNC_CONNECTION_STATE_DELETE:
+ imv_db = imv_os->get_database(imv_os);
+ if (imv_db && imv_os->get_state(imv_os, connection_id, &state))
+ {
+ session_id = state->get_session_id(state);
+ imv_db->policy_script(imv_db, session_id, FALSE);
+ }
return imv_os->delete_state(imv_os, connection_id);
default:
return imv_os->change_state(imv_os, connection_id,
ita_attr_settings_t *attr_cast;
imv_database_t *imv_db;
enumerator_t *e;
- int did;
+ int session_id, device_id;
char *name;
chunk_t value;
imv_db = imv_os->get_database(imv_os);
if (imv_db)
{
- did = imv_db->add_device(imv_db,
- state->get_session_id(state), value);
- os_state->set_device_id(os_state, did);
+ session_id = state->get_session_id(state);
+ device_id = imv_db->add_device(imv_db,
+ session_id, value);
+ os_state->set_device_id(os_state, device_id);
+
+ /* trigger the policy manager */
+ imv_db->policy_script(imv_db, session_id, TRUE);
}
}
DBG1(DBG_IMV, "setting '%s'\n %.*s",
private_imv_os_database_t *this, int session_id, int count,
int count_update, int count_blacklist, u_int flags)
{
- enumerator_t *e;
-
this->db->execute(this->db, NULL,
"INSERT INTO device_infos (session, count, count_update, "
"count_blacklist, flags) VALUES (?, ?, ?, ?, ?)",