1 /* $NetBSD: vendorid.c,v 1.3 2005/11/21 14:20:29 manu Exp $ */ 2 3 /* Id: vendorid.c,v 1.7 2005/01/29 16:34:25 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_KAME , "KAME/racoon" }, 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 }; 79 80 #define NUMVENDORIDS (sizeof(all_vendor_ids)/sizeof(all_vendor_ids[0])) 81 82 #define DPD_MAJOR_VERSION 0x01 83 #define DPD_MINOR_VERSION 0x00 84 85 const char vendorid_dpd_hash[] = { 86 0xAF, 0xCA, 0xD7, 0x13, 87 0x68, 0xA1, 0xF1, 0xC9, 88 0x6B, 0x86, 0x96, 0xFC, 89 0x77, 0x57, DPD_MAJOR_VERSION, DPD_MINOR_VERSION 90 }; 91 92 93 static vchar_t *vendorid_fixup(int, vchar_t *t); 94 95 static struct vendor_id * 96 lookup_vendor_id_by_id (int id) 97 { 98 int i; 99 100 for (i = 0; i < NUMVENDORIDS; i++) 101 if (all_vendor_ids[i].id == id) 102 return &all_vendor_ids[i]; 103 104 return NULL; 105 } 106 107 const char * 108 vid_string_by_id (int id) 109 { 110 struct vendor_id *current; 111 112 if (id == VENDORID_DPD) 113 return vendorid_dpd_hash; 114 115 current = lookup_vendor_id_by_id(id); 116 117 return current ? current->string : NULL; 118 } 119 120 static struct vendor_id * 121 lookup_vendor_id_by_hash (const char *hash) 122 { 123 int i; 124 unsigned char *h = (unsigned char *)hash; 125 126 for (i = 0; i < NUMVENDORIDS; i++) 127 if (strncmp(all_vendor_ids[i].hash->v, hash, 128 all_vendor_ids[i].hash->l) == 0) 129 return &all_vendor_ids[i]; 130 131 return NULL; 132 } 133 134 void 135 compute_vendorids (void) 136 { 137 int i; 138 vchar_t vid; 139 140 for (i = 0; i < NUMVENDORIDS; i++) { 141 /* VENDORID_DPD is not a MD5 sum... */ 142 if(i == VENDORID_DPD){ 143 all_vendor_ids[i].hash = vmalloc(sizeof(vendorid_dpd_hash)); 144 if (all_vendor_ids[i].hash == NULL) { 145 plog(LLV_ERROR, LOCATION, NULL, 146 "unable to get memory for VID hash\n"); 147 exit(1); /* this really shouldn't happen */ 148 } 149 memcpy(all_vendor_ids[i].hash->v, vendorid_dpd_hash, 150 sizeof(vendorid_dpd_hash)); 151 continue; 152 } 153 154 vid.v = (char *) all_vendor_ids[i].string; 155 vid.l = strlen(vid.v); 156 157 all_vendor_ids[i].hash = eay_md5_one(&vid); 158 if (all_vendor_ids[i].hash == NULL) 159 plog(LLV_ERROR, LOCATION, NULL, 160 "unable to hash vendor ID string\n"); 161 162 /* Special cases */ 163 all_vendor_ids[i].hash = 164 vendorid_fixup(all_vendor_ids[i].id, 165 all_vendor_ids[i].hash); 166 } 167 } 168 169 /* 170 * set hashed vendor id. 171 * hash function is always MD5. 172 */ 173 vchar_t * 174 set_vendorid(int vendorid) 175 { 176 struct vendor_id *current; 177 vchar_t vid, *new; 178 179 if (vendorid == VENDORID_UNKNOWN) { 180 /* 181 * The default unknown ID gets translated to 182 * KAME/racoon. 183 */ 184 vendorid = VENDORID_KAME; 185 } 186 187 current = lookup_vendor_id_by_id(vendorid); 188 if (current == NULL) { 189 plog(LLV_ERROR, LOCATION, NULL, 190 "invalid vendor ID index: %d\n", vendorid); 191 return (NULL); 192 } 193 194 /* The rest of racoon expects a private copy 195 * of the VID that could be free'd after use. 196 * That's why we don't return the original pointer. */ 197 return vdup(current->hash); 198 } 199 200 /* 201 * Check the vendor ID payload -- return the vendor ID index 202 * if we find a recognized one, or UNKNOWN if we don't. 203 * 204 * gen ... points to Vendor ID payload. 205 */ 206 int 207 check_vendorid(struct isakmp_gen *gen) 208 { 209 vchar_t vid, *vidhash; 210 int i, vidlen; 211 struct vendor_id *current; 212 213 if (gen == NULL) 214 return (VENDORID_UNKNOWN); 215 216 vidlen = ntohs(gen->len) - sizeof(*gen); 217 218 current = lookup_vendor_id_by_hash((char *)(gen + 1)); 219 if (!current) 220 goto unknown; 221 222 if (current->hash->l < vidlen) 223 plog(LLV_INFO, LOCATION, NULL, 224 "received broken Microsoft ID: %s\n", 225 current->string); 226 else 227 plog(LLV_INFO, LOCATION, NULL, 228 "received Vendor ID: %s\n", 229 current->string); 230 231 return current->id; 232 233 unknown: 234 plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); 235 return (VENDORID_UNKNOWN); 236 } 237 238 static vchar_t * 239 vendorid_fixup(vendorid, vidhash) 240 int vendorid; 241 vchar_t *vidhash; 242 { 243 switch(vendorid) { 244 case VENDORID_XAUTH: { /* The vendor Id is truncated */ 245 vchar_t *tmp; 246 247 if ((tmp = vmalloc(8)) == NULL) { 248 plog(LLV_ERROR, LOCATION, NULL, 249 "unable to hash vendor ID string\n"); 250 return NULL; 251 } 252 253 memcpy(tmp->v, vidhash->v, 8); 254 vfree(vidhash); 255 vidhash = tmp; 256 257 break; 258 } 259 case VENDORID_UNITY: /* Two bytes tweak */ 260 vidhash->v[14] = 0x01; 261 vidhash->v[15] = 0x00; 262 break; 263 264 default: 265 break; 266 } 267 268 return vidhash; 269 } 270