diff options
-rw-r--r-- | configure.in | 8 | ||||
-rw-r--r-- | src/libimcv/Makefile.am | 7 | ||||
-rw-r--r-- | src/libimcv/plugins/imc_scanner/Makefile.am | 16 | ||||
-rw-r--r-- | src/libimcv/plugins/imc_scanner/imc_scanner.c | 361 | ||||
-rw-r--r-- | src/libimcv/plugins/imc_scanner/imc_scanner_state.c | 82 | ||||
-rw-r--r-- | src/libimcv/plugins/imc_scanner/imc_scanner_state.h | 47 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_scanner.c | 266 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_scanner/Makefile.am | 16 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_scanner/imv_scanner.c | 397 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_scanner/imv_scanner_state.c | 206 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_scanner/imv_scanner_state.h | 52 | ||||
-rw-r--r-- | src/libtncif/tncif_pa_subtypes.c | 5 | ||||
-rw-r--r-- | src/libtncif/tncif_pa_subtypes.h | 3 | ||||
-rwxr-xr-x | testing/scripts/build-umlrootfs | 10 | ||||
-rwxr-xr-x | testing/testing.conf | 2 |
15 files changed, 1474 insertions, 4 deletions
diff --git a/configure.in b/configure.in index b448d2493..3e2723bf9 100644 --- a/configure.in +++ b/configure.in @@ -134,6 +134,8 @@ ARG_ENABL_SET([tnccs-20], [enable TNCCS 2.0 protocol module.]) ARG_ENABL_SET([tnccs-dynamic], [enable dynamic TNCCS protocol discovery module.]) ARG_ENABL_SET([imc-test], [enable IMC test module.]) ARG_ENABL_SET([imv-test], [enable IMV test module.]) +ARG_ENABL_SET([imc-scanner], [enable IMC port scanner module.]) +ARG_ENABL_SET([imv-scanner], [enable IMV port scanner module.]) ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.]) ARG_ENABL_SET([kernel-pfkey], [enable the PF_KEY kernel interface.]) ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.]) @@ -242,7 +244,7 @@ if test x$eap_tls = xtrue -o x$eap_ttls = xtrue -o x$eap_peap = xtrue; then tls=true; fi -if test x$imc_test = xtrue -o x$imv_test = xtrue; then +if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue; then imcv=true; fi @@ -910,6 +912,8 @@ AM_CONDITIONAL(USE_TNCCS_20, test x$tnccs_20 = xtrue) AM_CONDITIONAL(USE_TNCCS_DYNAMIC, test x$tnccs_dynamic = xtrue) AM_CONDITIONAL(USE_IMC_TEST, test x$imc_test = xtrue) AM_CONDITIONAL(USE_IMV_TEST, test x$imv_test = xtrue) +AM_CONDITIONAL(USE_IMC_SCANNER, test x$imc_scanner = xtrue) +AM_CONDITIONAL(USE_IMV_SCANNER, test x$imv_scanner = xtrue) AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue) AM_CONDITIONAL(USE_SOCKET_RAW, test x$socket_raw = xtrue) AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue) @@ -1041,6 +1045,8 @@ AC_OUTPUT( src/libimcv/Makefile src/libimcv/plugins/imc_test/Makefile src/libimcv/plugins/imv_test/Makefile + src/libimcv/plugins/imc_scanner/Makefile + src/libimcv/plugins/imv_scanner/Makefile src/pluto/Makefile src/pluto/plugins/xauth/Makefile src/whack/Makefile diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index 6b0f995ca..f3bc557b5 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -26,3 +26,10 @@ if USE_IMV_TEST SUBDIRS += plugins/imv_test endif +if USE_IMC_SCANNER + SUBDIRS += plugins/imc_scanner +endif + +if USE_IMV_SCANNER + SUBDIRS += plugins/imv_scanner +endif diff --git a/src/libimcv/plugins/imc_scanner/Makefile.am b/src/libimcv/plugins/imc_scanner/Makefile.am new file mode 100644 index 000000000..caf2c868f --- /dev/null +++ b/src/libimcv/plugins/imc_scanner/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-imc-scanner.la + +libstrongswan_imc_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +libstrongswan_imc_scanner_la_SOURCES = imc_scanner.c \ + imc_scanner_state.h imc_scanner_state.c + +libstrongswan_imc_scanner_la_LDFLAGS = -module -avoid-version + diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner.c b/src/libimcv/plugins/imc_scanner/imc_scanner.c new file mode 100644 index 000000000..97133e575 --- /dev/null +++ b/src/libimcv/plugins/imc_scanner/imc_scanner.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2011 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. + */ + +#include "imc_scanner_state.h" + +#include <imc/imc_agent.h> +#include <pa_tnc/pa_tnc_msg.h> +#include <ietf/ietf_attr.h> +#include <ietf/ietf_attr_pa_tnc_error.h> +#include <ietf/ietf_attr_port_filter.h> + +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <pen/pen.h> +#include <utils/lexparser.h> +#include <debug.h> + +#include <stdio.h> + +/* IMC definitions */ + +static const char imc_name[] = "Scanner"; + +#define IMC_VENDOR_ID PEN_ITA +#define IMC_SUBTYPE PA_SUBTYPE_ITA_SCANNER + +static imc_agent_t *imc_scanner; + +/** + * see section 3.7.1 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imc_scanner = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE, + imc_id, actual_version); + if (!imc_scanner) + { + return TNC_RESULT_FATAL; + } + if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1) + { + DBG1(DBG_IMC, "no common IF-IMC version"); + return TNC_RESULT_NO_COMMON_VERSION; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.2 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imc_state_t *state; + + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imc_scanner_state_create(connection_id); + return imc_scanner->create_state(imc_scanner, state); + case TNC_CONNECTION_STATE_DELETE: + return imc_scanner->delete_state(imc_scanner, connection_id); + default: + return imc_scanner->change_state(imc_scanner, connection_id, + new_state, NULL); + } +} + +/** + * Determine all TCP and UDP server sockets listening on physical interfaces + */ +static bool do_netstat(ietf_attr_port_filter_t *attr) +{ + FILE *file; + char buf[BUF_LEN]; + chunk_t line, token; + int n = 0; + bool success = FALSE; + + /* Open a pipe stream for reading the output of the netstat commmand */ + file = popen("/bin/netstat -n -l -4 -6 --inet", "r"); + if (!file) + { + DBG1(DBG_IMC, "Failed to run netstat command"); + return FALSE; + } + + /* Read the output a line at a time */ + while (fgets(buf, BUF_LEN-1, file)) + { + u_char *pos; + u_int8_t new_protocol, protocol; + u_int16_t new_port, port; + int i; + enumerator_t *enumerator; + bool allowed, found = FALSE; + + DBG2(DBG_IMC, "%.*s", strlen(buf)-1, buf); + + if (n++ < 2) + { + /* skip the first two header lines */ + continue; + } + line = chunk_create(buf, strlen(buf)); + + /* Extract the IP protocol type */ + if (!extract_token(&token, ' ', &line)) + { + DBG1(DBG_IMC, "Protocol field in netstat output not found"); + goto end; + } + if (match("tcp", &token) || match("tcp6", &token)) + { + new_protocol = IPPROTO_TCP; + } + else if (match("udp", &token) || match("udp6", &token)) + { + new_protocol = IPPROTO_UDP; + } + else + { + DBG1(DBG_IMC, "Skipped unknown IP protocol in netstat output"); + continue; + } + + /* Skip the Recv-Q and Send-Q fields */ + for (i = 0; i < 3; i++) + { + if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line)) + { + token = chunk_empty; + break; + } + } + if (token.len == 0) + { + DBG1(DBG_IMC, "Local Address field in netstat output not found"); + goto end; + } + + /* Find the local port appended to the local address */ + pos = token.ptr + token.len; + while (*--pos != ':' && --token.len); + if (*pos != ':') + { + DBG1(DBG_IMC, "Local port field in netstat output not found"); + goto end; + } + + /* convert the port string to an integer */ + new_port = atoi(pos+1); + + /* check if the there is already a port entry */ + enumerator = attr->create_port_enumerator(attr); + while (enumerator->enumerate(enumerator, &allowed, &protocol, &port)) + { + if (new_port == port && new_protocol == protocol) + { + found = TRUE; + } + } + enumerator->destroy(enumerator); + + /* Skip the duplicate port entry */ + if (found) + { + continue; + } + + /* Add new port entry */ + attr->add_port(attr, FALSE, new_protocol, new_port); + } + + /* Successfully completed the parsing of the netstat output */ + success = TRUE; + +end: + /* Close the pipe stream */ + pclose(file); + return success; +} + +static TNC_Result send_message(TNC_ConnectionID connection_id) +{ + pa_tnc_msg_t *msg; + pa_tnc_attr_t *attr; + ietf_attr_port_filter_t *attr_port_filter; + TNC_Result result; + + attr = ietf_attr_port_filter_create(); + attr->set_noskip_flag(attr, TRUE); + attr_port_filter = (ietf_attr_port_filter_t*)attr; + if (!do_netstat(attr_port_filter)) + { + attr->destroy(attr); + return TNC_RESULT_FATAL; + } + msg = pa_tnc_msg_create(); + msg->add_attribute(msg, attr); + msg->build(msg); + result = imc_scanner->send_message(imc_scanner, connection_id, + msg->get_encoding(msg)); + msg->destroy(msg); + + return result; +} + +/** + * see section 3.7.3 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return send_message(connection_id); +} + +/** + * see section 3.7.4 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + pa_tnc_msg_t *pa_tnc_msg; + pa_tnc_attr_t *attr; + enumerator_t *enumerator; + TNC_Result result; + bool fatal_error = FALSE; + + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + /* parse received PA-TNC message and automatically handle any errors */ + result = imc_scanner->receive_message(imc_scanner, connection_id, + chunk_create(msg, msg_len), msg_type, + &pa_tnc_msg); + + /* no parsed PA-TNC attributes available if an error occurred */ + if (!pa_tnc_msg) + { + return result; + } + + /* analyze PA-TNC attributes */ + enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + ietf_attr_pa_tnc_error_t *error_attr; + pa_tnc_error_code_t error_code; + chunk_t msg_info, attr_info; + + if (attr->get_vendor_id(attr) != PEN_IETF && + attr->get_type(attr) != IETF_ATTR_PA_TNC_ERROR) + { + continue; + } + + error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_code = error_attr->get_error_code(error_attr); + msg_info = error_attr->get_msg_info(error_attr); + DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + + switch (error_code) + { + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMC, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + fatal_error = TRUE; + } + enumerator->destroy(enumerator); + pa_tnc_msg->destroy(pa_tnc_msg); + + /* if no error occurred then always return the same response */ + return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id); +} + +/** + * see section 3.7.5 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id, + TNC_ConnectionID connection_id) +{ + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.6 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id) +{ + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + imc_scanner->destroy(imc_scanner); + imc_scanner = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.2 + */ +TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id, + TNC_TNCC_BindFunctionPointer bind_function) +{ + if (!imc_scanner) + { + DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imc_scanner->bind_functions(imc_scanner, bind_function); +} diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner_state.c b/src/libimcv/plugins/imc_scanner/imc_scanner_state.c new file mode 100644 index 000000000..dce7bca13 --- /dev/null +++ b/src/libimcv/plugins/imc_scanner/imc_scanner_state.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 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. + */ + +#include "imc_scanner_state.h" + +#include <debug.h> + +typedef struct private_imc_scanner_state_t private_imc_scanner_state_t; + +/** + * Private data of an imc_scanner_state_t object. + */ +struct private_imc_scanner_state_t { + + /** + * Public members of imc_scanner_state_t + */ + imc_scanner_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; +}; + +METHOD(imc_state_t, get_connection_id, TNC_ConnectionID, + private_imc_scanner_state_t *this) +{ + return this->connection_id; +} + +METHOD(imc_state_t, change_state, void, + private_imc_scanner_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imc_state_t, destroy, void, + private_imc_scanner_state_t *this) +{ + free(this); +} + +/** + * Described in header. + */ +imc_state_t *imc_scanner_state_create(TNC_ConnectionID connection_id) +{ + private_imc_scanner_state_t *this; + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .change_state = _change_state, + .destroy = _destroy, + }, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .connection_id = connection_id, + ); + + return &this->public.interface; +} + + diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner_state.h b/src/libimcv/plugins/imc_scanner/imc_scanner_state.h new file mode 100644 index 000000000..76aa4165b --- /dev/null +++ b/src/libimcv/plugins/imc_scanner/imc_scanner_state.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 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. + */ + +/** + * + * @defgroup imc_scanner_state_t imc_scanner_state + * @{ @ingroup imc_scanner_state + */ + +#ifndef IMC_SCANNER_STATE_H_ +#define IMC_SCANNER_STATE_H_ + +#include <imc/imc_state.h> +#include <library.h> + +typedef struct imc_scanner_state_t imc_scanner_state_t; + +/** + * Internal state of an imc_scanner_t connection instance + */ +struct imc_scanner_state_t { + + /** + * imc_state_t interface + */ + imc_state_t interface; +}; + +/** + * Create an imc_scanner_state_t instance + * + * @param id connection ID + */ +imc_state_t* imc_scanner_state_create(TNC_ConnectionID id); + +#endif /** IMC_SCANNER_STATE_H_ @}*/ diff --git a/src/libimcv/plugins/imv_scanner.c b/src/libimcv/plugins/imv_scanner.c new file mode 100644 index 000000000..276968c38 --- /dev/null +++ b/src/libimcv/plugins/imv_scanner.c @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2011 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. + */ + +#include "imv_scanner_state.h" + +#include <imv/imv_agent.h> +#include <pa_tnc/pa_tnc_msg.h> +#include <ietf/ietf_attr.h> +#include <ietf/ietf_attr_pa_tnc_error.h> +#include <ietf/ietf_attr_port_filter.h> + +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <pen/pen.h> +#include <debug.h> + +/* IMV definitions */ + +static const char imv_name[] = "Scanner"; + +#define IMV_VENDOR_ID PEN_ITA +#define IMV_SUBTYPE PA_SUBTYPE_ITA_SCANNER + +static imv_agent_t *imv_scanner; + +/** + * see section 3.7.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imv_scanner = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE, + imv_id, actual_version); + if (!imv_scanner) + { + return TNC_RESULT_FATAL; + } + if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1) + { + DBG1(DBG_IMV, "no common IF-IMV version"); + return TNC_RESULT_NO_COMMON_VERSION; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.2 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imv_state_t *state; + + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imv_scanner_state_create(connection_id); + return imv_scanner->create_state(imv_scanner, state); + case TNC_CONNECTION_STATE_DELETE: + return imv_scanner->delete_state(imv_scanner, connection_id); + default: + return imv_scanner->change_state(imv_scanner, connection_id, + new_state, NULL); + } +} + +static TNC_Result send_message(TNC_ConnectionID connection_id) +{ + pa_tnc_msg_t *msg; + pa_tnc_attr_t *attr; + TNC_Result result; + + msg = pa_tnc_msg_create(); + msg->build(msg); + result = imv_scanner->send_message(imv_scanner, connection_id, + msg->get_encoding(msg)); + msg->destroy(msg); + + return result; +} + +/** + * see section 3.7.3 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + pa_tnc_msg_t *pa_tnc_msg; + pa_tnc_attr_t *attr; + imv_state_t *state; + enumerator_t *enumerator; + TNC_Result result; + bool fatal_error = FALSE; + + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + /* get current IMV state */ + if (!imv_scanner->get_state(imv_scanner, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + + /* parse received PA-TNC message and automatically handle any errors */ + result = imv_scanner->receive_message(imv_scanner, connection_id, + chunk_create(msg, msg_len), msg_type, + &pa_tnc_msg); + + /* no parsed PA-TNC attributes available if an error occurred */ + if (!pa_tnc_msg) + { + return result; + } + + /* analyze PA-TNC attributes */ + enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + if (attr->get_vendor_id(attr) != PEN_IETF) + { + continue; + } + + if (attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR) + { + ietf_attr_pa_tnc_error_t *error_attr; + pa_tnc_error_code_t error_code; + chunk_t msg_info, attr_info; + + error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_code = error_attr->get_error_code(error_attr); + msg_info = error_attr->get_msg_info(error_attr); + + DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + switch (error_code) + { + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMV, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + fatal_error = TRUE; + } + else if (attr->get_type(attr) == IETF_ATTR_PORT_FILTER) + { + ietf_attr_port_filter_t *attr_port_filter; + enumerator_t *enumerator; + bool blocked; + u_int8_t protocol; + u_int16_t port; + + attr_port_filter = (ietf_attr_port_filter_t*)attr; + enumerator = attr_port_filter->create_port_enumerator(attr_port_filter); + while (enumerator->enumerate(enumerator, &blocked, &protocol, &port)) + { + DBG2(DBG_IMV, "%s: %s %5u", blocked ? "blocked" : "allowed", + (protocol == IPPROTO_TCP) ? "tcp" : "udp", port); + } + enumerator->destroy(enumerator); + } + } + enumerator->destroy(enumerator); + pa_tnc_msg->destroy(pa_tnc_msg); + + if (fatal_error) + { + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + TNC_IMV_EVALUATION_RESULT_ERROR); + return imv_scanner->provide_recommendation(imv_scanner, connection_id); + } + + return imv_scanner->provide_recommendation(imv_scanner, connection_id); +} + +/** + * see section 3.7.4 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_scanner->provide_recommendation(imv_scanner, connection_id); +} + +/** + * see section 3.7.5 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.6 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + imv_scanner->destroy(imv_scanner); + imv_scanner = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id, + TNC_TNCS_BindFunctionPointer bind_function) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_scanner->bind_functions(imv_scanner, bind_function); +} diff --git a/src/libimcv/plugins/imv_scanner/Makefile.am b/src/libimcv/plugins/imv_scanner/Makefile.am new file mode 100644 index 000000000..9d77a0c46 --- /dev/null +++ b/src/libimcv/plugins/imv_scanner/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libimcv + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-imv-scanner.la + +libstrongswan_imv_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la + +libstrongswan_imv_scanner_la_SOURCES = imv_scanner.c \ + imv_scanner_state.h imv_scanner_state.c + +libstrongswan_imv_scanner_la_LDFLAGS = -module -avoid-version + diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner.c b/src/libimcv/plugins/imv_scanner/imv_scanner.c new file mode 100644 index 000000000..d23e8880a --- /dev/null +++ b/src/libimcv/plugins/imv_scanner/imv_scanner.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2011 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. + */ + +#include "imv_scanner_state.h" + +#include <imv/imv_agent.h> +#include <pa_tnc/pa_tnc_msg.h> +#include <ietf/ietf_attr.h> +#include <ietf/ietf_attr_pa_tnc_error.h> +#include <ietf/ietf_attr_port_filter.h> + +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <pen/pen.h> +#include <utils/linked_list.h> +#include <utils/lexparser.h> +#include <debug.h> + +/* IMV definitions */ + +static const char imv_name[] = "Scanner"; + +#define IMV_VENDOR_ID PEN_ITA +#define IMV_SUBTYPE PA_SUBTYPE_ITA_SCANNER + +static imv_agent_t *imv_scanner; + +typedef struct port_range_t port_range_t; + +struct port_range_t { + u_int16_t start, stop; +}; + + +/** + * Default port policy + * + * TRUE: all server ports on the TNC client must be closed + * FALSE: any server port on the TNC client is allowed to be open + */ +static bool closed_port_policy = TRUE; + +/** + * List of TCP and UDP port ranges + * + * TRUE: server ports on the TNC client that are allowed to be open + * FALSE: server ports on the TNC client that must be closed + */ +static linked_list_t *tcp_ports, *udp_ports; + +/** + * Get a TCP or UDP port list from strongswan.conf + */ +static linked_list_t* get_port_list(char *label) +{ + char key[40], *value; + linked_list_t *list; + chunk_t port_list, port_item, port_stop; + port_range_t *port_range; + + list = linked_list_create(); + + snprintf(key, sizeof(key), "libimcv.plugins.imv-scanner.%s_ports", label); + value = lib->settings->get_str(lib->settings, key, NULL); + if (!value) + { + DBG1(DBG_IMV, "% not defined", key); + return list; + } + port_list = chunk_create(value, strlen(value)); + DBG2(DBG_IMV, "list of %s ports that %s:", label, + closed_port_policy ? "are allowed to be open" : "must be closed"); + + while (eat_whitespace(&port_list)) + { + if (!extract_token(&port_item, ' ', &port_list)) + { + /* reached last port item */ + port_item = port_list; + port_list = chunk_empty; + } + port_range = malloc_thing(port_range_t); + port_range->start = atoi(port_item.ptr);; + + if (extract_token(&port_stop, '-', &port_item)) + { + port_range->stop = atoi(port_stop.ptr); + } + else + { + port_range->stop = port_range->start; + } + DBG2(DBG_IMV, "%5u - %5u", port_range->start, port_range->stop); + list->insert_last(list, port_range); + } + + return list; +} + + +/* + * see section 3.7.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id, + TNC_Version min_version, + TNC_Version max_version, + TNC_Version *actual_version) +{ + if (imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name); + return TNC_RESULT_ALREADY_INITIALIZED; + } + imv_scanner = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE, + imv_id, actual_version); + if (!imv_scanner) + { + return TNC_RESULT_FATAL; + } + if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1) + { + DBG1(DBG_IMV, "no common IF-IMV version"); + return TNC_RESULT_NO_COMMON_VERSION; + } + + /* set the default port policy to closed (TRUE) or open (FALSE) */ + closed_port_policy = lib->settings->get_bool(lib->settings, + "libimcv.plugins.imv-scanner.closed_port_policy", TRUE); + DBG2(DBG_IMV, "default port policy is %s ports", + closed_port_policy ? "closed" : "open"); + + /* get the list of open|closed ports */ + tcp_ports = get_port_list("tcp"); + udp_ports = get_port_list("udp"); + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.2 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_ConnectionState new_state) +{ + imv_state_t *state; + + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + switch (new_state) + { + case TNC_CONNECTION_STATE_CREATE: + state = imv_scanner_state_create(connection_id); + return imv_scanner->create_state(imv_scanner, state); + case TNC_CONNECTION_STATE_DELETE: + return imv_scanner->delete_state(imv_scanner, connection_id); + default: + return imv_scanner->change_state(imv_scanner, connection_id, + new_state, NULL); + } +} + +/** + * see section 3.7.3 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) +{ + pa_tnc_msg_t *pa_tnc_msg; + pa_tnc_attr_t *attr; + imv_state_t *state; + enumerator_t *enumerator; + TNC_Result result; + bool fatal_error = FALSE; + + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + + /* get current IMV state */ + if (!imv_scanner->get_state(imv_scanner, connection_id, &state)) + { + return TNC_RESULT_FATAL; + } + + /* parse received PA-TNC message and automatically handle any errors */ + result = imv_scanner->receive_message(imv_scanner, connection_id, + chunk_create(msg, msg_len), msg_type, + &pa_tnc_msg); + + /* no parsed PA-TNC attributes available if an error occurred */ + if (!pa_tnc_msg) + { + return result; + } + + /* analyze PA-TNC attributes */ + enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + if (attr->get_vendor_id(attr) != PEN_IETF) + { + continue; + } + + if (attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR) + { + ietf_attr_pa_tnc_error_t *error_attr; + pa_tnc_error_code_t error_code; + chunk_t msg_info, attr_info; + + error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_code = error_attr->get_error_code(error_attr); + msg_info = error_attr->get_msg_info(error_attr); + DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + + switch (error_code) + { + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMV, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + fatal_error = TRUE; + } + else if (attr->get_type(attr) == IETF_ATTR_PORT_FILTER) + { + ietf_attr_port_filter_t *attr_port_filter; + enumerator_t *enumerator; + u_int8_t protocol; + u_int16_t port; + char buf[BUF_LEN], *pos = buf; + size_t len = BUF_LEN; + bool blocked, compliant = TRUE; + + attr_port_filter = (ietf_attr_port_filter_t*)attr; + enumerator = attr_port_filter->create_port_enumerator(attr_port_filter); + while (enumerator->enumerate(enumerator, &blocked, &protocol, &port)) + { + enumerator_t *e; + port_range_t *port_range; + bool passed, found = FALSE; + int written = 0; + + if (blocked) + { + /* ignore closed ports */ + continue; + } + + e = (protocol == IPPROTO_TCP) ? + tcp_ports->create_enumerator(tcp_ports) : + udp_ports->create_enumerator(udp_ports); + while (e->enumerate(e, &port_range)) + { + if (port >= port_range->start && port <= port_range->stop) + { + found = TRUE; + break; + } + } + e->destroy(e); + + passed = (closed_port_policy == found); + DBG2(DBG_IMV, "%s port %5u %s: %s", + (protocol == IPPROTO_TCP) ? "tcp" : "udp", port, + blocked ? "closed" : "open", passed ? "ok" : "fatal"); + if (!passed) + { + compliant = FALSE; + written = snprintf(pos, len, " %s/%u", + (protocol == IPPROTO_TCP) ? "tcp" : "udp", + port); + if (written < 0 || written >= len) + { + break; + } + pos += written; + len -= written; + } + } + enumerator->destroy(enumerator); + + if (compliant) + { + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_ALLOW, + TNC_IMV_EVALUATION_RESULT_COMPLIANT); + } + else + { + imv_scanner_state_t *imv_scanner_state; + + imv_scanner_state = (imv_scanner_state_t*)state; + imv_scanner_state->set_violating_ports(imv_scanner_state, buf); + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS, + TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR); + } + } + } + enumerator->destroy(enumerator); + pa_tnc_msg->destroy(pa_tnc_msg); + + if (fatal_error) + { + state->set_recommendation(state, + TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + TNC_IMV_EVALUATION_RESULT_ERROR); + return imv_scanner->provide_recommendation(imv_scanner, connection_id); + } + + return imv_scanner->provide_recommendation(imv_scanner, connection_id); +} + +/** + * see section 3.7.4 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_scanner->provide_recommendation(imv_scanner, connection_id); +} + +/** + * see section 3.7.5 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, + TNC_ConnectionID connection_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return TNC_RESULT_SUCCESS; +} + +/** + * see section 3.7.6 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + tcp_ports->destroy_function(tcp_ports, free); + udp_ports->destroy_function(udp_ports, free); + imv_scanner->destroy(imv_scanner); + imv_scanner = NULL; + + return TNC_RESULT_SUCCESS; +} + +/** + * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.2 + */ +TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id, + TNC_TNCS_BindFunctionPointer bind_function) +{ + if (!imv_scanner) + { + DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); + return TNC_RESULT_NOT_INITIALIZED; + } + return imv_scanner->bind_functions(imv_scanner, bind_function); +} diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c new file mode 100644 index 000000000..95383aa80 --- /dev/null +++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2011 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. + */ + +#include "imv_scanner_state.h" + +#include <utils/lexparser.h> +#include <debug.h> + +typedef struct private_imv_scanner_state_t private_imv_scanner_state_t; + +/** + * Private data of an imv_scanner_state_t object. + */ +struct private_imv_scanner_state_t { + + /** + * Public members of imv_scanner_state_t + */ + imv_scanner_state_t public; + + /** + * TNCCS connection ID + */ + TNC_ConnectionID connection_id; + + /** + * TNCCS connection state + */ + TNC_ConnectionState state; + + /** + * IMV action recommendation + */ + TNC_IMV_Action_Recommendation rec; + + /** + * IMV evaluation result + */ + TNC_IMV_Evaluation_Result eval; + + /** + * String with list of ports that should be closed + */ + char *violating_ports; + + /** + * Local copy of the reason string + */ + chunk_t reason_string; +}; + +typedef struct entry_t entry_t; + +/** + * Define an internal reason string entry + */ +struct entry_t { + char *lang; + char *string; +}; + +/** + * Table of multi-lingual reason string entries + */ +static entry_t reasons[] = { + { "en", "The following ports are open:" }, + { "de", "Die folgenden Ports sind offen" }, + { "fr", "Les ports suivants sont ouverts:" }, + { "pl", "Nastepujace porty sa otwarte:" } +}; + +METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, + private_imv_scanner_state_t *this) +{ + return this->connection_id; +} + +METHOD(imv_state_t, change_state, void, + private_imv_scanner_state_t *this, TNC_ConnectionState new_state) +{ + this->state = new_state; +} + +METHOD(imv_state_t, get_recommendation, void, + private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec, + TNC_IMV_Evaluation_Result *eval) +{ + *rec = this->rec; + *eval = this->eval; +} + +METHOD(imv_state_t, set_recommendation, void, + private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec, + TNC_IMV_Evaluation_Result eval) +{ + this->rec = rec; + this->eval = eval; +} + +METHOD(imv_state_t, get_reason_string, bool, + private_imv_scanner_state_t *this, chunk_t preferred_language, + chunk_t *reason_string, chunk_t *reason_language) +{ + chunk_t pref_lang, lang; + u_char *pos; + int i; + + while (eat_whitespace(&preferred_language)) + { + if (!extract_token(&pref_lang, ',', &preferred_language)) + { + /* last entry in a comma-separated list or single entry */ + pref_lang = preferred_language; + } + + /* eat trailing whitespace */ + pos = pref_lang.ptr + pref_lang.len - 1; + while (pref_lang.len && *pos-- == ' ') + { + pref_lang.len--; + } + + for (i = 0 ; i < countof(reasons); i++) + { + lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang)); + if (chunk_equals(lang, pref_lang)) + { + this->reason_string = chunk_cat("cc", + chunk_create(reasons[i].string, + strlen(reasons[i].string)), + chunk_create(this->violating_ports, + strlen(this->violating_ports))); + *reason_string = this->reason_string; + *reason_language = lang; + return TRUE; + } + } + } + + /* no preferred language match found - use the default language */ + + this->reason_string = chunk_cat("cc", + chunk_create(reasons[0].string, + strlen(reasons[0].string)), + chunk_create(this->violating_ports, + strlen(this->violating_ports))); + *reason_string = this->reason_string; + *reason_language = chunk_create(reasons[0].lang, + strlen(reasons[0].lang)); + return TRUE; +} + +METHOD(imv_state_t, destroy, void, + private_imv_scanner_state_t *this) +{ + free(this->violating_ports); + free(this->reason_string.ptr); + free(this); +} + +METHOD(imv_scanner_state_t, set_violating_ports, void, + private_imv_scanner_state_t *this, char *ports) +{ + this->violating_ports = strdup(ports); +} + +/** + * Described in header. + */ +imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id) +{ + private_imv_scanner_state_t *this; + + INIT(this, + .public = { + .interface = { + .get_connection_id = _get_connection_id, + .change_state = _change_state, + .get_recommendation = _get_recommendation, + .set_recommendation = _set_recommendation, + .get_reason_string = _get_reason_string, + .destroy = _destroy, + }, + .set_violating_ports = _set_violating_ports, + }, + .state = TNC_CONNECTION_STATE_CREATE, + .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, + .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW, + .connection_id = connection_id, + ); + + return &this->public.interface; +} + + diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.h b/src/libimcv/plugins/imv_scanner/imv_scanner_state.h new file mode 100644 index 000000000..716ddfea0 --- /dev/null +++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 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. + */ + +/** + * + * @defgroup imv_scanner_state_t imv_scanner_state + * @{ @ingroup imv_scanner_state + */ + +#ifndef IMV_SCANNER_STATE_H_ +#define IMV_SCANNER_STATE_H_ + +#include <imv/imv_state.h> +#include <library.h> + +typedef struct imv_scanner_state_t imv_scanner_state_t; + +/** + * Internal state of an imv_scanner_t connection instance + */ +struct imv_scanner_state_t { + + /** + * imv_state_t interface + */ + imv_state_t interface; + + /** + * list of violating TCP and UDP ports + */ + void (*set_violating_ports)(imv_scanner_state_t *this, char *ports); +}; + +/** + * Create an imv_scanner_state_t instance + * + * @param id connection ID + */ +imv_state_t* imv_scanner_state_create(TNC_ConnectionID id); + +#endif /** IMV_SCANNER_STATE_H_ @}*/ diff --git a/src/libtncif/tncif_pa_subtypes.c b/src/libtncif/tncif_pa_subtypes.c index adf501eed..858308ece 100644 --- a/src/libtncif/tncif_pa_subtypes.c +++ b/src/libtncif/tncif_pa_subtypes.c @@ -47,8 +47,9 @@ ENUM_NEXT(pa_subtype_fhh_names, PA_SUBTYPE_FHH_CLAMAV, PA_SUBTYPE_FHH_CLAMAV, ); ENUM_END(pa_subtype_fhh_names, PA_SUBTYPE_FHH_CLAMAV); -ENUM(pa_subtype_ita_names, PA_SUBTYPE_ITA_TEST, PA_SUBTYPE_ITA_TEST, - "Test" +ENUM(pa_subtype_ita_names, PA_SUBTYPE_ITA_TEST, PA_SUBTYPE_ITA_SCANNER, + "Test", + "Scanner" ); /** diff --git a/src/libtncif/tncif_pa_subtypes.h b/src/libtncif/tncif_pa_subtypes.h index 27546430b..771971338 100644 --- a/src/libtncif/tncif_pa_subtypes.h +++ b/src/libtncif/tncif_pa_subtypes.h @@ -75,7 +75,8 @@ extern enum_name_t *pa_subtype_fhh_names; * PA-TNC ITA-HSR Subtypes */ enum pa_subtype_ita_t { - PA_SUBTYPE_ITA_TEST = 1 + PA_SUBTYPE_ITA_TEST = 1, + PA_SUBTYPE_ITA_SCANNER = 2 }; /** diff --git a/testing/scripts/build-umlrootfs b/testing/scripts/build-umlrootfs index 03ef748fc..75fe5c69f 100755 --- a/testing/scripts/build-umlrootfs +++ b/testing/scripts/build-umlrootfs @@ -227,6 +227,16 @@ then echo -n " --enable-imv-test" >> $INSTALLSHELL fi +if [ "$USE_IMC_SCANNER" = "yes" ] +then + echo -n " --enable-imc-scanner" >> $INSTALLSHELL +fi + +if [ "$USE_IMV_SCANNER" = "yes" ] +then + echo -n " --enable-imv-scanner" >> $INSTALLSHELL +fi + if [ "$USE_SQL" = "yes" ] then echo -n " --enable-sql --enable-sqlite" >> $INSTALLSHELL diff --git a/testing/testing.conf b/testing/testing.conf index 075f43cf1..aff92bdd7 100755 --- a/testing/testing.conf +++ b/testing/testing.conf @@ -53,6 +53,8 @@ USE_TNCCS_20="yes" USE_TNCCS_DYNAMIC="yes" USE_IMC_TEST="yes" USE_IMV_TEST="yes" +USE_IMC_SCANNER="yes" +USE_IMV_SCANNER="yes" USE_SQL="yes" USE_MEDIATION="yes" USE_OPENSSL="yes" |