treat IF-M and IF-TNCCS remediation instructions/parameters in an equal way
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 19 Feb 2013 19:00:48 +0000 (20:00 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 19 Feb 2013 19:00:57 +0000 (20:00 +0100)
src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libimcv/ietf/ietf_attr_remediation_instr.c

index 63d94b9..2ef8dd6 100644 (file)
@@ -66,24 +66,24 @@ struct private_pb_remediation_parameters_msg_t {
        pb_tnc_msg_type_t type;
 
        /**
-        * Remediation Parameters Vendor ID
+        * Remediation Parameters Type
         */
-       u_int32_t vendor_id;
+       pen_type_t parameters_type;
 
        /**
-        * Remediation Parameters Type
+        * Remediation Parameters
         */
-       u_int32_t parameters_type;
+       chunk_t parameters;
 
        /**
-        * Remediation Parameters string
+        * Remediation String
         */
-       chunk_t remediation_string;
+       chunk_t string;
 
        /**
-        * Language code
+        * Remediation Language Code
         */
-       chunk_t language_code;
+       chunk_t lang_code;
 
        /**
         * Encoded message
@@ -113,10 +113,9 @@ METHOD(pb_tnc_msg_t, build, void,
                return;
        }
        writer = bio_writer_create(64);
-       writer->write_uint32(writer, this->vendor_id);
-       writer->write_uint32(writer, this->parameters_type);
-       writer->write_data32(writer, this->remediation_string);
-       writer->write_data8 (writer, this->language_code);
+       writer->write_uint32(writer, this->parameters_type.vendor_id);
+       writer->write_uint32(writer, this->parameters_type.type);
+       writer->write_data32(writer, this->parameters);
 
        this->encoding = writer->get_buf(writer);
        this->encoding = chunk_clone(this->encoding);
@@ -127,83 +126,103 @@ METHOD(pb_tnc_msg_t, process, status_t,
        private_pb_remediation_parameters_msg_t *this, u_int32_t *offset)
 {
        bio_reader_t *reader;
+       u_int8_t reserved;
+       status_t status = SUCCESS;
+       u_char *pos;
+
+       *offset = 0;
 
        /* process message */
        reader = bio_reader_create(this->encoding);
-       reader->read_uint32(reader, &this->vendor_id);
-       reader->read_uint32(reader, &this->parameters_type);
+       reader->read_uint8 (reader, &reserved);
+       reader->read_uint24(reader, &this->parameters_type.vendor_id);
+       reader->read_uint32(reader, &this->parameters_type.type);
+       reader->read_data  (reader, reader->remaining(reader), &this->parameters);
 
-       if (!reader->read_data32(reader, &this->remediation_string))
+       this->parameters = chunk_clone(this->parameters);
+       reader->destroy(reader);
+
+       if (this->parameters_type.vendor_id == PEN_IETF &&
+               this->parameters_type.type == PB_REMEDIATION_STRING)
        {
-               DBG1(DBG_TNC, "could not parse remediation string");
-               reader->destroy(reader);
+               reader = bio_reader_create(this->parameters);
+               status = FAILED;
                *offset = 8;
-               return FAILED;
-       };
-       this->remediation_string = chunk_clone(this->remediation_string);
 
-       if (this->remediation_string.len &&
-               this->remediation_string.ptr[this->remediation_string.len-1] == '\0')
-       {
-               DBG1(DBG_TNC, "remediation string must not be null terminated");
+               if (!reader->read_data32(reader, &this->string))
+               {
+                       DBG1(DBG_TNC, "insufficient data for remediation string");
+                       goto end;
+               };
+               *offset += 4;
+
+               pos = memchr(this->string.ptr, '\0', this->string.len);
+               if (pos)
+               {
+                       DBG1(DBG_TNC, "nul termination in remediation string");
+                       *offset += (pos - this->string.ptr);
+                       goto end;
+               }
+               *offset += this->string.len;
+
+               if (!reader->read_data8(reader, &this->lang_code))
+               {
+                       DBG1(DBG_TNC, "insufficient data for remediation string lang code");
+                       goto end;
+               };
+               *offset += 1;
+
+               pos = memchr(this->lang_code.ptr, '\0', this->lang_code.len);
+
+               if (pos)
+               {
+                       DBG1(DBG_TNC, "nul termination in remediation string lang code");
+                       *offset += (pos - this->lang_code.ptr);
+                       goto end;
+               }
+               status = SUCCESS;
+
+end:
                reader->destroy(reader);
-               *offset = 11 + this->remediation_string.len;
-               return FAILED;
        }
-
-       if (!reader->read_data8(reader, &this->language_code))
-       {
-               DBG1(DBG_TNC, "could not parse language code");
-               reader->destroy(reader);
-               *offset = 12 + this->remediation_string.len;
-               return FAILED;
-       };
-       this->language_code = chunk_clone(this->language_code);
-       reader->destroy(reader);
-
-       if (this->language_code.len &&
-               this->language_code.ptr[this->language_code.len-1] == '\0')
-       {
-               DBG1(DBG_TNC, "language code must not be null terminated");
-               *offset = 12 + this->remediation_string.len + this->language_code.len;
-               return FAILED;
-       }
-
-       return SUCCESS;
+       return status;
 }
 
 METHOD(pb_tnc_msg_t, destroy, void,
        private_pb_remediation_parameters_msg_t *this)
 {
        free(this->encoding.ptr);
-       free(this->remediation_string.ptr);
-       free(this->language_code.ptr);
+       free(this->parameters.ptr);
        free(this);
 }
 
-METHOD(pb_remediation_parameters_msg_t, get_vendor_id, u_int32_t,
-       private_pb_remediation_parameters_msg_t *this, u_int32_t *type)
+METHOD(pb_remediation_parameters_msg_t, get_parameters_type, pen_type_t,
+       private_pb_remediation_parameters_msg_t *this)
 {
-       *type = this->parameters_type;
-       return this->vendor_id;
+       return this->parameters_type;
 }
 
-METHOD(pb_remediation_parameters_msg_t, get_remediation_string, chunk_t,
+METHOD(pb_remediation_parameters_msg_t, get_parameters, chunk_t,
        private_pb_remediation_parameters_msg_t *this)
 {
-       return this->remediation_string;
+       return this->parameters;
 }
 
-METHOD(pb_remediation_parameters_msg_t, get_language_code, chunk_t,
-       private_pb_remediation_parameters_msg_t *this)
+METHOD(pb_remediation_parameters_msg_t, get_string, chunk_t,
+       private_pb_remediation_parameters_msg_t *this, chunk_t *lang_code)
 {
-       return this->language_code;
+       if (lang_code)
+       {
+               *lang_code = this->lang_code;
+       }
+       return this->string;
 }
 
 /**
  * See header
  */
-pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
+pb_tnc_msg_t* pb_remediation_parameters_msg_create(pen_type_t parameters_type,
+                                                                                                  chunk_t parameters)
 {
        private_pb_remediation_parameters_msg_t *this;
 
@@ -216,24 +235,56 @@ pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
                                .process = _process,
                                .destroy = _destroy,
                        },
-                       .get_vendor_id = _get_vendor_id,
-                       .get_remediation_string = _get_remediation_string,
-                       .get_language_code = _get_language_code,
+                       .get_parameters_type = _get_parameters_type,
+                       .get_parameters = _get_parameters,
+                       .get_uri = _get_parameters,
+                       .get_string = _get_string,
                },
-               .type = PB_MSG_REASON_STRING,
-               .encoding = chunk_clone(data),
+               .type = PB_MSG_REMEDIATION_PARAMETERS,
+               .parameters_type = parameters_type,
+               .parameters = chunk_clone(parameters),
        );
 
        return &this->public.pb_interface;
 }
 
 /**
+ * Described in header.
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_uri(chunk_t uri)
+{
+       pen_type_t type = { PEN_IETF, PB_REMEDIATION_URI };
+
+       return pb_remediation_parameters_msg_create(type, uri);
+}
+
+/**
+ * Described in header.
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_string(chunk_t string,
+                                                                                                                          chunk_t lang_code)
+{
+       pb_tnc_msg_t *msg;
+       bio_writer_t *writer;
+       pen_type_t type = { PEN_IETF, PB_REMEDIATION_STRING };
+
+       /* limit language code to 255 octets */
+       lang_code.len = min(255, lang_code.len);
+
+       writer = bio_writer_create(4 + string.len + 1 + lang_code.len);
+       writer->write_data32(writer, string);
+       writer->write_data8 (writer, lang_code);
+
+       msg = pb_remediation_parameters_msg_create(type, writer->get_buf(writer));
+       writer->destroy(writer);
+
+       return msg;
+}
+
+/**
  * See header
  */
-pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
-                                                                                                  u_int32_t type,
-                                                                                                  chunk_t remediation_string,
-                                                                                                  chunk_t language_code)
+pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
 {
        private_pb_remediation_parameters_msg_t *this;
 
@@ -246,16 +297,15 @@ pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
                                .process = _process,
                                .destroy = _destroy,
                        },
-                       .get_vendor_id = _get_vendor_id,
-                       .get_remediation_string = _get_remediation_string,
-                       .get_language_code = _get_language_code,
+                       .get_parameters_type = _get_parameters_type,
+                       .get_parameters = _get_parameters,
+                       .get_uri = _get_parameters,
+                       .get_string = _get_string,
                },
-               .type = PB_MSG_REASON_STRING,
-               .vendor_id = vendor_id,
-               .parameters_type = type,
-               .remediation_string = chunk_clone(remediation_string),
-               .language_code = chunk_clone(language_code),
+               .type = PB_MSG_REMEDIATION_PARAMETERS,
+               .encoding = chunk_clone(data),
        );
 
        return &this->public.pb_interface;
 }
+
index 258d495..f3a1c10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2011-2013 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@ typedef struct pb_remediation_parameters_msg_t pb_remediation_parameters_msg_t;
 
 #include "pb_tnc_msg.h"
 
