implemented sending of reason strings
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 13 Jun 2011 13:31:34 +0000 (15:31 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 13 Jun 2011 13:31:34 +0000 (15:31 +0200)
src/libimcv/imv/imv_agent.c
src/libimcv/imv/imv_agent.h
src/libimcv/imv/imv_state.h
src/libimcv/plugins/imv_test/imv_test_state.c

index 2df4fea..664dedd 100644 (file)
@@ -100,6 +100,41 @@ struct private_imv_agent_t {
                                                                                 TNC_IMV_Action_Recommendation rec,
                                                                                 TNC_IMV_Evaluation_Result eval);
 
+       /**
+        * Get the value of an attribute associated with a connection
+        * or with the TNCS as a whole.
+        *
+        * @param imv_id                        IMV ID assigned by TNCS
+        * @param connection_id         network connection ID assigned by TNCS
+        * @param attribute_id          attribute ID
+        * @param buffer_len            length of buffer in bytes
+        * @param buffer                        buffer
+        * @param out_value_len         size in bytes of attribute stored in buffer
+        * @return                                      TNC result code
+        */
+       TNC_Result (*get_attribute)(TNC_IMVID imv_id,
+                                                               TNC_ConnectionID connection_id,
+                                                               TNC_AttributeID attribute_id,
+                                                               TNC_UInt32 buffer_len,
+                                                               TNC_BufferReference buffer,
+                                                               TNC_UInt32 *out_value_len);
+
+       /**
+        * Set the value of an attribute associated with a connection
+        * or with the TNCS as a whole.
+        *
+        * @param imv_id                        IMV ID assigned by TNCS
+        * @param connection_id         network connection ID assigned by TNCS
+        * @param attribute_id          attribute ID
+        * @param buffer_len            length of buffer in bytes
+        * @param buffer                        buffer
+        * @return                                      TNC result code
+        */
+       TNC_Result (*set_attribute)(TNC_IMVID imv_id,
+                                                               TNC_ConnectionID connection_id,
+                                                               TNC_AttributeID attribute_id,
+                                                               TNC_UInt32 buffer_len,
+                                                               TNC_BufferReference buffer);
 };
 
 METHOD(imv_agent_t, bind_functions, TNC_Result,
@@ -131,14 +166,14 @@ METHOD(imv_agent_t, bind_functions, TNC_Result,
                this->provide_recommendation = NULL;
        }
        if (bind_function(this->id, "TNC_TNCS_GetAttribute",
-                       (void**)&this->public.get_attribute) != TNC_RESULT_SUCCESS)
+                       (void**)&this->get_attribute) != TNC_RESULT_SUCCESS)
        {
-               this->public.get_attribute = NULL;
+               this->get_attribute = NULL;
        }
        if (bind_function(this->id, "TNC_TNCS_SetAttribute",
-                       (void**)&this->public.set_attribute) != TNC_RESULT_SUCCESS)
+                       (void**)&this->set_attribute) != TNC_RESULT_SUCCESS)
        {
-               this->public.set_attribute = NULL;
+               this->set_attribute = NULL;
        }
        DBG2(DBG_IMV, "IMV %u \"%s\" provided with bind function",
                                  this->id, this->name);
@@ -317,6 +352,7 @@ METHOD(imv_agent_t, set_recommendation, TNC_Result,
                                          this->id, this->name, connection_id);
                return TNC_RESULT_FATAL;
        }
+
        state->set_recommendation(state, rec, eval);
        return this->provide_recommendation(this->id, connection_id, rec, eval);
 }
@@ -384,7 +420,10 @@ METHOD(imv_agent_t, provide_recommendation, TNC_Result,
        imv_state_t *state;
        TNC_IMV_Action_Recommendation rec;
        TNC_IMV_Evaluation_Result eval;
-       
+       TNC_UInt32 lang_len;
+       char buf[BUF_LEN];
+       chunk_t pref_lang = { buf, 0 }, reason_string, reason_lang;
+
        state = find_connection(this, connection_id);
        if (!state)
        {
@@ -392,6 +431,31 @@ METHOD(imv_agent_t, provide_recommendation, TNC_Result,
                                          this->id, this->name, connection_id);
                return TNC_RESULT_FATAL;
        }
+
+       /* check if there a preferred language has been requested */
+       if (this->get_attribute  &&
+               this->get_attribute(this->id, connection_id,
+                                                       TNC_ATTRIBUTEID_PREFERRED_LANGUAGE, BUF_LEN,
+                                                       buf, &lang_len) == TNC_RESULT_SUCCESS &&
+               lang_len <= BUF_LEN)
+       {
+               pref_lang.len = lang_len;
+               DBG2(DBG_IMV, "preferred language is '%.*s'",
+                                          pref_lang.len, pref_lang.ptr);
+       }
+
+       /* find a reason string for the preferred or default language and set it */
+       if (this->set_attribute &&
+               state->get_reason_string(state, pref_lang, &reason_string, &reason_lang))
+       {
+               this->set_attribute(this->id, connection_id,
+                                                       TNC_ATTRIBUTEID_REASON_STRING,
+                                                       reason_string.len, reason_string.ptr);
+               this->set_attribute(this->id, connection_id,
+                                                       TNC_ATTRIBUTEID_REASON_LANGUAGE,
+                                                       reason_lang.len, reason_lang.ptr);
+       }
+                       
        state->get_recommendation(state, &rec, &eval);
        return this->provide_recommendation(this->id, connection_id, rec, eval);
 }
