]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Added ITA Start/Stop Angel attributes to split bulk data into multiple attributes
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 5 Nov 2012 09:24:12 +0000 (10:24 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 5 Nov 2012 09:24:12 +0000 (10:24 +0100)
src/libimcv/Makefile.am
src/libimcv/ita/ita_attr.c
src/libimcv/ita/ita_attr.h
src/libimcv/ita/ita_attr_angel.c [new file with mode: 0644]
src/libimcv/ita/ita_attr_angel.h [new file with mode: 0644]
src/libimcv/plugins/imc_os/imc_os.c
src/libimcv/plugins/imv_os/imv_os.c
src/libimcv/plugins/imv_os/imv_os_state.c
src/libimcv/plugins/imv_os/imv_os_state.h

index 4f0e000512385b2918ab112b2e0585a4bf4abed8..39b6b1d7c9ff31135d602e7b148145682c9d12ca 100644 (file)
@@ -29,6 +29,7 @@ libimcv_la_SOURCES = \
        ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
        ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
        ita/ita_attr_settings.h ita/ita_attr_settings.c \
+       ita/ita_attr_angel.h ita/ita_attr_angel.c \
        os_info/os_info.h os_info/os_info.c \
        pa_tnc/pa_tnc_attr.h \
        pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
index cc5f648b5251f2d63446e95eb2a04bdf0e305271..09754aed6c3a957b00fe962730a473b5dda540fa 100644 (file)
 #include "ita/ita_attr_dummy.h"
 #include "ita/ita_attr_get_settings.h"
 #include "ita/ita_attr_settings.h"
+#include "ita/ita_attr_angel.h"
 
-ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_SETTINGS,
+ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_STOP_ANGEL,
        "Command",
        "Dummy",
        "Get Settings",
-       "Settings"
+       "Settings",
+       "Start Angel",
+       "Stop Angel"
 );
 
 /**
@@ -41,6 +44,10 @@ pa_tnc_attr_t* ita_attr_create_from_data(u_int32_t type, chunk_t value)
                        return ita_attr_get_settings_create_from_data(value);
                case ITA_ATTR_SETTINGS:
                        return ita_attr_settings_create_from_data(value);
+               case ITA_ATTR_START_ANGEL:
+                       return ita_attr_angel_create_from_data(TRUE, value);
+               case ITA_ATTR_STOP_ANGEL:
+                       return ita_attr_angel_create_from_data(FALSE, value);
                default:
                        return NULL;
        }
index ae964a2ed18b991e35cccd0cdc85a2e35428f5da..d7b06146f7e44f328eb3045f2a806af32e5f0d6c 100644 (file)
@@ -35,6 +35,8 @@ enum ita_attr_t {
        ITA_ATTR_DUMMY = 2,
        ITA_ATTR_GET_SETTINGS = 3,
        ITA_ATTR_SETTINGS = 4,
+       ITA_ATTR_START_ANGEL = 5,
+       ITA_ATTR_STOP_ANGEL = 6
 };
 
 /**
diff --git a/src/libimcv/ita/ita_attr_angel.c b/src/libimcv/ita/ita_attr_angel.c
new file mode 100644 (file)
index 0000000..0e9cff0
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012 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 "ita_attr.h"
+#include "ita_attr_angel.h"
+
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
+#include <collections/linked_list.h>
+#include <pen/pen.h>
+#include <utils/debug.h>
+
+typedef struct private_ita_attr_angel_t private_ita_attr_angel_t;
+
+/**
+ * Private data of an ita_attr_angel_t object.
+ */
+struct private_ita_attr_angel_t {
+
+       /**
+        * Public members of ita_attr_angel_t
+        */
+       ita_attr_angel_t public;
+
+       /**
+        * Vendor-specific attribute type
+        */
+       pen_type_t type;
+
+       /**
+        * Noskip flag
+        */
+       bool noskip_flag;
+
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+       private_ita_attr_angel_t *this)
+{
+       return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+       private_ita_attr_angel_t *this)
+{
+       return chunk_empty;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+       private_ita_attr_angel_t *this)
+{
+       return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+       private_ita_attr_angel_t *this, bool noskip)
+{
+       this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+       private_ita_attr_angel_t *this)
+{
+       /* nothing to build */
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+       private_ita_attr_angel_t *this, u_int32_t *offset)
+{
+       return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+       private_ita_attr_angel_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+       private_ita_attr_angel_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               free(this);
+       }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_angel_create(bool start)
+{
+       private_ita_attr_angel_t *this;
+
+       INIT(this,
+               .public = {
+                       .pa_tnc_attribute = {
+                               .get_type = _get_type,
+                               .get_value = _get_value,
+                               .get_noskip_flag = _get_noskip_flag,
+                               .set_noskip_flag = _set_noskip_flag,
+                               .build = _build,
+                               .process = _process,
+                               .get_ref = _get_ref,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = { PEN_ITA, start ? ITA_ATTR_START_ANGEL : ITA_ATTR_STOP_ANGEL },
+               .ref = 1,
+       );
+
+       return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_angel_create_from_data(bool start, chunk_t data)
+{
+       private_ita_attr_angel_t *this;
+
+       INIT(this,
+               .public = {
+                       .pa_tnc_attribute = {
+                               .get_type = _get_type,
+                               .get_value = _get_value,
+                               .get_noskip_flag = _get_noskip_flag,
+                               .set_noskip_flag = _set_noskip_flag,
+                               .build = _build,
+                               .process = _process,
+                               .get_ref = _get_ref,
+                               .destroy = _destroy,
+                       },
+               },
+               .type = { PEN_ITA, start ? ITA_ATTR_START_ANGEL : ITA_ATTR_STOP_ANGEL },
+               .ref = 1,
+       );
+
+       return &this->public.pa_tnc_attribute;
+}
+
+
diff --git a/src/libimcv/ita/ita_attr_angel.h b/src/libimcv/ita/ita_attr_angel.h
new file mode 100644 (file)
index 0000000..c392f79
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 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 ita_attr_angelt ita_attr_angel
+ * @{ @ingroup ita_attr_angel
+ */
+
+#ifndef ITA_ATTR_ANGEL_H_
+#define ITA_ATTR_ANGEL_H_
+
+typedef struct ita_attr_angel_t ita_attr_angel_t;
+
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the ITA Start/Stop Angel PA-TNC attribute.
+ *
+ */
+struct ita_attr_angel_t {
+
+       /**
+        * Public PA-TNC attribute interface
+        */
+       pa_tnc_attr_t pa_tnc_attribute;
+
+};
+
+/**
+ * Creates an ita_attr_angel_t object with an empty settings list
+ *
+ * @param start                                TRUE for Start, FALSE for Stop Angel attribute
+ */
+pa_tnc_attr_t* ita_attr_angel_create(bool start);
+
+/**
+ * Creates an ita_attr_angel_t object from received data
+ *
+ * @param start                                TRUE for Start, FALSE for Stop Angel attribute
+ * @param value                                binary value blob
+ */
+pa_tnc_attr_t* ita_attr_angel_create_from_data(bool start, chunk_t value);
+
+#endif /** ITA_ATTR_ANGEL_H_ @}*/
index abbe8513ad742d0f2efc63511fc21b08e4cf426d..4ebe55269c119704ae9a85c5f156463d79ecacd2 100644 (file)
@@ -30,6 +30,7 @@
 #include <ita/ita_attr.h>
 #include <ita/ita_attr_get_settings.h>
 #include <ita/ita_attr_settings.h>
+#include <ita/ita_attr_angel.h>
 #include <os_info/os_info.h>
 
 #include <tncif_pa_subtypes.h>
@@ -235,11 +236,12 @@ static void add_default_pwd_enabled(imc_msg_t *msg)
  */
 static void add_installed_packages(imc_msg_t *msg)
 {
-       pa_tnc_attr_t *attr = NULL;
+       pa_tnc_attr_t *attr = NULL, *attr_angel;
        ietf_attr_installed_packages_t *attr_cast;
        enumerator_t *enumerator;
        chunk_t name, version;
        size_t attr_size = 0;
+       bool first = TRUE;
 
        enumerator = os->create_package_enumerator(os);
        if (!enumerator)
@@ -259,6 +261,16 @@ static void add_installed_packages(imc_msg_t *msg)
                attr_size += 2 + name.len + version.len;
                if (attr_size > 20000)
                {
+                       if (first)
+                       {
+                               /**
+                                * Send an ITA Start Angel attribute to the IMV signalling that
+                                * there are multiple ITA Installed Package attributes to come.
+                                */
+                               attr_angel = ita_attr_angel_create(TRUE);
+                               msg->add_attribute(msg, attr_angel);
+                               first = FALSE;
+                       }
                        msg->add_attribute(msg, attr);
                        attr_size = 0;
                }
@@ -269,6 +281,15 @@ static void add_installed_packages(imc_msg_t *msg)
        {
                msg->add_attribute(msg, attr);
        }
+       if (!first)
+       {
+               /**
+                * If we sent an ITA Start Angel attribute in the first place,
+                * terminate by appending a matching ITA Stop Angel attribute.
+                */
+               attr_angel = ita_attr_angel_create(FALSE);
+               msg->add_attribute(msg, attr_angel);
+       }
 }
 
 /**
index 663914b323c59a145f0a3f728c32e527e82c75ae..1e1cbe24aec58fea3646a59c6df0affcb4e2342e 100644 (file)
@@ -31,6 +31,7 @@
 #include <ita/ita_attr.h>
 #include <ita/ita_attr_get_settings.h>
 #include <ita/ita_attr_settings.h>
+#include <ita/ita_attr_angel.h>
 
 #include <tncif_names.h>
 #include <tncif_pa_subtypes.h>
@@ -134,6 +135,7 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
        chunk_t os_version = chunk_empty;
        bool fatal_error = FALSE, assessment = FALSE;
 
+       os_state = (imv_os_state_t*)state;
 
        /* parse received PA-TNC message and handle local and remote errors */
        result = in_msg->receive(in_msg, &fatal_error);
@@ -251,31 +253,44 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                        }
                                        e->destroy(e);
 
-                                       state->set_recommendation(state,
-                                                                                 TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
-                                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT);
-                                       assessment = TRUE;
+                                       /* Received at least one Installed Packages attribute */
+                                       os_state->set_package_request(os_state, FALSE);
                                        break;
                                }
                                default:
                                        break;
                        }
                }
