1 /* $NetBSD: vendorid.c,v 1.4 2006/09/09 16:22:10 manu 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 "isakmp_xauth.h" 63 #include "isakmp_cfg.h" 64 #endif 65 66 static struct vendor_id all_vendor_ids[] = { 67 { VENDORID_IPSEC_TOOLS, "IPSec-Tools" }, 68 { VENDORID_GSSAPI_LONG, "A GSS-API Authentication Method for IKE" }, 69 { VENDORID_GSSAPI , "GSSAPI" }, 70 { VENDORID_MS_NT5 , "MS NT5 ISAKMPOAKLEY" }, 71 { VENDORID_NATT_00 , "draft-ietf-ipsec-nat-t-ike-00" }, 72 { VENDORID_NATT_01 , "draft-ietf-ipsec-nat-t-ike-01" }, 73 { VENDORID_NATT_02 , "draft-ietf-ipsec-nat-t-ike-02" }, 74 { VENDORID_NATT_02_N , "draft-ietf-ipsec-nat-t-ike-02\n" }, 75 { VENDORID_NATT_03 , "draft-ietf-ipsec-nat-t-ike-03" }, 76 { VENDORID_NATT_04 , "draft-ietf-ipsec-nat-t-ike-04" }, 77 { VENDORID_NATT_05 , "draft-ietf-ipsec-nat-t-ike-05" }, 78 { VENDORID_NATT_06 , "draft-ietf-ipsec-nat-t-ike-06" }, 79 { VENDORID_NATT_07 , "draft-ietf-ipsec-nat-t-ike-07" }, 80 { VENDORID_NATT_08 , "draft-ietf-ipsec-nat-t-ike-08" }, 81 { VENDORID_NATT_RFC , "RFC 3947" }, 82 { VENDORID_XAUTH , "draft-ietf-ipsra-isakmp-xauth-06.txt" }, 83 { VENDORID_UNITY , "CISCO-UNITY" }, 84 { VENDORID_FRAG , "FRAGMENTATION" }, 85 /* Just a readable string for DPD ... */ 86 { VENDORID_DPD , "DPD" }, 87 /* Other known Vendor IDs */ 88 { VENDORID_KAME , "KAME/racoon" }, 89 }; 90 91 #define NUMVENDORIDS (sizeof(all_vendor_ids)/sizeof(all_vendor_ids[0])) 92 93 #define DPD_MAJOR_VERSION 0x01 94 #define DPD_MINOR_VERSION 0x00 95 96 const char vendorid_dpd_hash[] = { 97 0xAF, 0xCA, 0xD7, 0x13, 98 0x68, 0xA1, 0xF1, 0xC9, 99 0x6B, 0x86, 0x96, 0xFC, 100 0x77, 0x57, DPD_MAJOR_VERSION, DPD_MINOR_VERSION 101 }; 102 103 104 static vchar_t *vendorid_fixup(int, vchar_t *t); 105 106 static struct vendor_id * 107 lookup_vendor_id_by_id (int id) 108 { 109 int i; 110 111 for (i = 0; i < NUMVENDORIDS; i++) 112 if (all_vendor_ids[i].id == id) 113 return &all_vendor_ids[i]; 114 115 return NULL; 116 } 117 118 const char * 119 vid_string_by_id (int id) 120 { 121 struct vendor_id *current; 122 123 if (id == VENDORID_DPD) 124 return vendorid_dpd_hash; 125 126 current = lookup_vendor_id_by_id(id); 127 128 return current ? current->string : NULL; 129 } 130 131 static struct vendor_id * 132 lookup_vendor_id_by_hash (const char *hash) 133 { 134 int i; 135 unsigned char *h = (unsigned char *)hash; 136 137 for (i = 0; i < NUMVENDORIDS; i++) 138 if (strncmp(all_vendor_ids[i].hash->v, hash, 139 all_vendor_ids[i].hash->l) == 0) 140 return &all_vendor_ids[i]; 141 142 return NULL; 143 } 144 145 void 146 compute_vendorids (void) 147 { 148 int i; 149 vchar_t vid; 150 151 for (i = 0; i < NUMVENDORIDS; i++) { 152 /* VENDORID_DPD is not a MD5 sum... */ 153 if(all_vendor_ids[i].id == VENDORID_DPD){ 154 all_vendor_ids[i].hash = vmalloc(sizeof(vendorid_dpd_hash)); 155 if (all_vendor_ids[i].hash == NULL) { 156 plog(LLV_ERROR, LOCATION, NULL, 157 "unable to get memory for VID hash\n"); 158 exit(1); /* this really shouldn't happen */ 159 } 160 memcpy(all_vendor_ids[i].hash->v, vendorid_dpd_hash, 161 sizeof(vendorid_dpd_hash)); 162 continue; 163 } 164 165 vid.v = (char *) all_vendor_ids[i].string; 166 vid.l = strlen(vid.v); 167 168 all_vendor_ids[i].hash = eay_md5_one(&vid); 169 if (all_vendor_ids[i].hash == NULL) 170 plog(LLV_ERROR, LOCATION, NULL, 171 "unable to hash vendor ID string\n"); 172 173 /* Special cases */ 174 all_vendor_ids[i].hash = 175 vendorid_fixup(all_vendor_ids[i].id, 176 all_vendor_ids[i].hash); 177 } 178 } 179 180 /* 181 * set hashed vendor id. 182 * hash function is always MD5. 183 */ 184 vchar_t * 185 set_vendorid(int vendorid) 186 { 187 struct vendor_id *current; 188 vchar_t vid, *new; 189 190 if (vendorid == VENDORID_UNKNOWN) { 191 /* 192 * The default unknown ID gets translated to 193 * KAME/racoon. 194 */ 195 vendorid = VENDORID_DEFAULT; 196 } 197 198 current = lookup_vendor_id_by_id(vendorid); 199 if (current == NULL) { 200 plog(LLV_ERROR, LOCATION, NULL, 201 "invalid vendor ID index: %d\n", vendorid); 202 return (NULL); 203 } 204 205 /* The rest of racoon expects a private copy 206 * of the VID that could be free'd after use. 207 * That's why we don't return the original pointer. */ 208 return vdup(current->hash); 209 } 210 211 /* 212 * Check the vendor ID payload -- return the vendor ID index 213 * if we find a recognized one, or UNKNOWN if we don't. 214 * 215 * gen ... points to Vendor ID payload. 216 */ 217 int 218 check_vendorid(struct isakmp_gen *gen) 219 { 220 vchar_t vid, *vidhash; 221 int i, vidlen; 222 struct vendor_id *current; 223 224 if (gen == NULL) 225 return (VENDORID_UNKNOWN); 226 227 vidlen = ntohs(gen->len) - sizeof(*gen); 228 229 current = lookup_vendor_id_by_hash((char *)(gen + 1)); 230 if (!current) 231 goto unknown; 232 233 if (current->hash->l < vidlen) 234 plog(LLV_INFO, LOCATION, NULL, 235 "received broken Microsoft ID: %s\n", 236 current->string); 237 else 238 plog(LLV_INFO, LOCATION, NULL, 239 "received Vendor ID: %s\n", 240 current->string); 241 242 return current->id; 243 244 unknown: 245 plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); 246 plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen); 247 return (VENDORID_UNKNOWN); 248 } 249 250 int 251 handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen) 252 { 253 int vid_numeric; 254 255 vid_numeric = check_vendorid(gen); 256 if (vid_numeric == VENDORID_UNKNOWN) 257 return vid_numeric; 258 259 #ifdef ENABLE_NATT 260 if (natt_vendorid(vid_numeric)) 261 natt_handle_vendorid(iph1, vid_numeric); 262 #endif 263 #ifdef ENABLE_HYBRID 264 switch (vid_numeric) { 265 case VENDORID_XAUTH: 266 iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH; 267 break; 268 case VENDORID_UNITY: 269 iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY; 270 break; 271 default: 272 break; 273 } 274 #endif 275 #ifdef ENABLE_DPD 276 if (vid_numeric == VENDORID_DPD && 277 (iph1->rmconf == NULL || iph1->rmconf->dpd)) { 278 iph1->dpd_support = 1; 279 plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n"); 280 } 281 #endif 282 283 return vid_numeric; 284 } 285 286 static vchar_t * 287 vendorid_fixup(vendorid, vidhash) 288 int vendorid; 289 vchar_t *vidhash; 290 { 291 switch(vendorid) { 292 case VENDORID_XAUTH: { /* The vendor Id is truncated */ 293 vchar_t *tmp; 294 295 if ((tmp = vmalloc(8)) == NULL) { 296 plog(LLV_ERROR, LOCATION, NULL, 297 "unable to hash vendor ID string\n"); 298 return NULL; 299 } 300 301 memcpy(tmp->v, vidhash->v, 8); 302 vfree(vidhash); 303 vidhash = tmp; 304 305 break; 306 } 307 case VENDORID_UNITY: /* Two bytes tweak */ 308 vidhash->v[14] = 0x01; 309 vidhash->v[15] = 0x00; 310 break; 311 312 default: 313 break; 314 } 315 316 return vidhash; 317 } 318