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 } 321