-               else if (type.vendor_id == PEN_ITA && type.type == ITA_ATTR_SETTINGS)
+               else if (type.vendor_id == PEN_ITA)
                {
-                       ita_attr_settings_t *attr_cast;
-                       enumerator_t *e;
-                       char *name;
-                       chunk_t value;
-
-                       attr_cast = (ita_attr_settings_t*)attr;
-                       e = attr_cast->create_enumerator(attr_cast);
-                       while (e->enumerate(e, &name, &value))
+                       switch (type.type)
                        {
-                               DBG1(DBG_IMV, "setting '%s'", name);
-                               dbg_imv_multi_line(value);
+                               case ITA_ATTR_SETTINGS:
+                               {
+                                       ita_attr_settings_t *attr_cast;
+                                       enumerator_t *e;
+                                       char *name;
+                                       chunk_t value;
+
+                                       attr_cast = (ita_attr_settings_t*)attr;
+                                       e = attr_cast->create_enumerator(attr_cast);
+                                       while (e->enumerate(e, &name, &value))
+                                       {
+                                               DBG1(DBG_IMV, "setting '%s'", name);
+                                               dbg_imv_multi_line(value);
+                                       }
+                                       e->destroy(e);
+                                       break;
+                               }
+                               case ITA_ATTR_START_ANGEL:
+                                       os_state->set_angel_count(os_state, TRUE);
+                                       break;
+                               case ITA_ATTR_STOP_ANGEL:
+                                       os_state->set_angel_count(os_state, FALSE);
+                                       break;
+                               default:
+                                       break;
                        }
-                       e->destroy(e);
                }
        }
        enumerator->destroy(enumerator);
