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