From: Tobias Brunner Date: Wed, 10 Feb 2016 09:11:31 +0000 (+0100) Subject: ikev1: Send and verify IPv6 addresses correctly X-Git-Tag: 5.4.0dr8~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91d80298f9de5e7d792b7cb0a6c7a2c61784d744;p=thirdparty%2Fstrongswan.git ikev1: Send and verify IPv6 addresses correctly According to the mode-config draft there is no prefix sent for IPv6 addresses in IKEv1. We still accept 17 bytes long addresses for backwards compatibility with older strongSwan releases. Fixes #1304. --- diff --git a/src/libcharon/encoding/payloads/configuration_attribute.c b/src/libcharon/encoding/payloads/configuration_attribute.c index 481bb7bc65..0bc94708fc 100644 --- a/src/libcharon/encoding/payloads/configuration_attribute.c +++ b/src/libcharon/encoding/payloads/configuration_attribute.c @@ -144,6 +144,13 @@ METHOD(payload_t, verify, status_t, } break; case INTERNAL_IP6_ADDRESS: + if (this->type == PLV1_CONFIGURATION_ATTRIBUTE && + this->length_or_value == 16) + { /* 16 bytes are correct for IKEv1, but older releases sent a + * prefix byte so we still accept 0 or 17 as in IKEv2 */ + break; + } + /* fall-through */ case INTERNAL_IP6_SUBNET: if (this->length_or_value != 0 && this->length_or_value != 17) { diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c index a03477e187..b9f9240095 100644 --- a/src/libcharon/sa/ikev1/tasks/mode_config.c +++ b/src/libcharon/sa/ikev1/tasks/mode_config.c @@ -76,35 +76,20 @@ typedef struct { */ static configuration_attribute_t *build_vip(host_t *vip) { - configuration_attribute_type_t type; - chunk_t chunk, prefix; + configuration_attribute_type_t type = INTERNAL_IP4_ADDRESS; + chunk_t chunk; - if (vip->get_family(vip) == AF_INET) + if (vip->get_family(vip) == AF_INET6) { - type = INTERNAL_IP4_ADDRESS; - if (vip->is_anyaddr(vip)) - { - chunk = chunk_empty; - } - else - { - chunk = vip->get_address(vip); - } + type = INTERNAL_IP6_ADDRESS; + } + if (vip->is_anyaddr(vip)) + { + chunk = chunk_empty; } else { - type = INTERNAL_IP6_ADDRESS; - if (vip->is_anyaddr(vip)) - { - chunk = chunk_empty; - } - else - { - prefix = chunk_alloca(1); - *prefix.ptr = 64; - chunk = vip->get_address(vip); - chunk = chunk_cata("cc", chunk, prefix); - } + chunk = vip->get_address(vip); } return configuration_attribute_create_chunk(PLV1_CONFIGURATION_ATTRIBUTE, type, chunk); @@ -165,8 +150,8 @@ static void process_attribute(private_mode_config_t *this, } else { - /* skip prefix byte in IPv6 payload*/ - if (family == AF_INET6) + /* skip prefix byte in IPv6 payload sent by older releases */ + if (family == AF_INET6 && addr.len == 17) { addr.len--; }