Annotation of embedaddon/ipsec-tools/src/racoon/vendorid.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>