+#include <pen/pen.h>
+
 /**
  * PB-TNC Remediation Parameter Types as defined in section 4.8.1 of RFC 5793
  */
@@ -50,41 +52,61 @@ struct pb_remediation_parameters_msg_t {
        pb_tnc_msg_t pb_interface;
 
        /**
-        * Get Remediation Parameters Vendor ID and Type
+        * Get the Remediation Parameters Type (Vendor ID and Type)
         *
-        * @param type                          Remediation Parameters Type
-        * @return                                      Remediation Parameters Vendor ID
+        * @return                              Remediation Parameters Type
         */
-       u_int32_t (*get_vendor_id)(pb_remediation_parameters_msg_t *this,
-                                                          u_int32_t *type);
+       pen_type_t (*get_parameters_type)(pb_remediation_parameters_msg_t *this);
 
        /**
-        * Get Remediation String
+        * Get the Remediation Parameters
         *
-        * @return                                      Remediation String
+        * @return                              Remediation Parameters
         */
-       chunk_t (*get_remediation_string)(pb_remediation_parameters_msg_t *this);
+       chunk_t (*get_parameters)(pb_remediation_parameters_msg_t *this);
 
        /**
-        * Get Reason String Language Code
+        * Get the Remediation URI
         *
-        * @return                                      Language Code
+        * @return                              Remediation URI
         */
-       chunk_t (*get_language_code)(pb_remediation_parameters_msg_t *this);
+       chunk_t (*get_uri)(pb_remediation_parameters_msg_t *this);
+
+       /**
+        * Get the Remediation String
+        *
+        * @param lang_code             Optional Language Code
+        * @return                              Remediation String
+        */
+       chunk_t (*get_string)(pb_remediation_parameters_msg_t *this,
+                                                 chunk_t *lang_code);
+
 };
 
 /**
- * Create a PB-Remediation-Parameters message from parameters
+ * Create a general PB-Remediation-Parameters message
+ *
+ * @param parameters_type      Remediation Parameters Type
+ * @param parameters           Remediation Parameters
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create(pen_type_t parameters_type,
+                                                                                                  chunk_t parameters);
+
+/**
+ * Create a PB-Remediation-Parameters message of IETF Type Remediation URI
+ *
+ * @param uri                          Remediation URI
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_uri(chunk_t uri);
+
+/**
+ * Create a PB-Remediation-Parameters message of IETF Type Remediation String
  *
- * @param vendor_id                            Remediation Parameters Vendor ID
- * @param type                                 Remediation Parameters Type             
- * @param remediation_string   Remediation String
- * @param language_code                        Language Code
+ * @param string                       Remediation String
+ * @param lang_code                    Remediation String Language Code
  */
-pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
-                                                                                                  u_int32_t type,
-                                                                                                  chunk_t remediation_string,
-                                                                                                  chunk_t language_code);
+pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_string(chunk_t string,
+                                                                                                                          chunk_t lang_code);
 
 /**
  * Create an unprocessed PB-Remediation-Parameters message from raw data
index 2ae665c..29a161e 100644 (file)
@@ -311,7 +311,36 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
                }
                case PB_MSG_REMEDIATION_PARAMETERS:
                {
-                       /* TODO : Remediation parameters message processing */
+                       pb_remediation_parameters_msg_t *rem_msg;
+                       pen_type_t parameters_type;
+                       chunk_t parameters, string, lang_code;
+
+                       rem_msg = (pb_remediation_parameters_msg_t*)msg;
+                       parameters_type = rem_msg->get_parameters_type(rem_msg);
+                       parameters = rem_msg->get_parameters(rem_msg);
+
+                       if (parameters_type.vendor_id == PEN_IETF)
+                       {
+                               switch (parameters_type.type)
+                               {
+                                       case PB_REMEDIATION_URI:
+                                               DBG1(DBG_TNC, "remediation uri: %.*s",
+                                                                          parameters.len, parameters.ptr);
+                                               break;
+                                       case PB_REMEDIATION_STRING:
+                                               string = rem_msg->get_string(rem_msg, &lang_code);
+                                               DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
+                                                                          lang_code.len, lang_code.ptr,
+                                                                          string.len, string.ptr);
+                                               break;
+                                       default:
+                                               DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+                               }
+                       }
+                       else
+                       {
+                               DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+                       }
                        break;
                }
                case PB_MSG_ERROR:
index f3b4e83..d28631e 100644 (file)
@@ -194,14 +194,16 @@ METHOD(pa_tnc_attr_t, process, status_t,
                        DBG1(DBG_TNC, "insufficient data for IETF remediation string");
                        goto end;
                }
+               *offset += 4;
+
                pos = memchr(this->string.ptr, '\0', this->string.len);
                if (pos)
                {
                        DBG1(DBG_TNC, "nul termination in IETF remediation string");
-                       *offset += 1 + (pos - this->string.ptr);
+                       *offset += (pos - this->string.ptr);
                        goto end;
                }
-               *offset += 4 + this->string.len;
+               *offset += this->string.len;
 
                if (!reader->read_data8(reader, &this->lang_code))
                {
@@ -246,12 +248,6 @@ METHOD(ietf_attr_remediation_instr_t, get_parameters, chunk_t,
        return this->parameters;
 }
 
-METHOD(ietf_attr_remediation_instr_t, get_uri, chunk_t,
-       private_ietf_attr_remediation_instr_t *this)
-{
-       return this->parameters;
-}
-
 METHOD(ietf_attr_remediation_instr_t, get_string, chunk_t,
        private_ietf_attr_remediation_instr_t *this, chunk_t *lang_code)
 {
@@ -284,7 +280,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create(pen_type_t parameters_type,
                        },
                        .get_parameters_type = _get_parameters_type,
                        .get_parameters = _get_parameters,
-                       .get_uri = _get_uri,
+                       .get_uri = _get_parameters,
                        .get_string = _get_string,
                },
                .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS },
@@ -350,7 +346,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data)
                        },
                        .get_parameters_type = _get_parameters_type,
                        .get_parameters = _get_parameters,
-                       .get_uri = _get_uri,
+                       .get_uri = _get_parameters,
                        .get_string = _get_string,
                },
                .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS },