diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-12-18 17:20:13 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-12-18 17:20:13 +0100 |
commit | 8982b702984a08bdcc568fa63402b3d012e440aa (patch) | |
tree | 903a1f454f6b9aed6fd1d10de39fa2d9b7d8fe51 /src | |
parent | 4f9134270214412c69e1c100c3ff9ac35a4522b6 (diff) | |
download | strongswan-8982b702984a08bdcc568fa63402b3d012e440aa.tar.bz2 strongswan-8982b702984a08bdcc568fa63402b3d012e440aa.tar.xz |
added reference counts to all PA-TNC attribute classes
Diffstat (limited to 'src')
19 files changed, 405 insertions, 56 deletions
diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c index c9b76dde5..b53019657 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.c +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -81,6 +81,11 @@ struct private_ietf_attr_port_filter_t { * List of Port Filter entries */ linked_list_t *ports; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -166,12 +171,22 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_port_filter_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_ietf_attr_port_filter_t *this) { - this->ports->destroy_function(this->ports, free); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + this->ports->destroy_function(this->ports, free); + free(this->value.ptr); + free(this); + } } METHOD(ietf_attr_port_filter_t, add_port, void, @@ -224,6 +239,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create(void) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .add_port = _add_port, @@ -232,6 +248,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create(void) .vendor_id = PEN_IETF, .type = IETF_ATTR_PORT_FILTER, .ports = linked_list_create(), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -252,6 +269,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) .get_value = _get_value, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .add_port = _add_port, @@ -261,6 +279,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) .type = IETF_ATTR_PORT_FILTER, .value = chunk_clone(data), .ports = linked_list_create(), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libimcv/ietf/ietf_attr_product_info.c b/src/libimcv/ietf/ietf_attr_product_info.c index 222fef0bf..548793547 100644 --- a/src/libimcv/ietf/ietf_attr_product_info.c +++ b/src/libimcv/ietf/ietf_attr_product_info.c @@ -80,6 +80,10 @@ struct private_ietf_attr_product_info_t { */ char *product_name; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -154,12 +158,22 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_product_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_ietf_attr_product_info_t *this) { - free(this->product_name); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->product_name); + free(this->value.ptr); + free(this); + } } METHOD(ietf_attr_product_info_t, get_info, char*, @@ -194,6 +208,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_info = _get_info, @@ -203,6 +218,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, .product_vendor_id = vendor_id, .product_id = id, .product_name = strdup(name), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -223,6 +239,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) .get_value = _get_value, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_info = _get_info, @@ -230,6 +247,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) .vendor_id = PEN_IETF, .type = IETF_ATTR_PRODUCT_INFORMATION, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_aik.c b/src/libpts/tcg/tcg_pts_attr_aik.c index 93bbfb990..9be3794b6 100644 --- a/src/libpts/tcg/tcg_pts_attr_aik.c +++ b/src/libpts/tcg/tcg_pts_attr_aik.c @@ -72,6 +72,11 @@ struct private_tcg_pts_attr_aik_t { * AIK Certificate or Public Key */ certificate_t *aik; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -163,12 +168,22 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_aik_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_aik_t *this) { - DESTROY_IF(this->aik); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + DESTROY_IF(this->aik); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*, @@ -194,6 +209,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_aik = _get_aik, @@ -201,6 +217,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik) .vendor_id = PEN_TCG, .type = TCG_PTS_AIK, .aik = aik->get_ref(aik), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -224,6 +241,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_aik = _get_aik, @@ -231,6 +249,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_AIK, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c index a32583822..dce98e87d 100644 --- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c +++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c @@ -86,6 +86,11 @@ struct private_tcg_pts_attr_dh_nonce_finish_t { * DH Initiator Nonce */ chunk_t initiator_nonce; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -162,13 +167,23 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_finish_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_dh_nonce_finish_t *this) { - free(this->value.ptr); - free(this->initiator_value.ptr); - free(this->initiator_nonce.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->initiator_value.ptr); + free(this->initiator_nonce.ptr); + free(this); + } } METHOD(tcg_pts_attr_dh_nonce_finish_t, get_hash_algo, pts_meas_algorithms_t, @@ -209,6 +224,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create( .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_hash_algo = _get_hash_algo, @@ -220,6 +236,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create( .hash_algo = hash_algo, .initiator_value = initiator_value, .initiator_nonce = chunk_clone(initiator_nonce), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -242,6 +259,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_hash_algo = _get_hash_algo, @@ -251,6 +269,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value) .vendor_id = PEN_TCG, .type = TCG_PTS_DH_NONCE_FINISH, .value = chunk_clone(value), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c index 372899498..36266fe12 100644 --- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c +++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c @@ -78,6 +78,10 @@ struct private_tcg_pts_attr_dh_nonce_params_req_t { */ pts_dh_group_t dh_groups; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -147,11 +151,21 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_params_req_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_dh_nonce_params_req_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_min_nonce_len, u_int8_t, @@ -184,6 +198,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_min_nonce_len = _get_min_nonce_len, @@ -193,6 +208,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len, .type = TCG_PTS_DH_NONCE_PARAMS_REQ, .min_nonce_len = min_nonce_len, .dh_groups = dh_groups, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -215,6 +231,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_min_nonce_len = _get_min_nonce_len, @@ -223,6 +240,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value) .vendor_id = PEN_TCG, .type = TCG_PTS_DH_NONCE_PARAMS_REQ, .value = chunk_clone(value), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c index c7357620d..09bfa3aac 100644 --- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c +++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c @@ -93,7 +93,11 @@ struct private_tcg_pts_attr_dh_nonce_params_resp_t { * DH Responder Public Value */ chunk_t responder_value; - + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -173,13 +177,23 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_dh_nonce_params_resp_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_dh_nonce_params_resp_t *this) { - free(this->value.ptr); - free(this->responder_nonce.ptr); - free(this->responder_value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->responder_nonce.ptr); + free(this->responder_value.ptr); + free(this); + } } METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_dh_group, pts_dh_group_t, @@ -226,6 +240,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_dh_group = _get_dh_group, @@ -239,6 +254,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group, .hash_algo_set = hash_algo_set, .responder_nonce = chunk_clone(responder_nonce), .responder_value = responder_value, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -261,6 +277,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_dh_group = _get_dh_group, @@ -271,6 +288,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value) .vendor_id = PEN_TCG, .type = TCG_PTS_DH_NONCE_PARAMS_RESP, .value = chunk_clone(value), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_file_meas.c b/src/libpts/tcg/tcg_pts_attr_file_meas.c index 3269bceed..737da65c1 100644 --- a/src/libpts/tcg/tcg_pts_attr_file_meas.c +++ b/src/libpts/tcg/tcg_pts_attr_file_meas.c @@ -88,6 +88,10 @@ struct private_tcg_pts_attr_file_meas_t { */ pts_file_meas_t *measurements; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -217,12 +221,21 @@ end: 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) { - this->measurements->destroy(this->measurements); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + this->measurements->destroy(this->measurements); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*, @@ -248,6 +261,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_measurements = _get_measurements, @@ -255,6 +269,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements) .vendor_id = PEN_TCG, .type = TCG_PTS_FILE_MEAS, .measurements = measurements, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -278,6 +293,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_measurements = _get_measurements, @@ -285,6 +301,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_FILE_MEAS, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c index 82b44167e..054285c4e 100644 --- a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c +++ b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c @@ -68,6 +68,11 @@ struct private_tcg_pts_attr_gen_attest_evid_t { * Noskip flag */ bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -131,11 +136,21 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_gen_attest_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_gen_attest_evid_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } } /** @@ -155,11 +170,13 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create() .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GEN_ATTEST_EVID, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -183,12 +200,14 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GEN_ATTEST_EVID, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_get_aik.c b/src/libpts/tcg/tcg_pts_attr_get_aik.c index 727c7a211..1875375a4 100644 --- a/src/libpts/tcg/tcg_pts_attr_get_aik.c +++ b/src/libpts/tcg/tcg_pts_attr_get_aik.c @@ -65,6 +65,11 @@ struct private_tcg_pts_attr_get_aik_t { * Noskip flag */ bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -128,11 +133,21 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_get_aik_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_get_aik_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } } /** @@ -152,11 +167,13 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create() .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GET_AIK, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -180,12 +197,14 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GET_AIK, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c index 08f0b0c9b..cb6834ca5 100644 --- a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c +++ b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c @@ -68,6 +68,11 @@ struct private_tcg_pts_attr_get_tpm_version_info_t { * Noskip flag */ bool noskip_flag; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -131,11 +136,21 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_get_tpm_version_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_get_tpm_version_info_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } } /** @@ -155,11 +170,13 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create() .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GET_TPM_VERSION_INFO, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -183,12 +200,14 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, }, .vendor_id = PEN_TCG, .type = TCG_PTS_GET_TPM_VERSION_INFO, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_meas_algo.c b/src/libpts/tcg/tcg_pts_attr_meas_algo.c index dffc15320..ed520e3cd 100644 --- a/src/libpts/tcg/tcg_pts_attr_meas_algo.c +++ b/src/libpts/tcg/tcg_pts_attr_meas_algo.c @@ -72,6 +72,10 @@ struct private_tcg_pts_attr_meas_algo_t { */ pts_meas_algorithms_t algorithms; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -140,8 +144,18 @@ METHOD(pa_tnc_attr_t, process, status_t, METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_meas_algo_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_meas_algo_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; } METHOD(tcg_pts_attr_meas_algo_t, get_algorithms, pts_meas_algorithms_t, @@ -168,6 +182,7 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_algorithms = _get_algorithms, @@ -175,6 +190,7 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms, .vendor_id = PEN_TCG, .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO, .algorithms = algorithms, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -199,6 +215,7 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_algorithms = _get_algorithms, @@ -206,6 +223,7 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data, .vendor_id = PEN_TCG, .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_proto_caps.c b/src/libpts/tcg/tcg_pts_attr_proto_caps.c index 6d078905d..055c750ff 100644 --- a/src/libpts/tcg/tcg_pts_attr_proto_caps.c +++ b/src/libpts/tcg/tcg_pts_attr_proto_caps.c @@ -72,6 +72,10 @@ struct private_tcg_pts_attr_proto_caps_t { */ pts_proto_caps_flag_t flags; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -141,8 +145,18 @@ METHOD(pa_tnc_attr_t, process, status_t, METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_proto_caps_t *this) { - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_proto_caps_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; } METHOD(tcg_pts_attr_proto_caps_t, get_flags, pts_proto_caps_flag_t, @@ -169,6 +183,7 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_flags = _get_flags, @@ -176,6 +191,7 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags, .vendor_id = PEN_TCG, .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS, .flags = flags, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -199,6 +215,7 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_flags = _get_flags, @@ -206,6 +223,7 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data, .vendor_id = PEN_TCG, .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meas.c b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c index 68ecfa8f1..17781f745 100644 --- a/src/libpts/tcg/tcg_pts_attr_req_file_meas.c +++ b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c @@ -93,6 +93,10 @@ struct private_tcg_pts_attr_req_file_meas_t { */ char *pathname; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -181,12 +185,22 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_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_req_file_meas_t *this) { - free(this->pathname); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->pathname); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_req_file_meas_t, get_directory_flag, bool, @@ -233,6 +247,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_directory_flag = _get_directory_flag, @@ -246,6 +261,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag, .request_id = request_id, .delimiter = delimiter, .pathname = strdup(pathname), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -269,6 +285,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_directory_flag = _get_directory_flag, @@ -279,6 +296,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_REQ_FILE_MEAS, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c index 5c7b9fe1a..bef6b5db6 100644 --- a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c +++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c @@ -86,6 +86,10 @@ struct private_tcg_pts_attr_req_file_meta_t { */ char *pathname; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -177,9 +181,19 @@ METHOD(pa_tnc_attr_t, process, status_t, METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_req_file_meta_t *this) { - free(this->pathname); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->pathname); + free(this->value.ptr); + free(this); + } +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_file_meta_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; } METHOD(tcg_pts_attr_req_file_meta_t, get_directory_flag, bool, @@ -219,6 +233,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_directory_flag = _get_directory_flag, @@ -230,6 +245,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag, .directory_flag = directory_flag, .delimiter = delimiter, .pathname = strdup(pathname), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -253,6 +269,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_directory_flag = _get_directory_flag, @@ -262,6 +279,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_REQ_FILE_META, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c index 062989572..bfd108b9f 100644 --- a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c +++ b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c @@ -96,6 +96,11 @@ struct private_tcg_pts_attr_req_func_comp_evid_t { * List of Functional Components */ linked_list_t *list; + + /** + * Reference count + */ + refcount_t ref; }; typedef struct entry_t entry_t; @@ -261,12 +266,22 @@ end: return status; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_req_func_comp_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_req_func_comp_evid_t *this) { - this->list->destroy_function(this->list, (void *)free_entry); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + this->list->destroy_function(this->list, (void *)free_entry); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void, @@ -312,6 +327,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .add_component = _add_component, @@ -321,6 +337,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void) .vendor_id = PEN_TCG, .type = TCG_PTS_REQ_FUNC_COMP_EVID, .list = linked_list_create(), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -343,6 +360,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .add_component = _add_component, @@ -353,6 +371,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data) .type = TCG_PTS_REQ_FUNC_COMP_EVID, .list = linked_list_create(), .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c index 96c01270c..98b0cd559 100644 --- a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c +++ b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c @@ -124,6 +124,10 @@ struct private_tcg_pts_attr_simple_comp_evid_t { */ pts_comp_evidence_t *evidence; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -422,12 +426,22 @@ end: return status; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_simple_comp_evid_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_simple_comp_evid_t *this) { - this->evidence->destroy(this->evidence); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + this->evidence->destroy(this->evidence); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_evidence, pts_comp_evidence_t*, @@ -453,6 +467,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_comp_evidence = _get_comp_evidence, @@ -460,6 +475,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid) .vendor_id = PEN_TCG, .type = TCG_PTS_SIMPLE_COMP_EVID, .evidence = evid, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -483,6 +499,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_comp_evidence = _get_comp_evidence, @@ -490,6 +507,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_SIMPLE_COMP_EVID, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c index 999c22b7b..4062ecf91 100644 --- a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c +++ b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c @@ -107,6 +107,10 @@ struct private_tcg_pts_attr_simple_evid_final_t { */ chunk_t evid_sig; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -139,14 +143,24 @@ METHOD(pa_tnc_attr_t, set_noskip_flag,void, this->noskip_flag = noskip; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_simple_evid_final_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_simple_evid_final_t *this) { - free(this->value.ptr); - free(this->pcr_comp.ptr); - free(this->tpm_quote_sig.ptr); - free(this->evid_sig.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->pcr_comp.ptr); + free(this->tpm_quote_sig.ptr); + free(this->evid_sig.ptr); + free(this); + } } METHOD(pa_tnc_attr_t, build, void, @@ -326,6 +340,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_quote_info = _get_quote_info, @@ -338,6 +353,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags, .comp_hash_algorithm = comp_hash_algorithm, .pcr_comp = pcr_comp, .tpm_quote_sig = tpm_quote_sig, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -361,6 +377,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_quote_info = _get_quote_info, @@ -370,6 +387,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_SIMPLE_EVID_FINAL, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c index adb562381..944a12cc9 100644 --- a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c +++ b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c @@ -72,6 +72,11 @@ struct private_tcg_pts_attr_tpm_version_info_t { * TPM Version Information */ chunk_t tpm_version_info; + + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -135,12 +140,22 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_tpm_version_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_tpm_version_info_t *this) { - free(this->value.ptr); - free(this->tpm_version_info.ptr); - free(this); + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->tpm_version_info.ptr); + free(this); + } } METHOD(tcg_pts_attr_tpm_version_info_t, get_tpm_version_info, chunk_t, @@ -173,6 +188,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_tpm_version_info = _get_tpm_version_info, @@ -181,6 +197,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info) .vendor_id = PEN_TCG, .type = TCG_PTS_TPM_VERSION_INFO, .tpm_version_info = chunk_clone(tpm_version_info), + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -204,6 +221,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_tpm_version_info = _get_tpm_version_info, @@ -212,6 +230,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_TPM_VERSION_INFO, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c index ecdc4c928..a9f4a115d 100644 --- a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c +++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c @@ -104,6 +104,10 @@ struct private_tcg_pts_attr_file_meta_t { */ pts_file_meta_t *metadata; + /** + * Reference count + */ + refcount_t ref; }; METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, @@ -268,12 +272,22 @@ end: return status; } +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_pts_attr_file_meta_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + METHOD(pa_tnc_attr_t, destroy, void, private_tcg_pts_attr_file_meta_t *this) { - this->metadata->destroy(this->metadata); - free(this->value.ptr); - free(this); + if (ref_put(&this->ref)) + { + this->metadata->destroy(this->metadata); + free(this->value.ptr); + free(this); + } } METHOD(tcg_pts_attr_file_meta_t, get_metadata, pts_file_meta_t*, @@ -299,6 +313,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_metadata = _get_metadata, @@ -306,6 +321,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata) .vendor_id = PEN_TCG, .type = TCG_PTS_UNIX_FILE_META, .metadata = metadata, + .ref = 1, ); return &this->public.pa_tnc_attribute; @@ -329,6 +345,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .get_ref = _get_ref, .destroy = _destroy, }, .get_metadata = _get_metadata, @@ -336,6 +353,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data) .vendor_id = PEN_TCG, .type = TCG_PTS_UNIX_FILE_META, .value = chunk_clone(data), + .ref = 1, ); return &this->public.pa_tnc_attribute; |