protection against insane IMCs and IMVs
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 11 May 2011 17:34:01 +0000 (19:34 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 11 May 2011 17:34:01 +0000 (19:34 +0200)
src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
src/libcharon/tnc/imc/imc_manager.h
src/libcharon/tnc/imv/imv_manager.h

index e18f1b0..25a6a1c 100644 (file)
@@ -28,6 +28,12 @@ TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
                                                                           TNC_MessageTypeList supported_types,
                                                                           TNC_UInt32 type_count)
 {
+       if (!charon->imcs->is_registered(charon->imcs, imc_id))
+       {
+               DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u",
+                                          imc_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->imcs->set_message_types(charon->imcs, imc_id,
                                                                                   supported_types, type_count);
 }
@@ -39,6 +45,12 @@ TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
                                                                                  TNC_ConnectionID connection_id,
                                                                                  TNC_RetryReason reason)
 {
+       if (!charon->imcs->is_registered(charon->imcs, imc_id))
+       {
+               DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u",
+                                          imc_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id,
                                                                                                  connection_id, reason);
 }
@@ -52,6 +64,12 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
                                                                TNC_UInt32 msg_len,
                                                                TNC_MessageType msg_type)
 {
+       if (!charon->imcs->is_registered(charon->imcs, imc_id))
+       {
+               DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
+                                          imc_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY,
                                                                           connection_id, msg, msg_len, msg_type);
 }
index 5ed6741..ccf6aea 100644 (file)
@@ -77,7 +77,7 @@ METHOD(imc_manager_t, remove_, imc_t*,
        private_tnc_imc_manager_t *this, TNC_IMCID id)
 {
        enumerator_t *enumerator;
-       imc_t *imc;
+       imc_t *imc, *removed_imc = NULL;
 
        enumerator = this->imcs->create_enumerator(this->imcs);
        while (enumerator->enumerate(enumerator, &imc))
@@ -85,11 +85,34 @@ METHOD(imc_manager_t, remove_, imc_t*,
                if (id == imc->get_id(imc))
                {
                        this->imcs->remove_at(this->imcs, enumerator);
-                       return imc;
+                       removed_imc = imc;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       return removed_imc;
+}
+
+METHOD(imc_manager_t, is_registered, bool,
+       private_tnc_imc_manager_t *this, TNC_IMCID id)
+{
+       enumerator_t *enumerator;
+       imc_t *imc;
+       bool found = FALSE;
+
+       enumerator = this->imcs->create_enumerator(this->imcs);
+       while (enumerator->enumerate(enumerator, &imc))
+       {
+               if (id == imc->get_id(imc))
+               {
+                       found = TRUE;
+                       break;
                }
        }
        enumerator->destroy(enumerator);
-       return NULL;
+
+       return found;
 }
 
 METHOD(imc_manager_t, get_preferred_language, char*,
@@ -228,6 +251,7 @@ imc_manager_t* tnc_imc_manager_create(void)
                .public = {
                        .add = _add,
                        .remove = _remove_, /* avoid name conflict with stdio.h */
+                       .is_registered = _is_registered,
                        .get_preferred_language = _get_preferred_language,
                        .notify_connection_change = _notify_connection_change,
                        .begin_handshake = _begin_handshake,
index 0ea52f0..0ed00b0 100644 (file)
@@ -28,6 +28,12 @@ TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
                                                                           TNC_MessageTypeList supported_types,
                                                                           TNC_UInt32 type_count)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->imvs->set_message_types(charon->imvs, imv_id,
                                                                                   supported_types, type_count);
 }
@@ -39,6 +45,12 @@ TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
                                                                                  TNC_ConnectionID connection_id,
                                                                                  TNC_RetryReason reason)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id,
                                                                                                  connection_id, reason);
 }
@@ -52,6 +64,12 @@ TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
                                                                TNC_UInt32 msg_len,
                                                                TNC_MessageType msg_type)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id,
                                                                           connection_id, msg, msg_len, msg_type);
 }
