]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike: Add additional Vendor IDs for third-party implementations
authorNoel Kuntze <noel.kuntze@thermi.consulting>
Mon, 10 May 2021 11:03:36 +0000 (13:03 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 21 May 2021 15:50:35 +0000 (17:50 +0200)
For some that are followed by unknown data (e.g. detailed version
information) we only do a prefix match.

Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Closes strongswan/strongswan#393.

src/libcharon/sa/ikev1/tasks/isakmp_vendor.c
src/libcharon/sa/ikev2/tasks/ike_vendor.c

index b26a11bb4b2121775edc76f9c109c5cb47a26559..918f9a72ee7567bf252a8ed9b8efafe3cbecf1f5 100644 (file)
@@ -84,6 +84,8 @@ static struct {
        ike_extension_t extension;
        /* send yourself? */
        bool send;
+       /* stored id is just a prefix for a longer, more specific one */
+       bool prefix;
        /* length of vendor ID string */
        int len;
        /* vendor ID string */
@@ -91,76 +93,139 @@ static struct {
 } vendor_ids[] = {
 
        /* strongSwan MD5("strongSwan") */
-       { "strongSwan", EXT_STRONGSWAN, FALSE, 16,
+       { "strongSwan", EXT_STRONGSWAN, FALSE, FALSE, 16,
          "\x88\x2f\xe5\x6d\x6f\xd2\x0d\xbc\x22\x51\x61\x3b\x2e\xbe\x5b\xeb"},
 
        /* XAuth, MD5("draft-ietf-ipsra-isakmp-xauth-06.txt") */
-       { "XAuth", EXT_XAUTH, TRUE, 8,
+       { "XAuth", EXT_XAUTH, TRUE, FALSE, 8,
          "\x09\x00\x26\x89\xdf\xd6\xb7\x12"},
 
        /* Dead peer detection, RFC 3706 */
-       { "DPD", EXT_DPD, TRUE, 16,
+       { "DPD", EXT_DPD, TRUE, FALSE, 16,
          "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00"},
 
        /* CISCO-UNITY, similar to DPD the last two bytes indicate the version */
-       { "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16,
+       { "Cisco Unity", EXT_CISCO_UNITY, FALSE, TRUE, 16,
          "\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. Windows peers send this VID
         * without capabilities, but accept it with and without capabilities. */
-       { "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, 20,
+       { "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, 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,
+       { "MS NT5 ISAKMPOAKLEY", EXT_MS_WINDOWS, FALSE, TRUE, 20,
          "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x00"},
 
+       { "Cisco VPN Concentrator", 0, FALSE, TRUE, 16,
+         "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a"},
+
+       { "Cisco VPN 3000 client", 0, FALSE, FALSE, 20,
+         "\xf6\xf7\xef\xc7\xf5\xae\xb8\xcb\x15\x8c\xb9\xd0\x94\xba\x69\xe7"},
+
+       { "KAME/racoon", 0, FALSE, FALSE, 16,
+         "\x70\x03\xcb\xc1\x09\x7d\xbe\x9c\x26\x00\xba\x69\x83\xbc\x8b\x35"},
+
+       { "ZyXEL ZyWALL Router", 0, FALSE, FALSE, 20,
+         "\xb8\x58\xd1\xad\xdd\x08\xc1\xe8\xad\xaf\xea\x15\x06\x08\xaa\x44\x97\xaa\x6c\xc8"},
+
+       { "ZyXEL ZyWALL USG 100", 0, FALSE, FALSE, 14,
+         "\xf7\x58\xf2\x26\x68\x75\x0f\x03\xb0\x8d\xf6\xeb\xe1\xd0"},
+
+       { "ZyXEL ZyWALL", 0, FALSE, FALSE, 20,
+         "\x62\x50\x27\x74\x9d\x5a\xb9\x7f\x56\x16\xc1\x60\x27\x65\xcf\x48\x0a\x3b\x7d\x0b"},
+
+       { "Sonicwall 1", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x01"},
+
+       { "Sonicwall 2", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x02"},
+
+       { "Sonicwall 3", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x03"},
+
+       { "Sonicwall 5", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x05"},
+
+       { "Sonicwall 6", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x06"},
+
+       { "Sonicwall 7", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x07"},
+
+       { "Sonicwall 8", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x08"},
+
+       { "Sonicwall a", 0, FALSE, TRUE, 8,
+         "\x40\x4b\xf4\x39\x52\x2c\xa3\xf6"},
+
+       { "Sonicwall b", 0, FALSE, TRUE, 8,
+         "\xda\x8e\x93\x78\x80\x01\x00\x00"},
+
+       { "Sonicwall c", 0, FALSE, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf7\x00\x01"},
+
+       { "Fortigate", 0, FALSE, FALSE, 16,
+         "\x1d\x6e\x17\x8f\x6c\x2c\x0b\xe2\x84\x98\x54\x65\x45\x0f\xe9\xd4"},
+
+       /* Checkpoint devices send a version blob after this VID */
+       { "Checkpoint Firewall", 0, FALSE, TRUE, 20,
+         "\xf4\xed\x19\xe0\xc1\x14\xeb\x51\x6f\xaa\xac\x0e\xe3\x7d\xaf\x28\x07\xb4\x38\x1f"},
+
+       /* Juniper SRX and Netscreen devices send this VID and a version number */
+       { "NetScreen Technologies", 0, NULL, TRUE, 20,
+         "\x69\x93\x69\x22\x87\x41\xc6\xd4\xca\x09\x4c\x93\xe2\x42\xc9\xde\x19\xe7\xb7\xc6"},
+
+       /* Probably the Juniper SRX VID */
+       { "Juniper SRX", 0, NULL, FALSE, 20,
+         "\xfd\x80\x88\x04\xdf\x73\xb1\x51\x50\x70\x9d\x87\x80\x44\xcd\xe0\xac\x1e\xfc\xde"},
+
 }, vendor_natt_ids[] = {
 
        /* NAT-Traversal VIDs ordered by preference */
 
        /* NAT-Traversal, MD5("RFC 3947") */
-       { "NAT-T (RFC 3947)", EXT_NATT, TRUE, 16,
+       { "NAT-T (RFC 3947)", EXT_NATT, FALSE, TRUE, 16,
          "\x4a\x13\x1c\x81\x07\x03\x58\x45\x5c\x57\x28\xf2\x0e\x95\x45\x2f"},
 
        { "draft-ietf-ipsec-nat-t-ike-03", EXT_NATT | EXT_NATT_DRAFT_02_03,
-         FALSE, 16,
+         FALSE, FALSE, 16,
          "\x7d\x94\x19\xa6\x53\x10\xca\x6f\x2c\x17\x9d\x92\x15\x52\x9d\x56"},
 
        { "draft-ietf-ipsec-nat-t-ike-02", EXT_NATT | EXT_NATT_DRAFT_02_03,
-         FALSE, 16,
+         FALSE, FALSE, 16,
          "\xcd\x60\x46\x43\x35\xdf\x21\xf8\x7c\xfd\xb2\xfc\x68\xb6\xa4\x48"},
 
        { "draft-ietf-ipsec-nat-t-ike-02\\n", EXT_NATT | EXT_NATT_DRAFT_02_03,
-         TRUE, 16,
+         FALSE, TRUE, 16,
          "\x90\xcb\x80\x91\x3e\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f"},
 
-       { "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, FALSE, 16,
          "\x8f\x8d\x83\x82\x6d\x24\x6b\x6f\xc7\xa8\xa6\xa4\x28\xc1\x1d\xe8"},
 
-       { "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, FALSE, 16,
          "\x43\x9b\x59\xf8\xba\x67\x6c\x4c\x77\x37\xae\x22\xea\xb8\xf5\x82"},
 
-       { "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, FALSE, 16,
          "\x4d\x1e\x0e\x13\x6d\xea\xfa\x34\xc4\xf3\xea\x9f\x02\xec\x72\x85"},
 
-       { "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, FALSE, 16,
          "\x80\xd0\xbb\x3d\xef\x54\x56\x5e\xe8\x46\x45\xd4\xc8\x5c\xe3\xee"},
 
-       { "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, FALSE, 16,
          "\x99\x09\xb6\x4e\xed\x93\x7c\x65\x73\xde\x52\xac\xe9\x52\xfa\x6b"},
 
-       { "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, FALSE, 16,
          "\x44\x85\x15\x2d\x18\xb6\xbb\xcd\x0b\xe8\xa8\x46\x95\x79\xdd\xcc"},
 
-       { "draft-ietf-ipsec-nat-t-ike", 0, FALSE, 16,
+       { "draft-ietf-ipsec-nat-t-ike", 0, FALSE, FALSE, 16,
          "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"},
 
-       { "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, 16,
+       { "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, FALSE, 16,
          "\x61\x05\xc4\x22\xe7\x68\x47\xe4\x3f\x96\x84\x80\x12\x92\xae\xcd"},
 
-       { "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, 16,
+       { "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, FALSE, 16,
          "\x27\xba\xb5\xdc\x01\xea\x07\x60\xea\x4e\x31\x90\xac\x27\xc0\xd0"},
 
 };
@@ -175,29 +240,25 @@ static const uint32_t fragmentation_ike = 0x80000000;
 
 static bool is_known_vid(chunk_t data, int i)
 {
-       switch (vendor_ids[i].extension)
+       if (vendor_ids[i].extension == EXT_IKE_FRAGMENTATION)
        {
-               case EXT_IKE_FRAGMENTATION:
-                       if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16))
+               if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16))
+               {
+                       switch (data.len)
                        {
-                               switch (data.len)
-                               {
-                                       case 16:
-                                               return TRUE;
-                                       case 20:
-                                               return untoh32(&data.ptr[16]) & fragmentation_ike;
-                               }
+                               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);
-               case EXT_CISCO_UNITY:
-                       return data.len == 16 && memeq(data.ptr, vendor_ids[i].id, 14);
-               default:
-                       return chunk_equals(data, chunk_create(vendor_ids[i].id,
-                                                                                                  vendor_ids[i].len));
+               }
+       }
+       if (vendor_ids[i].prefix)
+       {
+               data.len = min(data.len, vendor_ids[i].len);
        }
-       return FALSE;
+       return chunk_equals(data, chunk_create(vendor_ids[i].id,
+                                                                                  vendor_ids[i].len));
 }
 
 /**
index d455f28ab66ba62c4123fa5f7e0a632cb6ab66f3..5db1d185b1ec6e09e3b89ef68a56b897e401bac4 100644 (file)
@@ -74,6 +74,8 @@ typedef struct {
        ike_extension_t extension;
        /* Value from strongswan.conf, whether to send vendor ID */
        char *setting;
+       /* Prefix matching only */
+       bool prefix;
        /* length of vendor ID string, 0 for NULL terminated */
        int len;
        /* vendor ID string */
@@ -83,7 +85,7 @@ typedef struct {
 /**
  * Get the data of a vendor ID as a chunk
  */
-static chunk_t get_vid_data(vid_data_t *data)
+static inline chunk_t get_vid_data(vid_data_t *data)
 {
        return chunk_create(data->id, data->len ?: strlen(data->id));
 }
@@ -93,26 +95,54 @@ static chunk_t get_vid_data(vid_data_t *data)
  */
 static vid_data_t vids[] = {
        /* strongSwan MD5("strongSwan") */
-       { "strongSwan", EXT_STRONGSWAN, "send_vendor_id", 16,
+       { "strongSwan", EXT_STRONGSWAN, "send_vendor_id", FALSE, 16,
          "\x88\x2f\xe5\x6d\x6f\xd2\x0d\xbc\x22\x51\x61\x3b\x2e\xbe\x5b\xeb"},
-       { "Cisco Delete Reason", 0, NULL, 0,
+       { "Cisco Delete Reason", 0, NULL, FALSE, 0,
          "CISCO-DELETE-REASON" },
-       { "Cisco FlexVPN Supported", 0, "cisco_flexvpn", 0,
+       { "Cisco FlexVPN Supported", 0, "cisco_flexvpn", FALSE, 0,
          "FLEXVPN-SUPPORTED" },
-       { "Cisco Copyright (c) 2009", 0, NULL, 0,
+       { "Cisco Copyright (c) 2009", 0, NULL, FALSE, 0,
          "CISCO(COPYRIGHT)&Copyright (c) 2009 Cisco Systems, Inc." },
-       { "FRAGMENTATION", 0, NULL, 16,
+       { "FRAGMENTATION", 0, NULL, FALSE, 16,
          "\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3"},
-       { "MS NT5 ISAKMPOAKLEY v7", 0, NULL, 20,
+       { "MS NT5 ISAKMPOAKLEY v7", 0, NULL, FALSE, 20,
          "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x07"},
-       { "MS NT5 ISAKMPOAKLEY v8", 0, NULL, 20,
+       { "MS NT5 ISAKMPOAKLEY v8", 0, NULL, FALSE, 20,
          "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x08"},
-       { "MS NT5 ISAKMPOAKLEY v9", 0, NULL, 20,
+       { "MS NT5 ISAKMPOAKLEY v9", 0, NULL, FALSE, 20,
          "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x09"},
-       { "MS-Negotiation Discovery Capable", 0, NULL, 16,
+       { "MS-Negotiation Discovery Capable", 0, NULL, FALSE, 16,
          "\xfb\x1d\xe3\xcd\xf3\x41\xb7\xea\x16\xb7\xe5\xbe\x08\x55\xf1\x20"},
-       { "Vid-Initial-Contact", 0, NULL, 16,
+       { "Vid-Initial-Contact", 0, NULL, FALSE, 16,
          "\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19"},
+       { "Cisco VPN Concentrator", 0, NULL, TRUE, 16,
+         "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a"},
+       { "Cisco VPN 3000 client", 0, NULL, FALSE, 20,
+         "\xf6\xf7\xef\xc7\xf5\xae\xb8\xcb\x15\x8c\xb9\xd0\x94\xba\x69\xe7"},
+       { "ZyXEL ZyWALL Router", 0, NULL, FALSE, 20,
+         "\xb8\x58\xd1\xad\xdd\x08\xc1\xe8\xad\xaf\xea\x15\x06\x08\xaa\x44\x97\xaa\x6c\xc8"},
+       { "ZyXEL ZyWALL USG 100", 0, NULL, FALSE, 14,
+         "\xf7\x58\xf2\x26\x68\x75\x0f\x03\xb0\x8d\xf6\xeb\xe1\xd0"},
+       { "ZyXEL ZyWALL", 0, NULL, FALSE, 20,
+         "\x62\x50\x27\x74\x9d\x5a\xb9\x7f\x56\x16\xc1\x60\x27\x65\xcf\x48\x0a\x3b\x7d\x0b"},
+       { "Sonicwall 7", 0, NULL, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x07"},
+       { "Sonicwall 8", 0, NULL, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf6\x00\x08"},
+       { "Sonicwall a", 0, NULL, TRUE, 8,
+         "\x40\x4b\xf4\x39\x52\x2c\xa3\xf6"},
+       { "Sonicwall b", 0, NULL, TRUE, 8,
+         "\xda\x8e\x93\x78\x80\x01\x00\x00"},
+       { "Sonicwall c", 0, NULL, TRUE, 8,
+         "\x5b\x36\x2b\xc8\x20\xf7\x00\x01"},
+       { "Fortigate", 0, NULL, FALSE, 16,
+         "\x1d\x6e\x17\x8f\x6c\x2c\x0b\xe2\x84\x98\x54\x65\x45\x0f\xe9\xd4"},
+       { "Checkpoint Firewall", 0, NULL, TRUE, 20,
+         "\xf4\xed\x19\xe0\xc1\x14\xeb\x51\x6f\xaa\xac\x0e\xe3\x7d\xaf\x28\x07\xb4\x38\x1f"},
+       { "NetScreen Technologies", 0, NULL, TRUE, 20,
+         "\x69\x93\x69\x22\x87\x41\xc6\xd4\xca\x09\x4c\x93\xe2\x42\xc9\xde\x19\xe7\xb7\xc6"},
+       { "Juniper SRX", 0, NULL, FALSE, 20,
+         "\xfd\x80\x88\x04\xdf\x73\xb1\x51\x50\x70\x9d\x87\x80\x44\xcd\xe0\xac\x1e\xfc\xde"},
 };
 
 METHOD(task_t, build, status_t,
@@ -143,6 +173,20 @@ METHOD(task_t, build, status_t,
        return this->initiator ? NEED_MORE : SUCCESS;
 }
 
+/**
+ * Check if the given known vendor ID matches a received VID or its prefix
+ */
+static inline bool known_vid(vid_data_t *vid, chunk_t data)
+{
+       chunk_t known = get_vid_data(vid);
+
+       if (vid->prefix)
+       {
+               data.len = min(data.len, known.len);
+       }
+       return chunk_equals(known, data);
+}
+
 METHOD(task_t, process, status_t,
        private_ike_vendor_t *this, message_t *message)
 {
@@ -164,7 +208,7 @@ METHOD(task_t, process, status_t,
 
                        for (i = 0; i < countof(vids); i++)
                        {
-                               if (chunk_equals(get_vid_data(&vids[i]), data))
+                               if (known_vid(&vids[i], data))
                                {
                                        DBG1(DBG_IKE, "received %s vendor ID", vids[i].desc);
                                        if (vids[i].extension)