Return to vendorid.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
1.1 ! misho 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: }