1 /* $NetBSD: vendorid.c,v 1.9 2018/05/19 19:23:15 maxv 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 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 189 if (vendorid == VENDORID_UNKNOWN) { 190 /* 191 * The default unknown ID gets translated to 192 * KAME/racoon. 193 */ 194 vendorid = VENDORID_DEFAULT; 195 } 196 197 current = lookup_vendor_id_by_id(vendorid); 198 if (current == NULL) { 199 plog(LLV_ERROR, LOCATION, NULL, 200 "invalid vendor ID index: %d\n", vendorid); 201 return (NULL); 202 } 203 204 /* The rest of racoon expects a private copy 205 * of the VID that could be free'd after use. 206 * That's why we don't return the original pointer. */ 207 return vdup(current->hash); 208 } 209 210 /* 211 * Check the vendor ID payload -- return the vendor ID index 212 * if we find a recognized one, or UNKNOWN if we don't. 213 * 214 * gen ... points to Vendor ID payload. 215 */ 216 static int 217 check_vendorid(struct isakmp_gen *gen) 218 { 219 int vidlen; 220 struct vendor_id *current; 221 222 if (gen == NULL) 223 return (VENDORID_UNKNOWN); 224 225 vidlen = ntohs(gen->len) - sizeof(*gen); 226 227 current = lookup_vendor_id_by_hash((char *)(gen + 1)); 228 if (!current) 229 goto unknown; 230 231 if (current->hash->l < vidlen) 232 plog(LLV_INFO, LOCATION, NULL, 233 "received broken Microsoft ID: %s\n", 234 current->string); 235 else 236 plog(LLV_INFO, LOCATION, NULL, 237 "received Vendor ID: %s\n", 238 current->string); 239 240 return current->id; 241 242 unknown: 243 plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); 244 plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen); 245 return (VENDORID_UNKNOWN); 246 } 247 248 int 249 handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen) 250 { 251 int vid_numeric; 252 253 vid_numeric = check_vendorid(gen); 254 if (vid_numeric == VENDORID_UNKNOWN) 255 return vid_numeric; 256 257 iph1->vendorid_mask |= BIT(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