OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / pluto / vendor.c
1 /* FreeS/WAN ISAKMP VendorID
2  * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
3  *
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>.
8  *
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
12  * for more details.
13  *
14  * RCSID $Id: vendor.c,v 1.4 2003-09-29 05:08:44 philipc Exp $
15  */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <ctype.h>
20
21 #include <freeswan.h>
22
23 #include "constants.h"
24 #include "defs.h"
25 #include "log.h"
26 #include "md5.h"
27 #include "id.h"
28 #include "x509.h"
29 #include "connections.h"
30 #include "packet.h"
31 #include "demux.h"
32 #include "whack.h"
33 #include "vendor.h"
34
35 #ifdef NAT_TRAVERSAL
36 #include "nat_traversal.h"
37 #endif
38
39 /**
40  * Unknown/Special VID:
41  *
42  * SafeNet SoftRemote 8.0.0:
43  *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e302e3020284275696c6420313029000000
44  *  >> 382e302e3020284275696c6420313029 = '8.0.0 (Build 10)'
45  *  da8e937880010000
46  *
47  * SafeNet SoftRemote 9.0.1
48  *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310392e302e3120284275696c6420313229000000
49  *  >> 392e302e3120284275696c6420313229 = '9.0.1 (Build 12)'
50  *  da8e937880010000
51  *
52  * Netscreen:
53  *  d6b45f82f24bacb288af59a978830ab7
54  *  cf49908791073fb46439790fdeb6aeed981101ab0000000500000300
55  *
56  * Cisco:
57  *  c32364b3b4f447eb17c488ab2a480a57
58  *  1f07f70eaa6514d3b0fa96542a500305
59  *  1f07f70eaa6514d3b0fa96542a500300
60  *  1f07f70eaa6514d3b0fa96542a500301 (VPN 3000 version 3.1 ??)
61  *  afcad71368a1f1c96b8696fc77570100 (Dead Peer Detection ?)
62  *  6d761ddc26aceca1b0ed11fabbb860c4
63  *
64  * Microsoft L2TP (???):
65  *  47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e312e3020284275696c6420313029000000
66  *  >> 382e312e3020284275696c6420313029 = '8.1.0 (Build 10)'
67  *  3025dbd21062b9e53dc441c6aab5293600000000
68  *  da8e937880010000
69  *
70  * If someone know what they mean, mail me.
71  */
72
73 #define MAX_LOG_VID_LEN    8
74
75 #define VID_KEEP                   0x0000
76 #define VID_MD5HASH                0x0001
77 #define VID_STRING                 0x0002
78 #define VID_FSWAN_HASH             0x0004
79
80 #define VID_SUBSTRING_DUMPHEXA     0x0100
81 #define VID_SUBSTRING_DUMPASCII    0x0200
82 #define VID_SUBSTRING  (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII)
83
84 struct vid_struct {
85         unsigned int id;
86         unsigned short flags;
87         const char *data;
88         const char *descr;
89         const char *vid;
90         unsigned int vid_len;
91 };
92
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 },
99
100 static struct vid_struct _vid_tab[] = {
101
102         /* Implementation names */
103
104         { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
105
106         DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
107
108         { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
109                 "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
110
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")
117
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")
149
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",
153                 16 },
154
155         /**
156          * Timestep VID seen:
157          *   - 54494d455354455020312053475720313532302033313520322e303145303133
158          *     = 'TIMESTEP 1 SGW 1520 315 2.01E013'
159          */
160         { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
161                 NULL, NULL, 0 },
162
163         DEC_FSWAN_VID(FSWAN_2_00_VID,
164                 "Linux FreeS/WAN 2.00 PLUTO_SENDS_VENDORID",
165                 "FreeS/WAN 2.00")
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)")
172
173         /* NAT-Traversal */
174
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")
185
186         /* misc */
187         
188         { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
189                 "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
190
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",
193                 16 },
194
195         /**
196          * Netscreen:
197          * 4865617274426561745f4e6f74696679386b0100  (HeartBeat_Notify + 386b0100)
198          */
199         { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
200                 "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
201
202         DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
203
204         /* -- */
205         { 0, 0, NULL, NULL, NULL, 0 }
206
207 };
208
209 static const char _hexdig[] = "0123456789abcdef";
210
211 static int _vid_struct_init = 0;
212
213 void init_vendorid(void)
214 {
215         struct vid_struct *vid;
216         MD5_CTX ctx;
217         int i;
218
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);
224                 }
225                 else if (vid->flags & VID_MD5HASH) {
226                         /** VendorID is a string to hash with MD5 **/
227                         char *vidm =  malloc(MD5_DIGEST_SIZE);
228                         vid->vid = vidm;
229                         if (vidm) {
230                                 MD5Init(&ctx);
231                                 MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
232                                 MD5Final(vidm, &ctx);
233                                 vid->vid_len = MD5_DIGEST_SIZE;
234                         }
235                 }
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);
241                         vid->vid = vidm;
242                         if (vidm) {
243                                 MD5Init(&ctx);
244                                 MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
245                                 MD5Final(hash, &ctx);
246                                 vidm[0] = 'O';
247                                 vidm[1] = 'E';
248 #if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
249                                 memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
250 #else
251                                 memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
252                                 memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
253                                         FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
254 #endif
255                                 for (i = 2; i < FSWAN_VID_SIZE; i++) {
256                                         vidm[i] &= 0x7f;
257                                         vidm[i] |= 0x40;
258                                 }
259                                 vid->vid_len = FSWAN_VID_SIZE;
260                         }
261                 }
262
263                 if (vid->descr == NULL) {
264                         /** Find something to display **/
265                         vid->descr = vid->data;
266                 }
267 #if 0
268                 DBG_log("vendorid_init: %d [%s]",
269                         vid->id,
270                         vid->descr ? vid->descr : ""
271                         );
272                 if (vid->vid) DBG_dump("VID:", vid->vid, vid->vid_len);
273 #endif
274         }
275         _vid_struct_init = 1;
276 }
277
278 static void handle_known_vendorid (struct msg_digest *md,
279         const char *vidstr, size_t len, struct vid_struct *vid)
280 {
281         char vid_dump[128];
282         int vid_usefull = 0;
283         size_t i, j;
284
285         switch (vid->id) {
286 #ifdef NAT_TRAVERSAL
287                 /*
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)
291                  *
292                  * Note: most recent == higher id in vendor.h
293                  */
294                 case VID_NATT_IETF_00:
295                         if ((nat_traversal_enabled) && (!md->nat_traversal_vid)) {
296                                 md->nat_traversal_vid = vid->id;
297                                 vid_usefull = 1;
298                         }
299                         break;
300                 case VID_NATT_IETF_02:
301                 case VID_NATT_IETF_02_N:
302                 case VID_NATT_IETF_03:
303                 case VID_NATT_RFC:
304                         if ((nat_traversal_support_port_floating) &&
305                                 (md->nat_traversal_vid < vid->id)) {
306                                 md->nat_traversal_vid = vid->id;
307                                 vid_usefull = 1;
308                         }
309                         break;
310 #endif
311                 case VID_MISC_DPD:
312                         md->dpd = 1;
313                         vid_usefull = 1;
314                         break;
315                 default:
316                         break;
317         }
318
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);
326                         i+=2, j++) {
327                         vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
328                         vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
329                 }
330         }
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] : '.';
336                 }
337         }
338         else {
339                 /* Dump description (descr) */
340                 snprintf(vid_dump, sizeof(vid_dump), "%s",
341                         vid->descr ? vid->descr : "");
342         }
343
344         loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
345                 vid_usefull ? "received" : "ignoring", vid_dump);
346 }
347
348 void handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
349 {
350         struct vid_struct *pvid;
351
352         if (!_vid_struct_init) {
353                 init_vendorid();
354         }
355
356         /*
357          * Find known VendorID in _vid_tab
358          */
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);
364                                         return;
365                                 }
366                         }
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);
370                                         return;
371                                 }
372                         }
373                 }
374         }
375
376         /*
377          * Unknown VendorID. Log the beginning.
378          */
379         {
380                 char log_vid[2*MAX_LOG_VID_LEN+1];
381                 size_t i;
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];
386                 }
387                 loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
388                         log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
389         }
390 }
391
392 /**
393  * Add a vendor id payload to the msg
394  */
395 bool out_vendorid (u_int8_t np, pb_stream *outs, unsigned int vid)
396 {
397         struct vid_struct *pvid;
398
399         if (!_vid_struct_init) {
400                 init_vendorid();
401         }
402
403         for (pvid = _vid_tab; (pvid->id) && (pvid->id!=vid); pvid++);
404
405         if (pvid->id != vid) return FALSE; /* not found */
406         if (!pvid->vid) return FALSE; /* not initialized */
407
408         DBG(DBG_EMITTING,
409                 DBG_log("out_vendorid(): sending [%s]", pvid->descr);
410         );
411
412         if (!out_modify_previous_np(ISAKMP_NEXT_VID, outs))
413                 return FALSE;
414
415         return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
416                 (char *)pvid->vid, pvid->vid_len, "V_ID");
417 }
418