diff options
author | Volker Rümelin <vr_strongswan@t-online.de> | 2014-09-25 09:18:17 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2014-10-10 10:54:37 +0200 |
commit | 05db0f97e3051150a38511fdb35c9d58bb6e989b (patch) | |
tree | c538a9599c2182e99409138e20cf52c198b64be3 /src | |
parent | 3633b80147eae6c630d3e0177d6f475d6549a0d9 (diff) | |
download | strongswan-05db0f97e3051150a38511fdb35c9d58bb6e989b.tar.bz2 strongswan-05db0f97e3051150a38511fdb35c9d58bb6e989b.tar.xz |
ikev1: Add fragmentation support for Windows peers
I still think ipsec/l2tp with fragmentation support is a useful
fallback option in case the Windows IKEv2 connection fails because
of fragmentation problems.
Tested with Windows XP, 7 and 8.1.
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 30 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.h | 2 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_vendor.c | 39 |
3 files changed, 58 insertions, 13 deletions
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 8b659c005..0d4aa0cc1 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (c) 2014 Volker Rümelin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include <sys/stat.h> #include <errno.h> @@ -1024,6 +1046,14 @@ METHOD(ike_sa_t, generate_message_fragmented, status_t, break; case FRAGMENTATION_YES: use_frags = supports_extension(this, EXT_IKE_FRAGMENTATION); + if (use_frags && this->version == IKEV1 && + supports_extension(this, EXT_MS_WINDOWS)) + { + /* It seems Windows 7 and 8 peers only accept proprietary + * fragmented messages if they expect certificates. */ + use_frags = message->get_payload(message, + PLV1_CERTIFICATE) != NULL; + } break; default: break; diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index f04fab009..c72d87367 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -102,7 +102,7 @@ enum ike_extension_t { EXT_EAP_ONLY_AUTHENTICATION = (1<<5), /** - * peer is probably a Windows 7 RAS client + * peer is probably a Windows RAS client */ EXT_MS_WINDOWS = (1<<6), diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c index 426c4bd69..0162fd84e 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c @@ -15,7 +15,7 @@ */ /* - * Copyright (C) 2012 Volker Rümelin + * Copyright (C) 2012-2014 Volker Rümelin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -106,10 +106,15 @@ static struct { "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, /* Proprietary IKE fragmentation extension. Capabilities are handled - * specially on receipt of this VID. */ + * specially on receipt of this VID. Windows peers send this VID + * without capabilities, but accept it with and without capabilities. */ { "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, 20, "\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3\x80\x00\x00\x00"}, + /* Windows peers send this VID and a version number */ + { "MS NT5 ISAKMPOAKLEY", EXT_MS_WINDOWS, FALSE, 20, + "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x00"}, + }, vendor_natt_ids[] = { /* NAT-Traversal VIDs ordered by preference */ @@ -167,15 +172,27 @@ static struct { */ static const u_int32_t fragmentation_ike = 0x80000000; -/** - * Check if the given vendor ID indicate support for fragmentation - */ -static bool fragmentation_supported(chunk_t data, int i) +static bool is_known_vid(chunk_t data, int i) { - if (vendor_ids[i].extension == EXT_IKE_FRAGMENTATION && - data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16)) + switch (vendor_ids[i].extension) { - return untoh32(&data.ptr[16]) & fragmentation_ike; + case EXT_IKE_FRAGMENTATION: + if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16)) + { + switch (data.len) + { + case 16: + return TRUE; + case 20: + return untoh32(&data.ptr[16]) & fragmentation_ike; + } + } + break; + case EXT_MS_WINDOWS: + return data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16); + default: + return chunk_equals(data, chunk_create(vendor_ids[i].id, + vendor_ids[i].len)); } return FALSE; } @@ -251,9 +268,7 @@ static void process(private_isakmp_vendor_t *this, message_t *message) for (i = 0; i < countof(vendor_ids); i++) { - if (chunk_equals(data, chunk_create(vendor_ids[i].id, - vendor_ids[i].len)) || - fragmentation_supported(data, i)) + if (is_known_vid(data, i)) { DBG1(DBG_IKE, "received %s vendor ID", vendor_ids[i].desc); if (vendor_ids[i].extension) |