1 /* FreeS/WAN ISAKMP VendorID
2 * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: vendor.c,v 1.4 2003-09-29 05:08:44 philipc Exp $
23 #include "constants.h"
29 #include "connections.h"
36 #include "nat_traversal.h"
40 * Unknown/Special VID:
42 * SafeNet SoftRemote 8.0.0:
43 * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e302e3020284275696c6420313029000000
44 * >> 382e302e3020284275696c6420313029 = '8.0.0 (Build 10)'
47 * SafeNet SoftRemote 9.0.1
48 * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310392e302e3120284275696c6420313229000000
49 * >> 392e302e3120284275696c6420313229 = '9.0.1 (Build 12)'
53 * d6b45f82f24bacb288af59a978830ab7
54 * cf49908791073fb46439790fdeb6aeed981101ab0000000500000300
57 * c32364b3b4f447eb17c488ab2a480a57
58 * 1f07f70eaa6514d3b0fa96542a500305
59 * 1f07f70eaa6514d3b0fa96542a500300
60 * 1f07f70eaa6514d3b0fa96542a500301 (VPN 3000 version 3.1 ??)
61 * afcad71368a1f1c96b8696fc77570100 (Dead Peer Detection ?)
62 * 6d761ddc26aceca1b0ed11fabbb860c4
64 * Microsoft L2TP (???):
65 * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e312e3020284275696c6420313029000000
66 * >> 382e312e3020284275696c6420313029 = '8.1.0 (Build 10)'
67 * 3025dbd21062b9e53dc441c6aab5293600000000
70 * If someone know what they mean, mail me.
73 #define MAX_LOG_VID_LEN 8
75 #define VID_KEEP 0x0000
76 #define VID_MD5HASH 0x0001
77 #define VID_STRING 0x0002
78 #define VID_FSWAN_HASH 0x0004
80 #define VID_SUBSTRING_DUMPHEXA 0x0100
81 #define VID_SUBSTRING_DUMPASCII 0x0200
82 #define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII)
93 #define DEC_MD5_VID_D(id,str,descr) \
94 { VID_##id, VID_MD5HASH, str, descr, NULL, 0 },
95 #define DEC_MD5_VID(id,str) \
96 { VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
97 #define DEC_FSWAN_VID(id,str,descr) \
98 { VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 },
100 static struct vid_struct _vid_tab[] = {
102 /* Implementation names */
104 { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
106 DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
108 { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
109 "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
111 DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
112 DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
113 DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
114 DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
115 DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
116 DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
118 /* These ones come from SSH vendors.txt */
119 DEC_MD5_VID(SSH_IPSEC_1_1_0,
120 "Ssh Communications Security IPSEC Express version 1.1.0")
121 DEC_MD5_VID(SSH_IPSEC_1_1_1,
122 "Ssh Communications Security IPSEC Express version 1.1.1")
123 DEC_MD5_VID(SSH_IPSEC_1_1_2,
124 "Ssh Communications Security IPSEC Express version 1.1.2")
125 DEC_MD5_VID(SSH_IPSEC_1_2_1,
126 "Ssh Communications Security IPSEC Express version 1.2.1")
127 DEC_MD5_VID(SSH_IPSEC_1_2_2,
128 "Ssh Communications Security IPSEC Express version 1.2.2")
129 DEC_MD5_VID(SSH_IPSEC_2_0_0,
130 "SSH Communications Security IPSEC Express version 2.0.0")
131 DEC_MD5_VID(SSH_IPSEC_2_1_0,
132 "SSH Communications Security IPSEC Express version 2.1.0")
133 DEC_MD5_VID(SSH_IPSEC_2_1_1,
134 "SSH Communications Security IPSEC Express version 2.1.1")
135 DEC_MD5_VID(SSH_IPSEC_2_1_2,
136 "SSH Communications Security IPSEC Express version 2.1.2")
137 DEC_MD5_VID(SSH_IPSEC_3_0_0,
138 "SSH Communications Security IPSEC Express version 3.0.0")
139 DEC_MD5_VID(SSH_IPSEC_3_0_1,
140 "SSH Communications Security IPSEC Express version 3.0.1")
141 DEC_MD5_VID(SSH_IPSEC_4_0_0,
142 "SSH Communications Security IPSEC Express version 4.0.0")
143 DEC_MD5_VID(SSH_IPSEC_4_0_1,
144 "SSH Communications Security IPSEC Express version 4.0.1")
145 DEC_MD5_VID(SSH_IPSEC_4_1_0,
146 "SSH Communications Security IPSEC Express version 4.1.0")
147 DEC_MD5_VID(SSH_IPSEC_4_2_0,
148 "SSH Communications Security IPSEC Express version 4.2.0")
150 /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
151 { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
152 "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
157 * - 54494d455354455020312053475720313532302033313520322e303145303133
158 * = 'TIMESTEP 1 SGW 1520 315 2.01E013'
160 { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
163 DEC_FSWAN_VID(FSWAN_2_00_VID,
164 "Linux FreeS/WAN 2.00 PLUTO_SENDS_VENDORID",
166 DEC_FSWAN_VID(FSWAN_2_00_X509_1_3_1_VID,
167 "Linux FreeS/WAN 2.00 X.509-1.3.1 PLUTO_SENDS_VENDORID",
168 "FreeS/WAN 2.00 (X.509-1.3.1)")
169 DEC_FSWAN_VID(FSWAN_2_00_X509_1_3_1_LDAP_VID,
170 "Linux FreeS/WAN 2.00 X.509-1.3.1 LDAP PLUTO_SENDS_VENDORID",
171 "FreeS/WAN 2.00 (X.509-1.3.1 + LDAP)")
175 DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
176 DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
177 DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
178 DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
179 DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
180 DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
181 /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
182 DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
183 DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
184 DEC_MD5_VID(NATT_RFC, "Testing NAT-T RFC")
188 { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
189 "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
191 { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
192 "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00",
197 * 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
199 { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
200 "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
202 DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
205 { 0, 0, NULL, NULL, NULL, 0 }
209 static const char _hexdig[] = "0123456789abcdef";
211 static int _vid_struct_init = 0;
213 void init_vendorid(void)
215 struct vid_struct *vid;
219 for (vid = _vid_tab; vid->id; vid++) {
220 if (vid->flags & VID_STRING) {
221 /** VendorID is a string **/
222 vid->vid = strdup(vid->data);
223 vid->vid_len = strlen(vid->data);
225 else if (vid->flags & VID_MD5HASH) {
226 /** VendorID is a string to hash with MD5 **/
227 char *vidm = malloc(MD5_DIGEST_SIZE);
231 MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
232 MD5Final(vidm, &ctx);
233 vid->vid_len = MD5_DIGEST_SIZE;
236 else if (vid->flags & VID_FSWAN_HASH) {
237 /** FreeS/WAN 2.00+ specific hash **/
238 #define FSWAN_VID_SIZE 12
239 unsigned char hash[MD5_DIGEST_SIZE];
240 char *vidm = malloc(FSWAN_VID_SIZE);
244 MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
245 MD5Final(hash, &ctx);
248 #if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
249 memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
251 memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
252 memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
253 FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
255 for (i = 2; i < FSWAN_VID_SIZE; i++) {
259 vid->vid_len = FSWAN_VID_SIZE;
263 if (vid->descr == NULL) {
264 /** Find something to display **/
265 vid->descr = vid->data;
268 DBG_log("vendorid_init: %d [%s]",
270 vid->descr ? vid->descr : ""
272 if (vid->vid) DBG_dump("VID:", vid->vid, vid->vid_len);
275 _vid_struct_init = 1;
278 static void handle_known_vendorid (struct msg_digest *md,
279 const char *vidstr, size_t len, struct vid_struct *vid)
288 * Use most recent supported NAT-Traversal method and ignore the
289 * other ones (implementations will send all supported methods but
290 * only one will be used)
292 * Note: most recent == higher id in vendor.h
294 case VID_NATT_IETF_00:
295 if ((nat_traversal_enabled) && (!md->nat_traversal_vid)) {
296 md->nat_traversal_vid = vid->id;
300 case VID_NATT_IETF_02:
301 case VID_NATT_IETF_02_N:
302 case VID_NATT_IETF_03:
304 if ((nat_traversal_support_port_floating) &&
305 (md->nat_traversal_vid < vid->id)) {
306 md->nat_traversal_vid = vid->id;
319 if (vid->flags & VID_SUBSTRING_DUMPHEXA) {
320 /* Dump description + Hexa */
321 memset(vid_dump, 0, sizeof(vid_dump));
322 snprintf(vid_dump, sizeof(vid_dump), "%s ",
323 vid->descr ? vid->descr : "");
324 for (i=strlen(vid_dump), j=vid->vid_len;
325 (j<len) && (i<sizeof(vid_dump)-2);
327 vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
328 vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
331 else if (vid->flags & VID_SUBSTRING_DUMPASCII) {
332 /* Dump ASCII content */
333 memset(vid_dump, 0, sizeof(vid_dump));
334 for (i=0; (i<len) && (i<sizeof(vid_dump)-1); i++) {
335 vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
339 /* Dump description (descr) */
340 snprintf(vid_dump, sizeof(vid_dump), "%s",
341 vid->descr ? vid->descr : "");
344 loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
345 vid_usefull ? "received" : "ignoring", vid_dump);
348 void handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
350 struct vid_struct *pvid;
352 if (!_vid_struct_init) {
357 * Find known VendorID in _vid_tab
359 for (pvid = _vid_tab; pvid->id; pvid++) {
360 if (pvid->vid && vid && pvid->vid_len && len) {
361 if (pvid->vid_len == len) {
362 if (memcmp(pvid->vid, vid, len)==0) {
363 handle_known_vendorid(md, vid, len, pvid);
367 else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING)) {
368 if (memcmp(pvid->vid, vid, pvid->vid_len)==0) {
369 handle_known_vendorid(md, vid, len, pvid);
377 * Unknown VendorID. Log the beginning.
380 char log_vid[2*MAX_LOG_VID_LEN+1];
382 memset(log_vid, 0, sizeof(log_vid));
383 for (i=0; (i<len) && (i<MAX_LOG_VID_LEN); i++) {
384 log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
385 log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
387 loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
388 log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
393 * Add a vendor id payload to the msg
395 bool out_vendorid (u_int8_t np, pb_stream *outs, unsigned int vid)
397 struct vid_struct *pvid;
399 if (!_vid_struct_init) {
403 for (pvid = _vid_tab; (pvid->id) && (pvid->id!=vid); pvid++);
405 if (pvid->id != vid) return FALSE; /* not found */
406 if (!pvid->vid) return FALSE; /* not initialized */
409 DBG_log("out_vendorid(): sending [%s]", pvid->descr);
412 if (!out_modify_previous_np(ISAKMP_NEXT_VID, outs))
415 return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
416 (char *)pvid->vid, pvid->vid_len, "V_ID");