@@ -287,7 +302,6 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                char *string = "use a Linux operating system instead of Windows 1.2.3";
                char *lang_code = "en";
 
-               os_state = (imv_os_state_t*)state;
                os_state->set_info(os_state, os_name, os_version);
                product_info = os_state->get_info(os_state);
 
@@ -314,6 +328,7 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
 
                        DBG1(DBG_IMV, "requesting installed packages for '%s'",
                                                   product_info);
+                       os_state->set_package_request(os_state, TRUE);
                        attr = ietf_attr_attr_request_create(PEN_IETF,
                                                                IETF_ATTR_INSTALLED_PACKAGES);
                        out_msg->add_attribute(out_msg, attr);
@@ -344,6 +359,15 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                assessment = TRUE;
        }
 
+       /* If all Installed Packages attributes were received, go to assessment */
+       if (!os_state->get_package_request(os_state) &&
+               !os_state->get_angel_count(os_state))
+       {
+               state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+                                                                                TNC_IMV_EVALUATION_RESULT_COMPLIANT);
+               assessment = TRUE;
+       }
+
        if (assessment)
        {
                result = out_msg->send_assessment(out_msg);
index e36d4aeb1ac8097b34a9f371977ff671dfcdd6cc..05a3bf65a14c0c0a83a9b2715d42b49600947340 100644 (file)
@@ -68,6 +68,17 @@ struct private_imv_os_state_t {
         * OS Product Information
         */
        char *info;
+
+       /**
+        * OS Installed Package request sent - mandatory response expected
+        */
+       bool package_request;
+
+       /**
+        * Angel count
+        */
+       int angel_count;
+
 };
 
 typedef struct entry_t entry_t;
@@ -181,6 +192,30 @@ METHOD(imv_os_state_t, get_info, char*,
        return this->info;
 }
 
+METHOD(imv_os_state_t, set_package_request, void,
+       private_imv_os_state_t *this, bool set)
+{
+       this->package_request = set;
+}
+
+METHOD(imv_os_state_t, get_package_request, bool,
+       private_imv_os_state_t *this)
+{
+       return this->package_request;
+}
+
+METHOD(imv_os_state_t, set_angel_count, void,
+       private_imv_os_state_t *this, bool start)
+{
+       this->angel_count += start ? 1 : -1;
+}
+
+METHOD(imv_os_state_t, get_angel_count, int,
+       private_imv_os_state_t *this)
+{
+       return this->angel_count;
+}
+
 /**
  * Described in header.
  */
@@ -205,6 +240,10 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                        },
                        .set_info = _set_info,
                        .get_info = _get_info,
