Fix destruction of tcg_pts_attr_file_meas_t when building from encoding
[strongswan.git] / src / libpts / tcg / tcg_pts_attr_file_meas.c
index 3269bce..1daac70 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 #include <pa_tnc/pa_tnc_msg.h>
 #include <bio/bio_writer.h>
 #include <bio/bio_reader.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <bio/bio_writer.h>
 #include <bio/bio_reader.h>
-#include <utils/linked_list.h>
-#include <debug.h>
+#include <collections/linked_list.h>
+#include <utils/debug.h>
 
 typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
 
 /**
  * File Measurement
  * see section 3.19.2 of PTS Protocol: Binding to TNC IF-M Specification
 
 typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
 
 /**
  * File Measurement
  * see section 3.19.2 of PTS Protocol: Binding to TNC IF-M Specification
- * 
+ *
  *                                        1                               2                               3
  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *                                        1                               2                               3
  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -64,39 +64,32 @@ struct private_tcg_pts_attr_file_meas_t {
        tcg_pts_attr_file_meas_t public;
 
        /**
        tcg_pts_attr_file_meas_t public;
 
        /**
-        * Attribute vendor ID
-        */
-       pen_t vendor_id;
-
-       /**
-        * Attribute type
+        * Vendor-specific attribute type
         */
         */
-       u_int32_t type;
+       pen_type_t type;
 
        /**
         * Attribute value
         */
        chunk_t value;
 
        /**
         * Attribute value
         */
        chunk_t value;
-       
+
        /**
         * Noskip flag
         */
        bool noskip_flag;
        /**
         * Noskip flag
         */
        bool noskip_flag;
-       
+
        /**
         * PTS File Measurements
         */
        pts_file_meas_t *measurements;
 
        /**
         * PTS File Measurements
         */
        pts_file_meas_t *measurements;
 
+       /**
+        * Reference count
+        */
+       refcount_t ref;
 };
 
 };
 
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
-       private_tcg_pts_attr_file_meas_t *this)
-{
-       return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
        private_tcg_pts_attr_file_meas_t *this)
 {
        return this->type;
        private_tcg_pts_attr_file_meas_t *this)
 {
        return this->type;
@@ -130,7 +123,11 @@ METHOD(pa_tnc_attr_t, build, void,
        char *filename;
        chunk_t measurement;
        bool first = TRUE;
        char *filename;
        chunk_t measurement;
        bool first = TRUE;
-       
+
+       if (this->value.ptr)
+       {
+               return;
+       }
        number_of_files = this->measurements->get_file_count(this->measurements);
        request_id = this->measurements->get_request_id(this->measurements);
 
        number_of_files = this->measurements->get_file_count(this->measurements);
        request_id = this->measurements->get_request_id(this->measurements);
 
@@ -147,8 +144,7 @@ METHOD(pa_tnc_attr_t, build, void,
                        first = FALSE;
                }
                writer->write_data  (writer, measurement);
                        first = FALSE;
                }
                writer->write_data  (writer, measurement);
-               writer->write_uint16(writer, strlen(filename));
-               writer->write_data  (writer, chunk_create(filename, strlen(filename)));
+               writer->write_data16(writer, chunk_create(filename, strlen(filename)));
        }
        enumerator->destroy(enumerator);
 
        }
        enumerator->destroy(enumerator);
 
