Annotation of embedaddon/ipsec-tools/src/racoon/vendorid.c, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: vendorid.c,v 1.8 2009/09/01 12:22:09 tteras Exp $ */
2:
3: /* Id: vendorid.c,v 1.10 2006/02/22 16:10:21 vanhu Exp */
4:
5: /*
6: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. Neither the name of the project nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include "config.h"
35:
36: #include <sys/types.h>
37: #include <sys/param.h>
38:
39: #include <stdlib.h>
40: #include <stdio.h>
41: #include <string.h>
42: #include <errno.h>
43: #include <ctype.h>
44:
45: #include "var.h"
46: #include "misc.h"
47: #include "vmbuf.h"
48: #include "plog.h"
49: #include "debug.h"
50:
51: #include "localconf.h"
52: #include "isakmp_var.h"
53: #include "isakmp.h"
54: #include "vendorid.h"
55: #include "crypto_openssl.h"
56: #include "handler.h"
57: #include "remoteconf.h"
58: #ifdef ENABLE_NATT
59: #include "nattraversal.h"
60: #endif
61: #ifdef ENABLE_HYBRID
62: #include <resolv.h>
63: #include "isakmp_xauth.h"
64: #include "isakmp_cfg.h"
65: #endif
66:
67: static struct vendor_id all_vendor_ids[] = {
68: { VENDORID_IPSEC_TOOLS, "IPSec-Tools" },
69: { VENDORID_GSSAPI_LONG, "A GSS-API Authentication Method for IKE" },
70: { VENDORID_GSSAPI , "GSSAPI" },
71: { VENDORID_MS_NT5 , "MS NT5 ISAKMPOAKLEY" },
72: { VENDORID_NATT_00 , "draft-ietf-ipsec-nat-t-ike-00" },
73: { VENDORID_NATT_01 , "draft-ietf-ipsec-nat-t-ike-01" },
74: { VENDORID_NATT_02 , "draft-ietf-ipsec-nat-t-ike-02" },
75: { VENDORID_NATT_02_N , "draft-ietf-ipsec-nat-t-ike-02\n" },
76: { VENDORID_NATT_03 , "draft-ietf-ipsec-nat-t-ike-03" },
77: { VENDORID_NATT_04 , "draft-ietf-ipsec-nat-t-ike-04" },
78: { VENDORID_NATT_05 , "draft-ietf-ipsec-nat-t-ike-05" },
79: { VENDORID_NATT_06 , "draft-ietf-ipsec-nat-t-ike-06" },
80: { VENDORID_NATT_07 , "draft-ietf-ipsec-nat-t-ike-07" },
81: { VENDORID_NATT_08 , "draft-ietf-ipsec-nat-t-ike-08" },
82: { VENDORID_NATT_RFC , "RFC 3947" },
83: { VENDORID_XAUTH , "draft-ietf-ipsra-isakmp-xauth-06.txt" },
84: { VENDORID_UNITY , "CISCO-UNITY" },
85: { VENDORID_FRAG , "FRAGMENTATION" },
86: /* Just a readable string for DPD ... */
87: { VENDORID_DPD , "DPD" },
88: /* Other known Vendor IDs */
89: { VENDORID_KAME , "KAME/racoon" },
90: };
91:
92: #define NUMVENDORIDS (sizeof(all_vendor_ids)/sizeof(all_vendor_ids[0]))
93:
94: #define DPD_MAJOR_VERSION 0x01
95: #define DPD_MINOR_VERSION 0x00
96:
97: const char vendorid_dpd_hash[] = {
98: 0xAF, 0xCA, 0xD7, 0x13,
99: 0x68, 0xA1, 0xF1, 0xC9,
100: 0x6B, 0x86, 0x96, 0xFC,
101: 0x77, 0x57, DPD_MAJOR_VERSION, DPD_MINOR_VERSION
102: };
103:
104:
105: static vchar_t *vendorid_fixup(int, vchar_t *t);
106:
107: static struct vendor_id *
108: lookup_vendor_id_by_id (int id)
109: {
110: int i;
111:
112: for (i = 0; i < NUMVENDORIDS; i++)
113: if (all_vendor_ids[i].id == id)
114: return &all_vendor_ids[i];
115:
116: return NULL;
117: }
118:
119: const char *
120: vid_string_by_id (int id)
121: {
122: struct vendor_id *current;
123:
124: if (id == VENDORID_DPD)
125: return vendorid_dpd_hash;
126:
127: current = lookup_vendor_id_by_id(id);
128:
129: return current ? current->string : NULL;
130: }
131:
132: static struct vendor_id *
133: lookup_vendor_id_by_hash (const char *hash)
134: {
135: int i;
136: unsigned char *h = (unsigned char *)hash;
137:
138: for (i = 0; i < NUMVENDORIDS; i++)
139: if (strncmp(all_vendor_ids[i].hash->v, hash,
140: all_vendor_ids[i].hash->l) == 0)
141: return &all_vendor_ids[i];
142:
143: return NULL;
144: }
145:
146: void
147: compute_vendorids (void)
148: {
149: int i;
150: vchar_t vid;
151:
152: for (i = 0; i < NUMVENDORIDS; i++) {
153: /* VENDORID_DPD is not a MD5 sum... */
154: if(all_vendor_ids[i].id == VENDORID_DPD){
155: all_vendor_ids[i].hash = vmalloc(sizeof(vendorid_dpd_hash));
156: if (all_vendor_ids[i].hash == NULL) {
157: plog(LLV_ERROR, LOCATION, NULL,
158: "unable to get memory for VID hash\n");
159: exit(1); /* this really shouldn't happen */
160: }
161: memcpy(all_vendor_ids[i].hash->v, vendorid_dpd_hash,
162: sizeof(vendorid_dpd_hash));
163: continue;
164: }
165:
166: vid.v = (char *) all_vendor_ids[i].string;
167: vid.l = strlen(vid.v);
168:
169: all_vendor_ids[i].hash = eay_md5_one(&vid);
170: if (all_vendor_ids[i].hash == NULL)
171: plog(LLV_ERROR, LOCATION, NULL,
172: "unable to hash vendor ID string\n");
173:
174: /* Special cases */
175: all_vendor_ids[i].hash =
176: vendorid_fixup(all_vendor_ids[i].id,
177: all_vendor_ids[i].hash);
178: }
179: }
180:
181: /*
182: * set hashed vendor id.
183: * hash function is always MD5.
184: */
185: vchar_t *
186: set_vendorid(int vendorid)
187: {
188: struct vendor_id *current;
189: vchar_t vid, *new;
190:
191: if (vendorid == VENDORID_UNKNOWN) {
192: /*
193: * The default unknown ID gets translated to
194: * KAME/racoon.
195: */
196: vendorid = VENDORID_DEFAULT;
197: }
198:
199: current = lookup_vendor_id_by_id(vendorid);
200: if (current == NULL) {
201: plog(LLV_ERROR, LOCATION, NULL,
202: "invalid vendor ID index: %d\n", vendorid);
203: return (NULL);
204: }
205:
206: /* The rest of racoon expects a private copy
207: * of the VID that could be free'd after use.
208: * That's why we don't return the original pointer. */
209: return vdup(current->hash);
210: }
211:
212: /*
213: * Check the vendor ID payload -- return the vendor ID index
214: * if we find a recognized one, or UNKNOWN if we don't.
215: *
216: * gen ... points to Vendor ID payload.
217: */
218: static int
219: check_vendorid(struct isakmp_gen *gen)
220: {
221: vchar_t vid, *vidhash;
222: int i, vidlen;
223: struct vendor_id *current;
224:
225: if (gen == NULL)
226: return (VENDORID_UNKNOWN);
227:
228: vidlen = ntohs(gen->len) - sizeof(*gen);
229:
230: current = lookup_vendor_id_by_hash((char *)(gen + 1));
231: if (!current)
232: goto unknown;
233:
234: if (current->hash->l < vidlen)
235: plog(LLV_INFO, LOCATION, NULL,
236: "received broken Microsoft ID: %s\n",
237: current->string);
238: else
239: plog(LLV_INFO, LOCATION, NULL,
240: "received Vendor ID: %s\n",
241: current->string);
242:
243: return current->id;
244:
245: unknown:
246: plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n");
247: plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen);
248: return (VENDORID_UNKNOWN);
249: }
250:
251: int
252: handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen)
253: {
254: int vid_numeric;
255:
256: vid_numeric = check_vendorid(gen);
257: if (vid_numeric == VENDORID_UNKNOWN)
258: return vid_numeric;
259:
260: iph1->vendorid_mask |= BIT(vid_numeric);
261:
262: #ifdef ENABLE_NATT
263: if (natt_vendorid(vid_numeric))
264: natt_handle_vendorid(iph1, vid_numeric);
265: #endif
266: #ifdef ENABLE_HYBRID
267: switch (vid_numeric) {
268: case VENDORID_XAUTH:
269: iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH;
270: break;
271: case VENDORID_UNITY:
272: iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY;
273: break;
274: default:
275: break;
276: }
277: #endif
278: #ifdef ENABLE_DPD
279: if (vid_numeric == VENDORID_DPD &&
280: (iph1->rmconf == NULL || iph1->rmconf->dpd)) {
281: iph1->dpd_support = 1;
282: plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n");
283: }
284: #endif
285:
286: return vid_numeric;
287: }
288:
289: static vchar_t *
290: vendorid_fixup(vendorid, vidhash)
291: int vendorid;
292: vchar_t *vidhash;
293: {
294: switch(vendorid) {
295: case VENDORID_XAUTH: { /* The vendor Id is truncated */
296: vchar_t *tmp;
297:
298: if ((tmp = vmalloc(8)) == NULL) {
299: plog(LLV_ERROR, LOCATION, NULL,
300: "unable to hash vendor ID string\n");
301: return NULL;
302: }
303:
304: memcpy(tmp->v, vidhash->v, 8);
305: vfree(vidhash);
306: vidhash = tmp;
307:
308: break;
309: }
310: case VENDORID_UNITY: /* Two bytes tweak */
311: vidhash->v[14] = 0x01;
312: vidhash->v[15] = 0x00;
313: break;
314:
315: default:
316: break;
317: }
318:
319: return vidhash;
320: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>