121259Swollman/* $NetBSD: vendorid.c,v 1.7 2009/03/12 10:57:26 tteras Exp $ */ 221259Swollman 321259Swollman/* Id: vendorid.c,v 1.10 2006/02/22 16:10:21 vanhu Exp */ 421259Swollman 521259Swollman/* 621259Swollman * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 721259Swollman * All rights reserved. 821259Swollman * 921259Swollman * Redistribution and use in source and binary forms, with or without 1021259Swollman * modification, are permitted provided that the following conditions 1121259Swollman * are met: 1221259Swollman * 1. Redistributions of source code must retain the above copyright 1321259Swollman * notice, this list of conditions and the following disclaimer. 1421259Swollman * 2. Redistributions in binary form must reproduce the above copyright 1521259Swollman * notice, this list of conditions and the following disclaimer in the 1621259Swollman * documentation and/or other materials provided with the distribution. 1721259Swollman * 3. Neither the name of the project nor the names of its contributors 1821259Swollman * may be used to endorse or promote products derived from this software 1921259Swollman * without specific prior written permission. 2021259Swollman * 2121259Swollman * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2221259Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2321259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2421259Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2521259Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2621259Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2721259Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2821259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2921259Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3021259Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3121259Swollman * SUCH DAMAGE. 3221259Swollman */ 3321259Swollman 3450477Speter#include "config.h" 3521259Swollman 3621259Swollman#include <sys/types.h> 3721259Swollman#include <sys/param.h> 3821259Swollman 3921259Swollman#include <stdlib.h> 4021259Swollman#include <stdio.h> 4121259Swollman#include <string.h> 4221259Swollman#include <errno.h> 4321259Swollman#include <ctype.h> 4421259Swollman 4521259Swollman#include "var.h" 4621259Swollman#include "misc.h" 4721259Swollman#include "vmbuf.h" 4821259Swollman#include "plog.h" 4921259Swollman#include "debug.h" 5021259Swollman 5121259Swollman#include "localconf.h" 5221259Swollman#include "isakmp_var.h" 5321259Swollman#include "isakmp.h" 5421259Swollman#include "vendorid.h" 55108533Sschweikh#include "crypto_openssl.h" 5621259Swollman#include "handler.h" 5721259Swollman#include "remoteconf.h" 5821259Swollman#ifdef ENABLE_NATT 5921259Swollman#include "nattraversal.h" 60108533Sschweikh#endif 6121259Swollman#ifdef ENABLE_HYBRID 6221259Swollman#include <resolv.h> 6321259Swollman#include "isakmp_xauth.h" 6421259Swollman#include "isakmp_cfg.h" 6521259Swollman#endif 6621259Swollman 6721259Swollmanstatic struct vendor_id all_vendor_ids[] = { 6821259Swollman{ VENDORID_IPSEC_TOOLS, "IPSec-Tools" }, 6921259Swollman{ VENDORID_GSSAPI_LONG, "A GSS-API Authentication Method for IKE" }, 7083366Sjulian{ VENDORID_GSSAPI , "GSSAPI" }, 7121259Swollman{ VENDORID_MS_NT5 , "MS NT5 ISAKMPOAKLEY" }, 7285074Sru{ VENDORID_NATT_00 , "draft-ietf-ipsec-nat-t-ike-00" }, 7321259Swollman{ VENDORID_NATT_01 , "draft-ietf-ipsec-nat-t-ike-01" }, 7421259Swollman{ VENDORID_NATT_02 , "draft-ietf-ipsec-nat-t-ike-02" }, 7521259Swollman{ VENDORID_NATT_02_N , "draft-ietf-ipsec-nat-t-ike-02\n" }, 7621259Swollman{ VENDORID_NATT_03 , "draft-ietf-ipsec-nat-t-ike-03" }, 7721259Swollman{ VENDORID_NATT_04 , "draft-ietf-ipsec-nat-t-ike-04" }, 7821259Swollman{ VENDORID_NATT_05 , "draft-ietf-ipsec-nat-t-ike-05" }, 7969224Sjlemon{ VENDORID_NATT_06 , "draft-ietf-ipsec-nat-t-ike-06" }, 8069152Sjlemon{ VENDORID_NATT_07 , "draft-ietf-ipsec-nat-t-ike-07" }, 81126264Smlaier{ VENDORID_NATT_08 , "draft-ietf-ipsec-nat-t-ike-08" }, 8269224Sjlemon{ VENDORID_NATT_RFC , "RFC 3947" }, 8374914Sjhb{ VENDORID_XAUTH , "draft-ietf-ipsra-isakmp-xauth-06.txt" }, 8474914Sjhb{ VENDORID_UNITY , "CISCO-UNITY" }, 8583130Sjlemon{ VENDORID_FRAG , "FRAGMENTATION" }, 8669152Sjlemon/* Just a readable string for DPD ... */ 87121816Sbrooks{ VENDORID_DPD , "DPD" }, 88121816Sbrooks/* Other known Vendor IDs */ 8960938Sjake{ VENDORID_KAME , "KAME/racoon" }, 9060938Sjake}; 9160938Sjake 9272084Sphk#define NUMVENDORIDS (sizeof(all_vendor_ids)/sizeof(all_vendor_ids[0])) 9321259Swollman 9421259Swollman#define DPD_MAJOR_VERSION 0x01 9521259Swollman#define DPD_MINOR_VERSION 0x00 9621259Swollman 9721259Swollmanconst char vendorid_dpd_hash[] = { 9821259Swollman 0xAF, 0xCA, 0xD7, 0x13, 9921259Swollman 0x68, 0xA1, 0xF1, 0xC9, 10021259Swollman 0x6B, 0x86, 0x96, 0xFC, 10121259Swollman 0x77, 0x57, DPD_MAJOR_VERSION, DPD_MINOR_VERSION 10221259Swollman}; 10369152Sjlemon 10421259Swollman 10521259Swollmanstatic vchar_t *vendorid_fixup(int, vchar_t *t); 10621259Swollman 10721259Swollmanstatic struct vendor_id * 10821259Swollmanlookup_vendor_id_by_id (int id) 10921259Swollman{ 11021259Swollman int i; 11184380Smjacob 11284380Smjacob for (i = 0; i < NUMVENDORIDS; i++) 11384380Smjacob if (all_vendor_ids[i].id == id) 11484380Smjacob return &all_vendor_ids[i]; 11586797Sluigi 11686797Sluigi return NULL; 11786797Sluigi} 11886797Sluigi 11986797Sluigiconst char * 12086797Sluigivid_string_by_id (int id) 12186797Sluigi{ 12286797Sluigi struct vendor_id *current; 12386797Sluigi 12486797Sluigi if (id == VENDORID_DPD) 12586797Sluigi return vendorid_dpd_hash; 12686797Sluigi 12786797Sluigi current = lookup_vendor_id_by_id(id); 12886797Sluigi 12986797Sluigi return current ? current->string : NULL; 13084380Smjacob} 13121259Swollman 13221259Swollmanstatic struct vendor_id * 13360938Sjakelookup_vendor_id_by_hash (const char *hash) 134121816Sbrooks{ 135121816Sbrooks int i; 136121816Sbrooks unsigned char *h = (unsigned char *)hash; 13721259Swollman 13883130Sjlemon for (i = 0; i < NUMVENDORIDS; i++) 13983130Sjlemon if (strncmp(all_vendor_ids[i].hash->v, hash, 14021259Swollman all_vendor_ids[i].hash->l) == 0) 14121259Swollman return &all_vendor_ids[i]; 14221259Swollman 143106931Ssam return NULL; 144102052Ssobomax} 14583624Sjlemon 14683624Sjlemonvoid 14721259Swollmancompute_vendorids (void) 14821259Swollman{ 14921259Swollman int i; 15021259Swollman vchar_t vid; 15121404Swollman 15221404Swollman for (i = 0; i < NUMVENDORIDS; i++) { 15321259Swollman /* VENDORID_DPD is not a MD5 sum... */ 15421259Swollman if(all_vendor_ids[i].id == VENDORID_DPD){ 15592725Salfred all_vendor_ids[i].hash = vmalloc(sizeof(vendorid_dpd_hash)); 15692725Salfred if (all_vendor_ids[i].hash == NULL) { 157106931Ssam plog(LLV_ERROR, LOCATION, NULL, 158106931Ssam "unable to get memory for VID hash\n"); 15921259Swollman exit(1); /* this really shouldn't happen */ 16092725Salfred } 16121259Swollman memcpy(all_vendor_ids[i].hash->v, vendorid_dpd_hash, 16292725Salfred sizeof(vendorid_dpd_hash)); 16321259Swollman continue; 16492725Salfred } 16521259Swollman 16692725Salfred vid.v = (char *) all_vendor_ids[i].string; 16721404Swollman vid.l = strlen(vid.v); 16892725Salfred 16921259Swollman all_vendor_ids[i].hash = eay_md5_one(&vid); 170123220Simp if (all_vendor_ids[i].hash == NULL) 171127828Sluigi plog(LLV_ERROR, LOCATION, NULL, 172127828Sluigi "unable to hash vendor ID string\n"); 173127828Sluigi 174122524Srwatson /* Special cases */ 175121161Sume all_vendor_ids[i].hash = 176127828Sluigi vendorid_fixup(all_vendor_ids[i].id, 177127828Sluigi all_vendor_ids[i].hash); 178121161Sume } 179121470Sume} 180121470Sume 18121259Swollman/* 18269152Sjlemon * set hashed vendor id. 18392725Salfred * hash function is always MD5. 18421259Swollman */ 18521259Swollmanvchar_t * 18621259Swollmanset_vendorid(int vendorid) 18721259Swollman{ 18821259Swollman struct vendor_id *current; 18921259Swollman vchar_t vid, *new; 19021259Swollman 19121259Swollman if (vendorid == VENDORID_UNKNOWN) { 19258698Sjlemon /* 19321259Swollman * The default unknown ID gets translated to 19421259Swollman * KAME/racoon. 19521259Swollman */ 19621259Swollman vendorid = VENDORID_DEFAULT; 19721259Swollman } 19821259Swollman 19921259Swollman current = lookup_vendor_id_by_id(vendorid); 20021259Swollman if (current == NULL) { 20121259Swollman plog(LLV_ERROR, LOCATION, NULL, 20221259Swollman "invalid vendor ID index: %d\n", vendorid); 20321259Swollman return (NULL); 20421259Swollman } 20521259Swollman 20621259Swollman /* The rest of racoon expects a private copy 20721259Swollman * of the VID that could be free'd after use. 20821259Swollman * That's why we don't return the original pointer. */ 20953541Sshin return vdup(current->hash); 21053541Sshin} 21153541Sshin 21253541Sshin/* 21321259Swollman * Check the vendor ID payload -- return the vendor ID index 21421259Swollman * if we find a recognized one, or UNKNOWN if we don't. 21521259Swollman * 21621259Swollman * gen ... points to Vendor ID payload. 21721259Swollman */ 21821259Swollmanstatic int 21921259Swollmancheck_vendorid(struct isakmp_gen *gen) 22021259Swollman{ 22121259Swollman vchar_t vid, *vidhash; 22221259Swollman int i, vidlen; 22321259Swollman struct vendor_id *current; 22421259Swollman 22572200Sbmilekic if (gen == NULL) 22672200Sbmilekic return (VENDORID_UNKNOWN); 22769152Sjlemon 22869152Sjlemon vidlen = ntohs(gen->len) - sizeof(*gen); 22969152Sjlemon 23021259Swollman current = lookup_vendor_id_by_hash((char *)(gen + 1)); 23169152Sjlemon if (!current) 23269152Sjlemon goto unknown; 23369152Sjlemon 23469152Sjlemon if (current->hash->l < vidlen) 23569152Sjlemon plog(LLV_INFO, LOCATION, NULL, 23669152Sjlemon "received broken Microsoft ID: %s\n", 23769152Sjlemon current->string); 23869152Sjlemon else 23969152Sjlemon plog(LLV_INFO, LOCATION, NULL, 24069152Sjlemon "received Vendor ID: %s\n", 24169152Sjlemon current->string); 24269152Sjlemon 24369152Sjlemon return current->id; 24469152Sjlemon 24569152Sjlemonunknown: 24669152Sjlemon plog(LLV_DEBUG, LOCATION, NULL, "received unknown Vendor ID\n"); 24769152Sjlemon plogdump(LLV_DEBUG, (char *)(gen + 1), vidlen); 24869152Sjlemon return (VENDORID_UNKNOWN); 24969152Sjlemon} 25069152Sjlemon 25169152Sjlemonint 25269152Sjlemonhandle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen) 25369152Sjlemon{ 25469152Sjlemon int vid_numeric; 25569152Sjlemon 25669152Sjlemon vid_numeric = check_vendorid(gen); 25769152Sjlemon if (vid_numeric == VENDORID_UNKNOWN) 25869152Sjlemon return vid_numeric; 25969152Sjlemon 26069152Sjlemon iph1->vendorid_mask |= BIT(vid_numeric); 26169152Sjlemon 26269152Sjlemon#ifdef ENABLE_NATT 26369152Sjlemon if (natt_vendorid(vid_numeric)) 26469152Sjlemon natt_handle_vendorid(iph1, vid_numeric); 26569152Sjlemon#endif 26669152Sjlemon#ifdef ENABLE_HYBRID 26769152Sjlemon switch (vid_numeric) { 26869152Sjlemon case VENDORID_XAUTH: 26969152Sjlemon iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH; 27069152Sjlemon break; 27169152Sjlemon case VENDORID_UNITY: 27269152Sjlemon iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY; 27369152Sjlemon break; 27469152Sjlemon default: 27569152Sjlemon break; 27669152Sjlemon } 27769152Sjlemon#endif 27869152Sjlemon#ifdef ENABLE_DPD 27969152Sjlemon if (vid_numeric == VENDORID_DPD && 28069152Sjlemon (iph1->rmconf == NULL || iph1->rmconf->dpd)) { 28169152Sjlemon iph1->dpd_support = 1; 28269152Sjlemon plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n"); 28369152Sjlemon } 28469152Sjlemon#endif 28569152Sjlemon 28669152Sjlemon return vid_numeric; 28769152Sjlemon} 28869152Sjlemon 28955205Speterstatic vchar_t * 290126264Smlaiervendorid_fixup(vendorid, vidhash) 291126264Smlaier int vendorid; 292126264Smlaier vchar_t *vidhash; 293126264Smlaier{ 294126264Smlaier switch(vendorid) { 295126264Smlaier case VENDORID_XAUTH: { /* The vendor Id is truncated */ 296126264Smlaier vchar_t *tmp; 297126264Smlaier 298126264Smlaier if ((tmp = vmalloc(8)) == NULL) { 299126264Smlaier plog(LLV_ERROR, LOCATION, NULL, 300126264Smlaier "unable to hash vendor ID string\n"); 301126264Smlaier return NULL; 302126264Smlaier } 303121470Sume 304121470Sume memcpy(tmp->v, vidhash->v, 8); 305121470Sume vfree(vidhash); 306121470Sume vidhash = tmp; 307121470Sume 308121470Sume break; 309121470Sume } 31069152Sjlemon case VENDORID_UNITY: /* Two bytes tweak */ 31169152Sjlemon vidhash->v[14] = 0x01; 31221259Swollman vidhash->v[15] = 0x00; 31335210Sbde break; 31469152Sjlemon 31521259Swollman default: 31669152Sjlemon break; 31721259Swollman } 31869152Sjlemon 31969152Sjlemon return vidhash; 32069152Sjlemon} 32169152Sjlemon