File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / vendorid.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, v0_8_0p0, v0_8_0, HEAD
ipsec-tools

    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>