@@ -167,12 +163,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
 {
        bio_reader_t *reader;
        u_int64_t number_of_files;
 {
        bio_reader_t *reader;
        u_int64_t number_of_files;
-       u_int16_t request_id, meas_len, filename_len;
-       size_t len;
+       u_int16_t request_id, meas_len;
        chunk_t measurement, filename;
        chunk_t measurement, filename;
+       size_t len;
        char buf[BUF_LEN];
        status_t status = FAILED;
        char buf[BUF_LEN];
        status_t status = FAILED;
-       
+
        if (this->value.len < PTS_FILE_MEAS_SIZE)
        {
                DBG1(DBG_TNC, "insufficient data for PTS file measurement header");
        if (this->value.len < PTS_FILE_MEAS_SIZE)
        {
                DBG1(DBG_TNC, "insufficient data for PTS file measurement header");
@@ -184,9 +180,10 @@ METHOD(pa_tnc_attr_t, process, status_t,
        reader->read_uint64(reader, &number_of_files);
        reader->read_uint16(reader, &request_id);
        reader->read_uint16(reader, &meas_len);
        reader->read_uint64(reader, &number_of_files);
        reader->read_uint16(reader, &request_id);
        reader->read_uint16(reader, &meas_len);
-       
+       *offset = PTS_FILE_MEAS_SIZE;
+
        this->measurements = pts_file_meas_create(request_id);
        this->measurements = pts_file_meas_create(request_id);
-       
+
        while (number_of_files--)
        {
                if (!reader->read_data(reader, meas_len, &measurement))
        while (number_of_files--)
        {
                if (!reader->read_data(reader, meas_len, &measurement))
@@ -194,16 +191,14 @@ METHOD(pa_tnc_attr_t, process, status_t,
                        DBG1(DBG_TNC, "insufficient data for PTS file measurement");
                        goto end;
                }
                        DBG1(DBG_TNC, "insufficient data for PTS file measurement");
                        goto end;
                }
-               if (!reader->read_uint16(reader, &filename_len))
-               {
-                       DBG1(DBG_TNC, "insufficient data for filename length");
-                       goto end;
-               }
-               if (!reader->read_data(reader, filename_len, &filename))
+               *offset += meas_len;
+
+               if (!reader->read_data16(reader, &filename))
                {
                        DBG1(DBG_TNC, "insufficient data for filename");
                        goto end;
                }
                {
                        DBG1(DBG_TNC, "insufficient data for filename");
                        goto end;
                }
+               *offset += 2 + filename.len;
 
                len = min(filename.len, BUF_LEN-1);
                memcpy(buf, filename.ptr, len);
 
                len = min(filename.len, BUF_LEN-1);
                memcpy(buf, filename.ptr, len);
@@ -217,12 +212,21 @@ end:
        return status;
 }
 
        return status;
 }
 
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+       private_tcg_pts_attr_file_meas_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public.pa_tnc_attribute;
+}
 METHOD(pa_tnc_attr_t, destroy, void,
        private_tcg_pts_attr_file_meas_t *this)
 {
 METHOD(pa_tnc_attr_t, destroy, void,
        private_tcg_pts_attr_file_meas_t *this)
 {
-       this->measurements->destroy(this->measurements);
-       free(this->value.ptr);
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               DESTROY_IF(this->measurements);
+               free(this->value.ptr);
+               free(this);
+       }
 }
 
 METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*,
 }
 
 METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*,
@@ -241,20 +245,20 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements)
        INIT(this,
                .public = {
                        .pa_tnc_attribute = {
        INIT(this,
                .public = {
                        .pa_tnc_attribute = {
-                               .get_vendor_id = _get_vendor_id,
                                .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_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,
                        },
                        .get_measurements = _get_measurements,
                },
                                .destroy = _destroy,
                        },
                        .get_measurements = _get_measurements,
                },
-               .vendor_id = PEN_TCG,
-               .type = TCG_PTS_FILE_MEAS,
+               .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
                .measurements = measurements,
                .measurements = measurements,
+               .ref = 1,
        );
 
        return &this->public.pa_tnc_attribute;
        );
 
        return &this->public.pa_tnc_attribute;
@@ -271,20 +275,20 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data)
        INIT(this,
                .public = {
                        .pa_tnc_attribute = {
        INIT(this,
                .public = {
                        .pa_tnc_attribute = {
-                               .get_vendor_id = _get_vendor_id,
                                .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_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,
                        },
                        .get_measurements = _get_measurements,
                },
                                .destroy = _destroy,
                        },
                        .get_measurements = _get_measurements,
                },
-               .vendor_id = PEN_TCG,
-               .type = TCG_PTS_FILE_MEAS,
+               .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
                .value = chunk_clone(data),
                .value = chunk_clone(data),
+               .ref = 1,
        );
 
        return &this->public.pa_tnc_attribute;
        );
 
        return &this->public.pa_tnc_attribute;