index 00e9c9d..bffa1ad 100644 (file)
@@ -49,42 +49,6 @@ struct imv_agent_t {
                                                                                  TNC_RetryReason reason);
 
        /**
-        * Get the value of an attribute associated with a connection
-        * or with the TNCS as a whole.
-        *
-        * @param imv_id                        IMV ID assigned by TNCS
-        * @param connection_id         network connection ID assigned by TNCS
-        * @param attribute_id          attribute ID
-        * @param buffer_len            length of buffer in bytes
-        * @param buffer                        buffer
-        * @param out_value_len         size in bytes of attribute stored in buffer
-        * @return                                      TNC result code
-        */
-       TNC_Result (*get_attribute)(TNC_IMVID imv_id,
-                                                               TNC_ConnectionID connection_id,
-                                                               TNC_AttributeID attribute_id,
-                                                               TNC_UInt32 buffer_len,
-                                                               TNC_BufferReference buffer,
-                                                               TNC_UInt32 *out_value_len);
-
-       /**
-        * Set the value of an attribute associated with a connection
-        * or with the TNCS as a whole.
-        *
-        * @param imv_id                        IMV ID assigned by TNCS
-        * @param connection_id         network connection ID assigned by TNCS
-        * @param attribute_id          attribute ID
-        * @param buffer_len            length of buffer in bytes
-        * @param buffer                        buffer
-        * @return                                      TNC result code
-        */
-       TNC_Result (*set_attribute)(TNC_IMVID imv_id,
-                                                               TNC_ConnectionID connection_id,
-                                                               TNC_AttributeID attribute_id,
-                                                               TNC_UInt32 buffer_len,
-                                                               TNC_BufferReference buffer);
-       
-       /**
         * Bind TNCS functions
         *
         * @param bind_function         function offered by the TNCS
@@ -158,7 +122,7 @@ struct imv_agent_t {
        /**
         * Set Action Recommendation and Evaluation Result in the IMV state
         *
-        # @param connection_id         network connection ID assigned by TNCS
+        * @param connection_id         network connection ID assigned by TNCS
         * @param rec                           IMV action recommendation
         * @param eval                          IMV evaluation result
         * @return                                      TNC result code
@@ -171,7 +135,7 @@ struct imv_agent_t {
        /**
         * Deliver IMV Action Recommendation and IMV Evaluation Result to the TNCS
         *
-        # @param connection_id         network connection ID assigned by TNCS
+        * @param connection_id         network connection ID assigned by TNCS
         * @return                                      TNC result code
         */
        TNC_Result (*provide_recommendation)(imv_agent_t *this,
index a255964..26d07bb 100644 (file)
@@ -69,6 +69,17 @@ struct imv_state_t {
                                                           TNC_IMV_Evaluation_Result eval);
 
        /**
+        * Get reason string based on the preferred language
+        *
+        * @param preferred_language    preferred language
+        * @param reason_string                 reason string
+        * @param language code                 language of the returned reason string
+        * @return                                              TRUE if a reason string was found
+        */
+       bool (*get_reason_string)(imv_state_t *this, chunk_t preferred_language,
+                                                         chunk_t *reason_string, chunk_t *language_code);
+
+       /**
         * Destroys an imv_state_t object
         */
        void (*destroy)(imv_state_t *this);
index 85c9ba0..5e38ab2 100644 (file)
@@ -55,6 +55,26 @@ struct private_imv_test_state_t {
 
 };
 
+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", "IMC Test was not configured with \"command = allow\"" },
+       { "de", "IMC Test wurde nicht mit \"command = allow\" konfiguriert" },
+       { "fr", "IMC Test n'etait pas configuré avec \"command = allow\"" },
+       { "pl", "IMC Test nie zostało skonfigurowany z \"command = allow\"" }
+};
+
 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
        private_imv_test_state_t *this)
 {
@@ -83,6 +103,34 @@ METHOD(imv_state_t, set_recommendation, void,
        this->eval = eval;
 }
 
+METHOD(imv_state_t, get_reason_string, bool,
+       private_imv_test_state_t *this, chunk_t preferred_language,
+       chunk_t *reason_string, chunk_t *reason_language)
+{
+       int i;
+
+       for (i = 0 ; i < countof(reasons); i++)
+       {
+               chunk_t lang;
+
+               lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
+               if (chunk_equals(lang, preferred_language))
+               {
+                       *reason_language = lang;
+                       *reason_string = chunk_create(reasons[i].string, 
+                                                                       strlen(reasons[i].string));
+                       return TRUE;
+               }
+       }
+
+       /* no preferred language match found - use the default language */
+       *reason_string =   chunk_create(reasons[0].string,
+                                                                       strlen(reasons[0].string));
+       *reason_language = chunk_create(reasons[0].lang, 
+                                                                       strlen(reasons[0].lang));
+       return TRUE;
+}
+
 METHOD(imv_state_t, destroy, void,
        private_imv_test_state_t *this)
 {
@@ -115,6 +163,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
+                               .get_reason_string = _get_reason_string,
                                .destroy = _destroy,
                        },
                        .set_rounds = _set_rounds,