diff options
author | Martin Willi <martin@revosec.ch> | 2012-01-04 14:43:15 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-03-20 17:31:33 +0100 |
commit | 927c1dd9d2d7f932c40b890e275184d007c6743d (patch) | |
tree | f947b3468b35cc9f0ccfdbf613cdec49a2a963a6 /src/libcharon/encoding/payloads/proposal_substructure.c | |
parent | b147679a2c1b3c232a13f8f58418b4976571b8da (diff) | |
download | strongswan-927c1dd9d2d7f932c40b890e275184d007c6743d.tar.bz2 strongswan-927c1dd9d2d7f932c40b890e275184d007c6743d.tar.xz |
Support IKEv1 proposal encodings having both lifebytes and a lifetime
Diffstat (limited to 'src/libcharon/encoding/payloads/proposal_substructure.c')
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.c | 125 |
1 files changed, 58 insertions, 67 deletions
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index 77a4fe434..ba7ef9961 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -770,121 +770,112 @@ METHOD(proposal_substructure_t, create_substructure_enumerator, enumerator_t*, } /** - * Get an attribute from a selected transform + * Get an attribute from any transform, 0 if not found */ -static u_int64_t get_attr_tfrm(transform_substructure_t *transform, - transform_attribute_type_t type) +static u_int64_t get_attr(private_proposal_substructure_t *this, + transform_attribute_type_t type) { - enumerator_t *enumerator; + enumerator_t *transforms, *attributes; + transform_substructure_t *transform; transform_attribute_t *attr; - u_int64_t value = 0; - enumerator = transform->create_attribute_enumerator(transform); - while (enumerator->enumerate(enumerator, &attr)) + transforms = this->transforms->create_enumerator(this->transforms); + while (transforms->enumerate(transforms, &transform)) { - if (attr->get_attribute_type(attr) == type) + attributes = transform->create_attribute_enumerator(transform); + while (attributes->enumerate(attributes, &attr)) { - value = attr->get_value(attr); - break; + if (attr->get_attribute_type(attr) == type) + { + attributes->destroy(attributes); + transforms->destroy(transforms); + return attr->get_value(attr); + } } + attributes->destroy(attributes); } - enumerator->destroy(enumerator); - return value; + transforms->destroy(transforms); + return 0; } - /** - * Get an attribute from any transform, 0 if not found + * Look up a lifetime duration of a given kind in all transforms */ -static u_int64_t get_attr(private_proposal_substructure_t *this, - transform_attribute_type_t type, transform_substructure_t **sel) +static u_int64_t get_life_duration(private_proposal_substructure_t *this, + transform_attribute_type_t type_attr, ikev1_life_type_t type, + transform_attribute_type_t dur_attr) { + enumerator_t *transforms, *attributes; transform_substructure_t *transform; - enumerator_t *enumerator; - u_int64_t value = 0; + transform_attribute_t *attr; - enumerator = this->transforms->create_enumerator(this->transforms); - while (enumerator->enumerate(enumerator, &transform)) + transforms = this->transforms->create_enumerator(this->transforms); + while (transforms->enumerate(transforms, &transform)) { - value = get_attr_tfrm(transform, type); - if (value) + attributes = transform->create_attribute_enumerator(transform); + while (attributes->enumerate(attributes, &attr)) { - if (sel) - { - *sel = transform; + if (attr->get_attribute_type(attr) == type_attr && + attr->get_value(attr) == type) + { /* got type attribute, look for duration following next */ + while (attributes->enumerate(attributes, &attr)) + { + if (attr->get_attribute_type(attr) == dur_attr) + { + attributes->destroy(attributes); + transforms->destroy(transforms); + return attr->get_value(attr); + } + } } - break; } + attributes->destroy(attributes); } - enumerator->destroy(enumerator); - return value; + transforms->destroy(transforms); + return 0; } METHOD(proposal_substructure_t, get_lifetime, u_int32_t, private_proposal_substructure_t *this) { - transform_substructure_t *transform; - ikev1_life_type_t type; + u_int32_t duration; switch (this->protocol_id) { case PROTO_IKE: - type = get_attr(this, TATTR_PH1_LIFE_TYPE, &transform); - if (type == IKEV1_LIFE_TYPE_SECONDS) - { - return get_attr_tfrm(transform, TATTR_PH1_LIFE_DURATION); - } - break; + return get_life_duration(this, TATTR_PH1_LIFE_TYPE, + IKEV1_LIFE_TYPE_SECONDS, TATTR_PH1_LIFE_DURATION); case PROTO_ESP: - type = get_attr(this, TATTR_PH2_SA_LIFE_TYPE, &transform); - if (type == IKEV1_LIFE_TYPE_SECONDS) - { - return get_attr_tfrm(transform, TATTR_PH2_SA_LIFE_DURATION); - } - else if (type != IKEV1_LIFE_TYPE_KILOBYTES) + duration = get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, + IKEV1_LIFE_TYPE_SECONDS, TATTR_PH2_SA_LIFE_DURATION); + if (!duration) { /* default to 8 hours, RFC 2407 */ return 28800; } - break; + return duration; default: - break; + return 0; } - return 0; } METHOD(proposal_substructure_t, get_lifebytes, u_int64_t, private_proposal_substructure_t *this) { - transform_substructure_t *transform; - ikev1_life_type_t type; - switch (this->protocol_id) { - case PROTO_IKE: - type = get_attr(this, TATTR_PH1_LIFE_TYPE, &transform); - if (type == IKEV1_LIFE_TYPE_KILOBYTES) - { - return get_attr_tfrm(transform, TATTR_PH1_LIFE_DURATION); - } - break; case PROTO_ESP: - type = get_attr(this, TATTR_PH2_SA_LIFE_TYPE, &transform); - if (type == IKEV1_LIFE_TYPE_KILOBYTES) - { - return get_attr_tfrm(transform, TATTR_PH1_LIFE_DURATION); - } - break; + return 1000 * get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, + IKEV1_LIFE_TYPE_KILOBYTES, TATTR_PH2_SA_LIFE_DURATION); + case PROTO_IKE: default: - break; + return 0; } - return 0; - } METHOD(proposal_substructure_t, get_auth_method, auth_method_t, private_proposal_substructure_t *this) { - switch (get_attr(this, TATTR_PH1_AUTH_METHOD, NULL)) + switch (get_attr(this, TATTR_PH1_AUTH_METHOD)) { case IKEV1_AUTH_PSK: return AUTH_PSK; @@ -908,7 +899,7 @@ METHOD(proposal_substructure_t, get_encap_mode, ipsec_mode_t, private_proposal_substructure_t *this, bool *udp) { *udp = FALSE; - switch (get_attr(this, TATTR_PH2_ENCAP_MODE, NULL)) + switch (get_attr(this, TATTR_PH2_ENCAP_MODE)) { case IKEV1_ENCAP_TRANSPORT: return MODE_TRANSPORT; @@ -1110,7 +1101,7 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1, TATTR_PH2_SA_LIFE_DURATION, lifetime)); } - else if (lifebytes) + if (lifebytes) { transform->add_transform_attribute(transform, transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1, |