@@ -65,6 +83,12 @@ TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
                                                                TNC_IMV_Action_Recommendation recommendation,
                                                                TNC_IMV_Evaluation_Result evaluation)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring ProvideRecommendation() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->provide_recommendation(charon->tnccs, imv_id,
                                                        connection_id, recommendation, evaluation);
 }
@@ -80,6 +104,12 @@ TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id,
                                                                 TNC_BufferReference buffer,
                                                                 TNC_UInt32 *out_value_len)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id,
                                                        attribute_id, buffer_len, buffer, out_value_len);
 }
@@ -94,6 +124,12 @@ TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id,
                                                                 TNC_UInt32 buffer_len,
                                                                 TNC_BufferReference buffer)
 {
+       if (!charon->imvs->is_registered(charon->imvs, imv_id))
+       {
+               DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMV %u",
+                                          imv_id);
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
        return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id,
                                                                                attribute_id, buffer_len, buffer);
 }
index e3f54d7..579ab06 100644 (file)
@@ -84,7 +84,7 @@ METHOD(imv_manager_t, remove_, imv_t*,
        private_tnc_imv_manager_t *this, TNC_IMVID id)
 {
        enumerator_t *enumerator;
-       imv_t *imv;
+       imv_t *imv, *removed_imv = NULL;
 
        enumerator = this->imvs->create_enumerator(this->imvs);
        while (enumerator->enumerate(enumerator, &imv))
@@ -92,11 +92,34 @@ METHOD(imv_manager_t, remove_, imv_t*,
                if (id == imv->get_id(imv))
                {
                        this->imvs->remove_at(this->imvs, enumerator);
-                       return imv;
+                       removed_imv = imv;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       return removed_imv;
+}
+
+METHOD(imv_manager_t, is_registered, bool,
+       private_tnc_imv_manager_t *this, TNC_IMVID id)
+{
+       enumerator_t *enumerator;
+       imv_t *imv;
+       bool found = FALSE;
+
+       enumerator = this->imvs->create_enumerator(this->imvs);
+       while (enumerator->enumerate(enumerator, &imv))
+       {
+               if (id == imv->get_id(imv))
+               {
+                       found = TRUE;
+                       break;
                }
        }
        enumerator->destroy(enumerator);
-       return NULL;
+
+       return found;
 }
 
 METHOD(imv_manager_t, get_recommendation_policy, recommendation_policy_t,
@@ -297,6 +320,7 @@ imv_manager_t* tnc_imv_manager_create(void)
                .public = {
                        .add = _add,
                        .remove = _remove_, /* avoid name conflict with stdio.h */
+                       .is_registered = _is_registered,
                        .get_recommendation_policy = _get_recommendation_policy,
                        .create_recommendations = _create_recommendations,
                        .enforce_recommendation = _enforce_recommendation,
index 634afdb..ad83cf5 100644 (file)
@@ -49,6 +49,14 @@ struct imc_manager_t {
        imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id);
 
        /**
+        * Check if an IMC with a given ID is registered with the IMC manager
+        *
+        * @param id                            ID of IMC instance
+        * @return                                      TRUE if registered
+        */
+       bool (*is_registered)(imc_manager_t *this, TNC_IMCID id);
+
+       /**
         * Return the preferred language for recommendations
         *
         * @return                                      preferred language string
index 724d4dc..0dd2d62 100644 (file)
@@ -50,6 +50,15 @@ struct imv_manager_t {
        imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id);
 
        /**
+        * Check if an IMV with a given ID is registered with the IMV manager
+        *
+        * @param id                            ID of IMV instance
+        * @return                                      TRUE if registered
+        */
+       bool (*is_registered)(imv_manager_t *this, TNC_IMVID id);
+
+
+       /**
         * Get the configured recommendation policy
         *
         * @return                                      configured recommendation policy