+                       .set_package_request = _set_package_request,
+                       .get_package_request = _get_package_request,
+                       .set_angel_count = _set_angel_count,
+                       .get_angel_count = _get_angel_count,
                },
                .state = TNC_CONNECTION_STATE_CREATE,
                .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
index 2d20692209b4304e6fcccfce8b8a29e6dec1c17e..47684fe8344f5957bce6d2097d273390c56aa334 100644 (file)
@@ -52,6 +52,34 @@ struct imv_os_state_t {
         */
        char* (*get_info)(imv_os_state_t *this);
 
+       /**
+        * Set/reset OS Installed Packages request status
+        *
+        * @param set           TRUE to set, FALSE to clear
+        */
+       void (*set_package_request)(imv_os_state_t *this, bool set);
+
+       /**
+        * Get OS Installed Packages request status
+        *
+        * @result                      TRUE if set, FALSE if unset
+        */
+       bool (*get_package_request)(imv_os_state_t *this);
+
+       /**
+        * Increase/Decrease the ITA Angel count
+        *
+        * @param start                 TRUE increases and FALSE decreases count by one
+        */
+       void (*set_angel_count)(imv_os_state_t *this, bool start);
+
+       /**
+        * Get the ITA Angel count
+        *
+        * @result                      ITA Angel count
+        */
+       int (*get_angel_count)(imv_os_state_t *this);
+
 };
 
 /**