1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $ */ 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */ 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h> 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h> 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h> 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h> 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h> 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h> 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h> 460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if TIME_WITH_SYS_TIME 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h> 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h> 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if HAVE_SYS_TIME_H 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h> 520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# else 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h> 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 56c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID 57c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#include <resolv.h> 58c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include PATH_IPSEC_H 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h" 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h" 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h" 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h" 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h" 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h" 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h" 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h" 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h" 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h" 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "proposal.h" 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h" 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h" 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_inf.h" 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_quick.h" 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h" 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h" 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h" 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "pfkey.h" 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h" 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "algorithm.h" 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h" 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "proposal.h" 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sainfo.h" 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h" 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h" 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* quick mode */ 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *)); 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int get_sainfo_r __P((struct ph2handle *)); 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int get_proposal_r __P((struct ph2handle *)); 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Quick Mode 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * begin Quick Mode as initiator. send pfkey getspi message to kernel. 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_i1prep(iph2, msg) 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg; /* must be null pointer */ 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_STATUS2) { 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->msgid = isakmp_newmsgid2(iph2->ph1); 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid); 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->ivm == NULL) 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_GETSPISENT; 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't anything if local test mode. */ 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (f_local) { 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send getspi message */ 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendgetspi(iph2) < 0) 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 134c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->sce = sched_new(lcconf->wait_ph2complete, 135c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh pfkey_timeover_stub, iph2); 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * send to responder 145c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_i1send(iph2, msg) 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg; /* must be null pointer */ 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *body = NULL; 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *hash = NULL; 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_gen *gen; 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int pfsgroup, idci, idcr; 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int np; 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ipsecdoi_id_b *id, *id_p; 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg != NULL) { 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "msg has to be NULL in this function.\n"); 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_GETSPIDONE) { 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create SA payload for my proposal */ 1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ipsecdoi_setph2proposal(iph2) < 0) 1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate NONCE value */ 1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); 1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->nonce == NULL) 1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DH value calculation is kicked out into cfparse.y. 1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * because pfs group can not be negotiated, it's only to be checked 1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * acceptable. 1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate KE value if need */ 1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pfsgroup = iph2->proposal->pfs_group; 1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pfsgroup) { 1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* DH group settting if PFS is required. */ 1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { 1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to set DH value.\n"); 1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_dh_generate(iph2->pfsgrp, 1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang &iph2->dhpub, &iph2->dhpriv) < 0) { 1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate ID value */ 2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ipsecdoi_setid2(iph2) < 0) { 2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get ID.\n"); 2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n"); 2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); 2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n"); 2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * we do not attach IDci nor IDcr, under the following condition: 2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - all proposals are transport mode 2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - no MIP6 or proxy 2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - id payload suggests to encrypt all the traffic (no specific 2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * protocol type) 2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang id = (struct ipsecdoi_id_b *)iph2->id->v; 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang id_p = (struct ipsecdoi_id_b *)iph2->id_p->v; 223c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (id->proto_id == 0 224c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && id_p->proto_id == 0 225c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && iph2->ph1->rmconf->support_proxy == 0 226c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && ipsecdoi_transportmode(iph2->proposal)) { 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang idci = idcr = 0; 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else 2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang idci = idcr = 1; 2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create SA;NONCE payload, and KE if need, and IDii, IDir. */ 2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = + sizeof(*gen) + iph2->sa->l 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(*gen) + iph2->nonce->l; 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pfsgroup) 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += (sizeof(*gen) + iph2->dhpub->l); 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idci) 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += sizeof(*gen) + iph2->id->l; 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idcr) 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += sizeof(*gen) + iph2->id_p->l; 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang body = vmalloc(tlen); 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (body == NULL) { 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get buffer to send.\n"); 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = body->v; 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add SA payload */ 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE); 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add NONCE payload */ 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pfsgroup) 2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang np = ISAKMP_NPTYPE_KE; 2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else if (idci || idcr) 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang np = ISAKMP_NPTYPE_ID; 2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 259c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh np = ISAKMP_NPTYPE_NONE; 2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->nonce, np); 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add KE payload if need. */ 263c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pfsgroup) 2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->dhpub, np); 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* IDci */ 268c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE; 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idci) 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->id, np); 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* IDcr */ 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idcr) 274c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE); 2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate HASH(1) */ 2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body); 2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL) 2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send isakmp payload */ 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sendbuf = quick_ir1mx(iph2, body, hash); 2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sendbuf == NULL) 2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send the packet, add to the schedule to resend */ 287c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 288c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_ph2resend(iph2) == -1) 2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* change status of isakmp status entry */ 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_MSG1SENT; 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (body != NULL) 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(body); 2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash != NULL) 3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(hash); 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive from responder 307c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] 3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_i2recv(iph2, msg0) 3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg = NULL; 3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *hbuf = NULL; /* for hash computing. */ 3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *pbuf = NULL; /* for payload parsing */ 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_parse_t *pa; 3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp *isakmp = (struct isakmp *)msg0->v; 3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_pl_hash *hash = NULL; 320c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int f_id; 3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_MSG1SENT) { 3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* decrypt packet */ 3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Packet wasn't encrypted.\n"); 3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg == NULL) 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create buffer for validating HASH(2) */ 3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ordering rule: 3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. the first one must be HASH 3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. the second one must be SA (added in isakmp-oakley-05!) 3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. two IDs must be considered as IDci, then IDcr 3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pbuf = isakmp_parse(msg); 3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf == NULL) 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa = (struct isakmp_parse_t *)pbuf->v; 3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* HASH payload is fixed postion */ 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pa->type != ISAKMP_NPTYPE_HASH) { 3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received invalid next payload type %d, " 3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "expecting %d.\n", 3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type, ISAKMP_NPTYPE_HASH); 3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = (struct isakmp_pl_hash *)pa->ptr; 3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa++; 3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this restriction was introduced in isakmp-oakley-05. 3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * we do not check this for backward compatibility. 3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * TODO: command line/config file option to enable/disable this code 3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* HASH payload is fixed postion */ 3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pa->type != ISAKMP_NPTYPE_SA) { 3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_WARNING, LOCATION, iph2->ph1->remote, 3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received invalid next payload type %d, " 3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "expecting %d.\n", 3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type, ISAKMP_NPTYPE_HASH); 3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* allocate buffer for computing HASH(2) */ 3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = iph2->nonce->l 3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + ntohl(isakmp->len) - sizeof(*isakmp); 3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hbuf = vmalloc(tlen); 3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hbuf == NULL) { 3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get hash buffer.\n"); 3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = hbuf->v + iph2->nonce->l; /* retain the space for Ni_b */ 3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse the payloads. 3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * copy non-HASH payloads into hbuf, so that we can validate HASH. 3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sa_ret = NULL; 394c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh f_id = 0; /* flag to use checking ID */ 3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = 0; /* count payload length except of HASH payload. */ 3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (; pa->type; pa++) { 3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* copy to buffer for HASH */ 3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Don't modify the payload */ 4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(p, pa->ptr, pa->len); 4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (pa->type) { 4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_SA: 4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sa_ret != NULL) { 4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Ignored, multiple SA " 4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "isn't supported.\n"); 4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) 4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NONCE: 415c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) 4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_KE: 420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) 4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_ID: 425c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh { 426c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh vchar_t *vp; 427c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 428c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* check ID value */ 429c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (f_id == 0) { 430c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* for IDci */ 431c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh f_id = 1; 432c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh vp = iph2->id; 4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 434c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* for IDcr */ 435c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh vp = iph2->id_p; 436c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 437c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 438c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef ANDROID_PATCHED 439c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) { 440c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 441c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 442c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "mismatched ID was returned.\n"); 443c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; 4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 446c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif 447c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_N: 451c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh isakmp_check_notify(pa->ptr, iph2->ph1); 4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT 4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NATOA_DRAFT: 4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NATOA_RFC: 457c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* Ignore original source/destination messages */ 4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't send information, see ident_r1recv() */ 4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ignore the packet, " 4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received unexpecting payload type %d.\n", 4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type); 4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p += pa->len; 4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* compute true length of payload. */ 4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += pa->len; 4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* payload existency check */ 4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) { 4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "few isakmp message received.\n"); 4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Fixed buffer for calculating HASH */ 4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l); 4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n", 4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hbuf->l, tlen + iph2->nonce->l); 4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* adjust buffer length for HASH */ 4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hbuf->l = iph2->nonce->l + tlen; 4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate HASH(2) */ 4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *r_hash; 4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *my_hash = NULL; 4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int result; 4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang r_hash = (char *)hash + sizeof(*hash); 4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:"); 5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); 5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (my_hash == NULL) 5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang result = memcmp(my_hash->v, r_hash, my_hash->l); 5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(my_hash); 5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (result) { 5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "HASH(2) mismatch.\n"); 5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check SA payload sent from responder */ 5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ipsecdoi_checkph2proposal(iph2) < 0) { 5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* change status of isakmp status entry */ 5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_STATUS6; 5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hbuf) 5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(hbuf); 5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf) 5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(pbuf); 5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg) 5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(msg); 5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) { 5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->sa_ret); 5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->nonce_p); 5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->dhpub_p); 5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->id); 5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->id_p); 5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * send to responder 5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HDR*, HASH(3) 5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_i2send(iph2, msg0) 5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg = NULL; 5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf = NULL; 5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *hash = NULL; 5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p = NULL; 5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_STATUS6) { 5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate HASH(3) */ 5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *tmp = NULL; 5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n"); 5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l); 5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (tmp == NULL) { 5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get hash buffer.\n"); 5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l); 5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l); 5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); 5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(tmp); 5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL) 5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create buffer for isakmp payload */ 5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = sizeof(struct isakmp) 5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(struct isakmp_gen) + hash->l; 5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = vmalloc(tlen); 5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (buf == NULL) { 5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get buffer to send.\n"); 5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create isakmp header */ 6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (p == NULL) 6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add HASH(3) payload */ 6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE); 6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C 6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* encoding */ 6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sendbuf == NULL) 6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* if there is commit bit, need resending */ 6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send the packet, add to the schedule to resend */ 622c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 623c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_ph2resend(iph2) == -1) 6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send the packet */ 6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) 6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* the sending message is added to the received-list. */ 6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, 6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sendbuf, msg0) == -1) { 6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR , LOCATION, NULL, 6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to add a response packet to the tree.\n"); 6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* compute both of KEYMATs */ 6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_compute_keymat(iph2, INITIATOR) < 0) 6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_ADDSA; 6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't anything if local test mode. */ 6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (f_local) { 6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* if there is commit bit don't set up SA now. */ 6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_COMMIT; 6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do UPDATE for initiator */ 6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendupdate(iph2) < 0) { 6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do ADD for responder */ 6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendadd(iph2) < 0) { 6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (buf != NULL) 6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg != NULL) 6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(msg); 6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash != NULL) 6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(hash); 6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive from responder 6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HDR#*, HASH(4), notify 6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_i3recv(iph2, msg0) 6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg = NULL; 6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *pbuf = NULL; /* for payload parsing */ 6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_parse_t *pa; 6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_pl_hash *hash = NULL; 6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *notify = NULL; 7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_COMMIT) { 7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* decrypt packet */ 7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Packet wasn't encrypted.\n"); 7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg == NULL) 7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate the type of next payload */ 7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pbuf = isakmp_parse(msg); 7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf == NULL) 7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (pa = (struct isakmp_parse_t *)pbuf->v; 7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type != ISAKMP_NPTYPE_NONE; 7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa++) { 7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (pa->type) { 7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_HASH: 7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = (struct isakmp_pl_hash *)pa->ptr; 7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_N: 7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (notify != NULL) { 7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_WARNING, LOCATION, NULL, 7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Ignoring multiples notifications\n"); 7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 738c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh isakmp_check_notify(pa->ptr, iph2->ph1); 7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang notify = vmalloc(pa->len); 7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (notify == NULL) { 7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get notify buffer.\n"); 7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(notify->v, pa->ptr, notify->l); 7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't send information, see ident_r1recv() */ 7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ignore the packet, " 7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received unexpecting payload type %d.\n", 7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type); 7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* payload existency check */ 7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL) { 7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "few isakmp message received.\n"); 7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate HASH(4) */ 7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *r_hash; 7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *my_hash = NULL; 7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *tmp = NULL; 7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int result; 7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang r_hash = (char *)hash + sizeof(*hash); 7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:"); 7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); 7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(tmp); 7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (my_hash == NULL) 7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang result = memcmp(my_hash->v, r_hash, my_hash->l); 7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(my_hash); 7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (result) { 7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "HASH(4) mismatch.\n"); 7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_ADDSA; 7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ 7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't anything if local test mode. */ 7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (f_local) { 7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do UPDATE for initiator */ 8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendupdate(iph2) < 0) { 8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do ADD for responder */ 8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendadd(iph2) < 0) { 8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg != NULL) 8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(msg); 8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf != NULL) 8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(pbuf); 8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (notify != NULL) 8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(notify); 8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive from initiator 831c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] 8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r1recv(iph2, msg0) 8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg = NULL; 8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *hbuf = NULL; /* for hash computing. */ 8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *pbuf = NULL; /* for payload parsing */ 8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_parse_t *pa; 8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp *isakmp = (struct isakmp *)msg0->v; 8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_pl_hash *hash = NULL; 8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int f_id_order; /* for ID payload detection */ 8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_START) { 8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* decrypting */ 8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Packet wasn't encrypted.\n"); 8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* decrypt packet */ 8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (msg == NULL) 8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create buffer for using to validate HASH(1) */ 8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ordering rule: 8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. the first one must be HASH 8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. the second one must be SA (added in isakmp-oakley-05!) 8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. two IDs must be considered as IDci, then IDcr 8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pbuf = isakmp_parse(msg); 8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf == NULL) 8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa = (struct isakmp_parse_t *)pbuf->v; 8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* HASH payload is fixed postion */ 8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pa->type != ISAKMP_NPTYPE_HASH) { 8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received invalid next payload type %d, " 8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "expecting %d.\n", 8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type, ISAKMP_NPTYPE_HASH); 8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; 8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = (struct isakmp_pl_hash *)pa->ptr; 8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa++; 8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this restriction was introduced in isakmp-oakley-05. 8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * we do not check this for backward compatibility. 8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * TODO: command line/config file option to enable/disable this code 8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* HASH payload is fixed postion */ 8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pa->type != ISAKMP_NPTYPE_SA) { 8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_WARNING, LOCATION, iph2->ph1->remote, 9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received invalid next payload type %d, " 9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "expecting %d.\n", 9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type, ISAKMP_NPTYPE_SA); 9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX; 9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* allocate buffer for computing HASH(1) */ 9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = ntohl(isakmp->len) - sizeof(*isakmp); 9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hbuf = vmalloc(tlen); 9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hbuf == NULL) { 9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get hash buffer.\n"); 9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = hbuf->v; 9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse the payloads. 9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * copy non-HASH payloads into hbuf, so that we can validate HASH. 9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sa = NULL; /* we don't support multi SAs. */ 9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->nonce_p = NULL; 9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->dhpub_p = NULL; 9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->id_p = NULL; 9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->id = NULL; 9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = 0; /* count payload length except of HASH payload. */ 9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IDi2 MUST be immediatelly followed by IDr2. We allowed the 9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * illegal case, but logged. First ID payload is to be IDi2. 9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * And next ID payload is to be IDr2. 9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang f_id_order = 0; 9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (; pa->type; pa++) { 9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* copy to buffer for HASH */ 9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Don't modify the payload */ 9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(p, pa->ptr, pa->len); 9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pa->type != ISAKMP_NPTYPE_ID) 9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang f_id_order = 0; 9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (pa->type) { 9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_SA: 9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sa != NULL) { 9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Multi SAs isn't supported.\n"); 9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 950c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) 9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NONCE: 955c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) 9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_KE: 960c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) 9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_ID: 9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p == NULL) { 9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* for IDci */ 9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang f_id_order++; 9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) 9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else if (iph2->id == NULL) { 9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* for IDcr */ 9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (f_id_order == 0) { 9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "IDr2 payload is not " 9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "immediatelly followed " 9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "by IDi2. We allowed.\n"); 9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* XXX we allowed in this case. */ 9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) 9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received too many ID payloads.\n"); 9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_ERROR, iph2->id->v, iph2->id->l); 9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_INVALID_ID_INFORMATION; 9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_N: 994c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh isakmp_check_notify(pa->ptr, iph2->ph1); 9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT 9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NATOA_DRAFT: 9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_NATOA_RFC: 1000c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* Ignore original source/destination messages */ 10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ignore the packet, " 10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received unexpecting payload type %d.\n", 10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type); 10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p += pa->len; 10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* compute true length of payload. */ 10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += pa->len; 10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* payload existency check */ 10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) { 10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "few isakmp message received.\n"); 10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; 10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p) { 10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:"); 10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l); 10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id) { 10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:"); 10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l); 10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* adjust buffer length for HASH */ 10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hbuf->l = tlen; 10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate HASH(1) */ 10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *r_hash; 10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *my_hash = NULL; 10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int result; 10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang r_hash = (caddr_t)hash + sizeof(*hash); 10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:"); 10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf); 10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (my_hash == NULL) 10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang result = memcmp(my_hash->v, r_hash, my_hash->l); 10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(my_hash); 10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (result) { 10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, 10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "HASH(1) mismatch.\n"); 10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get sainfo */ 10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = get_sainfo_r(iph2); 10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) { 10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get sainfo.\n"); 10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* check the existence of ID payload and create responder's proposal */ 10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = get_proposal_r(iph2); 10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (error) { 10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case -2: 10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate a policy template from peer's proposal */ 10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (set_proposal_from_proposal(iph2)) { 10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to generate a proposal template " 10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "from client's proposal.\n"); 1083c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return ISAKMP_INTERNAL_ERROR; 10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /*FALLTHROUGH*/ 10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case 0: 10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* select single proposal or reject it. */ 10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ipsecdoi_selectph2proposal(iph2) < 0) { 10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get proposal for responder.\n"); 10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* check KE and attribute of PFS */ 11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) { 11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "no PFS is specified, but peer sends KE.\n"); 11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) { 11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "PFS is specified, but peer doesn't sends KE.\n"); 11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * save the packet from the initiator in order to resend the 11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * responder's first packet against this packet. 11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->msg1 = vdup(msg0); 11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* change status of isakmp status entry */ 11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_STATUS2; 11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hbuf) 11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(hbuf); 11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg) 11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(msg); 11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf) 11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(pbuf); 11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) { 11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->sa); 11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->nonce_p); 11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->dhpub_p); 11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->id); 11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang VPTRINIT(iph2->id_p); 11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * call pfkey_getspi. 11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r1prep(iph2, msg) 11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg; 11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_STATUS2) { 11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_GETSPISENT; 11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send getspi message */ 11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendgetspi(iph2) < 0) 11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n"); 11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1168c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->sce = sched_new(lcconf->wait_ph2complete, 1169c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh pfkey_timeover_stub, iph2); 11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * send to initiator 1179c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] 11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r2send(iph2, msg) 11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg; 11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *body = NULL; 11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *hash = NULL; 11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_gen *gen; 11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int pfsgroup; 11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int8_t *np_p = NULL; 11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg != NULL) { 11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "msg has to be NULL in this function.\n"); 11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_GETSPIDONE) { 12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* update responders SPI */ 12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ipsecdoi_updatespi(iph2) < 0) { 12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n"); 12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate NONCE value */ 12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size); 12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->nonce == NULL) 12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate KE value if need */ 12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pfsgroup = iph2->approval->pfs_group; 12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->dhpub_p != NULL && pfsgroup != 0) { 12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* DH group settting if PFS is required. */ 12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) { 12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to set DH value.\n"); 12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate DH public value */ 12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_dh_generate(iph2->pfsgrp, 12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang &iph2->dhpub, &iph2->dhpriv) < 0) { 12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create SA;NONCE payload, and KE and ID if need */ 12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = sizeof(*gen) + iph2->sa_ret->l 12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(*gen) + iph2->nonce->l; 12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->dhpub_p != NULL && pfsgroup != 0) 12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += (sizeof(*gen) + iph2->dhpub->l); 12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p != NULL) 12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen += (sizeof(*gen) + iph2->id_p->l 12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(*gen) + iph2->id->l); 12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang body = vmalloc(tlen); 12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (body == NULL) { 12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get buffer to send.\n"); 12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = body->v; 12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make SA payload */ 12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE); 12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add NONCE payload */ 12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->nonce, 12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (iph2->dhpub_p != NULL && pfsgroup != 0) 12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ? ISAKMP_NPTYPE_KE 12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang : (iph2->id_p != NULL 12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ? ISAKMP_NPTYPE_ID 1261c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh : ISAKMP_NPTYPE_NONE)); 12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add KE payload if need. */ 12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->dhpub_p != NULL && pfsgroup != 0) { 12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->dhpub, 12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (iph2->id_p == NULL) 1268c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh ? ISAKMP_NPTYPE_NONE 12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang : ISAKMP_NPTYPE_ID); 12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add ID payloads received. */ 12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p != NULL) { 12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* IDci */ 12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID); 12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* IDcr */ 12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang np_p = &((struct isakmp_gen *)p)->np; /* XXX */ 1278c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE); 12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add a RESPONDER-LIFETIME notify payload if needed */ 12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *data = NULL; 12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct saprop *pp = iph2->approval; 12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct saproto *pr; 12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) { 12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int32_t v = htonl((u_int32_t)pp->lifetime); 12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, 12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang IPSECDOI_ATTR_SA_LD_TYPE_SEC); 12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!data) 12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, 12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (caddr_t)&v, sizeof(v)); 12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!data) 12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) { 12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int32_t v = htonl((u_int32_t)pp->lifebyte); 13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE, 13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang IPSECDOI_ATTR_SA_LD_TYPE_KB); 13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!data) 13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD, 13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (caddr_t)&v, sizeof(v)); 13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!data) 13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message 13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * in the case of SA bundle ? 13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (data) { 13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (pr = pp->head; pr; pr = pr->next) { 13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang body = isakmp_add_pl_n(body, &np_p, 13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data); 13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!body) { 13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(data); 13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; /* XXX */ 13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(data); 13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate HASH(2) */ 13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *tmp; 13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tmp = vmalloc(iph2->nonce_p->l + body->l); 13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (tmp == NULL) { 13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get hash buffer.\n"); 13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); 13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l); 13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp); 13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(tmp); 13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL) 13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send isakmp payload */ 13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sendbuf = quick_ir1mx(iph2, body, hash); 13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sendbuf == NULL) 13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send the packet, add to the schedule to resend */ 1353c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->retry_counter = iph2->ph1->rmconf->retry_counter; 1354c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (isakmp_ph2resend(iph2) == -1) 13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* the sending message is added to the received-list. */ 13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) { 13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR , LOCATION, NULL, 13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to add a response packet to the tree.\n"); 13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* change status of isakmp status entry */ 13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_MSG1SENT; 13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (body != NULL) 13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(body); 13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash != NULL) 13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(hash); 13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive from initiator 13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HDR*, HASH(3) 13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r3recv(iph2, msg0) 13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg = NULL; 13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *pbuf = NULL; /* for payload parsing */ 13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_parse_t *pa; 13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_pl_hash *hash = NULL; 13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_MSG1SENT) { 13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* decrypt packet */ 14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Packet wasn't encrypted.\n"); 14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); 14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg == NULL) 14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate the type of next payload */ 14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pbuf = isakmp_parse(msg); 14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf == NULL) 14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (pa = (struct isakmp_parse_t *)pbuf->v; 14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type != ISAKMP_NPTYPE_NONE; 14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa++) { 14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (pa->type) { 14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_HASH: 14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hash = (struct isakmp_pl_hash *)pa->ptr; 14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case ISAKMP_NPTYPE_N: 1424c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh isakmp_check_notify(pa->ptr, iph2->ph1); 14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't send information, see ident_r1recv() */ 14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ignore the packet, " 14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "received unexpecting payload type %d.\n", 14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pa->type); 14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* payload existency check */ 14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (hash == NULL) { 14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "few isakmp message received.\n"); 14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validate HASH(3) */ 14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */ 14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *r_hash; 14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *my_hash = NULL; 14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *tmp = NULL; 14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int result; 14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang r_hash = (char *)hash + sizeof(*hash); 14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:"); 14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)); 14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l); 14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (tmp == NULL) { 14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get hash buffer.\n"); 14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l); 14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l); 14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp); 14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(tmp); 14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (my_hash == NULL) 14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang result = memcmp(my_hash->v, r_hash, my_hash->l); 14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(my_hash); 14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (result) { 14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, iph2->ph1->remote, 14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "HASH(3) mismatch.\n"); 14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* if there is commit bit, don't set up SA now. */ 14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ISSET(iph2->flags, ISAKMP_FLAG_C)) { 14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_COMMIT; 14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else 14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_STATUS6; 14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pbuf != NULL) 14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(pbuf); 14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg != NULL) 14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(msg); 14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * send to initiator 15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HDR#*, HASH(4), notify 15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r3send(iph2, msg0) 15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf = NULL; 15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *myhash = NULL; 15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_pl_n *n; 15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *notify = NULL; 15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_COMMIT) { 15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* generate HASH(4) */ 15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* XXX What can I do in the case of multiple different SA */ 15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n"); 15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* XXX What should I do if there are multiple SAs ? */ 15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize; 15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang notify = vmalloc(tlen); 15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (notify == NULL) { 15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get notify buffer.\n"); 15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n = (struct isakmp_pl_n *)notify->v; 15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->h.np = ISAKMP_NPTYPE_NONE; 15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->h.len = htons(tlen); 15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->doi = htonl(IPSEC_DOI); 15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->proto_id = iph2->approval->head->proto_id; 15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->spi_size = sizeof(iph2->approval->head->spisize); 15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang n->type = htons(ISAKMP_NTYPE_CONNECTED); 15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize); 15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify); 15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (myhash == NULL) 15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create buffer for isakmp payload */ 15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = sizeof(struct isakmp) 15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(struct isakmp_gen) + myhash->l 15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + notify->l; 15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = vmalloc(tlen); 15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (buf == NULL) { 15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get buffer to send.\n"); 15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create isakmp header */ 15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (p == NULL) 15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add HASH(4) payload */ 15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N); 15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add notify payload */ 15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(p, notify->v, notify->l); 15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C 15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* encoding */ 15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sendbuf == NULL) 15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* send the packet */ 15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) 15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* the sending message is added to the received-list. */ 15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) { 15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR , LOCATION, NULL, 15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to add a response packet to the tree.\n"); 15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_COMMIT; 15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (buf != NULL) 15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (myhash != NULL) 15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(myhash); 15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (notify != NULL) 15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(notify); 16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangtunnel_mode_prop(p) 16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct saprop *p; 16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct saproto *pr; 16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (pr = p->head; pr; pr = pr->next) 16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) 16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 1; 16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set SA to kernel. 16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_r3prep(iph2, msg0) 16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg0; 16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* validity check */ 16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->status != PHASE2ST_STATUS6) { 16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "status mismatched %d.\n", iph2->status); 16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* compute both of KEYMATs */ 16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (oakley_compute_keymat(iph2, RESPONDER) < 0) 16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->status = PHASE2ST_ADDSA; 16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */ 16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* don't anything if local test mode. */ 16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (f_local) { 16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do UPDATE as responder */ 16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n"); 16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendupdate(iph2) < 0) { 16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n"); 16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n"); 16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Do ADD for responder */ 16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendadd(iph2) < 0) { 16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n"); 16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n"); 16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set policies into SPD if the policy is generated 16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * from peer's policy. 16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->spidx_gen) { 16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct policyindex *spidx; 16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr_storage addr; 16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int8_t pref; 16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr *src = iph2->src; 16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr *dst = iph2->dst; 16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make inbound policy */ 16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->src = dst; 16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->dst = src; 16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendspdupdate2(iph2) < 0) { 16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(inbound) failed.\n"); 16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(inbound) sent.\n"); 16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx = (struct policyindex *)iph2->spidx_gen; 16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_POLICY_FWD 16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make forward policy if required */ 16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (tunnel_mode_prop(iph2->approval)) { 16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->dir = IPSEC_DIR_FWD; 16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendspdupdate2(iph2) < 0) { 16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(forward) failed.\n"); 16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(forward) sent.\n"); 16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make outbound policy */ 17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->src = src; 17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->dst = dst; 17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->dir = IPSEC_DIR_OUTBOUND; 17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr = spidx->src; 17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->src = spidx->dst; 17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->dst = addr; 17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pref = spidx->prefs; 17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->prefs = spidx->prefd; 17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx->prefd = pref; 17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (pk_sendspdupdate2(iph2) < 0) { 17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(outbound) failed.\n"); 17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "pfkey spdupdate2(outbound) sent.\n"); 17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* spidx_gen is unnecessary any more */ 17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang delsp_bothdir((struct policyindex *)iph2->spidx_gen); 17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang racoon_free(iph2->spidx_gen); 17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->spidx_gen = NULL; 17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->generated_spidx=1; 17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create HASH, body (SA, NONCE) payload with isakmp header. 17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t * 17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_ir1mx(iph2, body, hash) 17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *body, *hash; 17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp *isakmp; 17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf = NULL, *new = NULL; 17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int tlen; 17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_gen *gen; 17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create buffer for isakmp payload */ 17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang tlen = sizeof(*isakmp) 17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(*gen) + hash->l 17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + body->l; 17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = vmalloc(tlen); 17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (buf == NULL) { 17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get buffer to send.\n"); 17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* re-set encryption flag, for serurity. */ 17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->flags |= ISAKMP_FLAG_E; 17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* set isakmp header */ 17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH); 17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (p == NULL) 17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add HASH payload */ 17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* XXX is next type always SA ? */ 17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA); 17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* add body payload */ 17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(p, body->v, body->l); 17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C 17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1); 17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* encoding */ 17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv); 17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (new == NULL) 17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = new; 17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error && buf != NULL) { 17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = NULL; 17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return buf; 17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get remote's sainfo. 17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: this function is for responder. 18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int 18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_sainfo_r(iph2) 18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1805c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh vchar_t *idsrc = NULL, *iddst = NULL; 1806c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int prefixlen; 18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 1808c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh int remoteid = 0; 18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id == NULL) { 1811c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh switch (iph2->src->sa_family) { 1812c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET: 1813c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh prefixlen = sizeof(struct in_addr) << 3; 1814c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 1815c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET6: 1816c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh prefixlen = sizeof(struct in6_addr) << 3; 1817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 1818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh default: 1819c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 1820c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "invalid family: %d\n", iph2->src->sa_family); 1821c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto end; 1822c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 1823c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen, 18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang IPSEC_ULPROTO_ANY); 18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang idsrc = vdup(iph2->id); 18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idsrc == NULL) { 18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to set ID for source.\n"); 18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p == NULL) { 1835c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh switch (iph2->dst->sa_family) { 1836c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET: 1837c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh prefixlen = sizeof(struct in_addr) << 3; 1838c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 1839c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh case AF_INET6: 1840c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh prefixlen = sizeof(struct in6_addr) << 3; 1841c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh break; 1842c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh default: 1843c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_ERROR, LOCATION, NULL, 1844c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "invalid family: %d\n", iph2->dst->sa_family); 1845c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh goto end; 1846c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 1847c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen, 18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang IPSEC_ULPROTO_ANY); 18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iddst = vdup(iph2->id_p); 18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iddst == NULL) { 18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to set ID for destination.\n"); 18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1858f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh { 1859c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh struct remoteconf *conf; 1860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh conf = getrmconf(iph2->dst); 1861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (conf != NULL) 1862c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh remoteid=conf->ph1id; 1863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh else{ 1864c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n"); 1865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh remoteid=0; 1866c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh } 1867c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 1868f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh } 1869f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 1870c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, remoteid); 18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sainfo == NULL) { 18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to get sainfo.\n"); 18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID 18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* xauth group inclusion check */ 18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->sainfo->group != NULL) 18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) 18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "selected sainfo: %s\n", sainfo2str(iph2->sainfo)); 18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (idsrc) 18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(idsrc); 18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iddst) 18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(iddst); 18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types 18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are IP address and same address family. 19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Then get remote's policy from SPD copied from kernel. 19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * If the type of ID payload is address or subnet type, then the index is 19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * made from the payload. If there is no ID payload, or the type of ID 19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * payload is NOT address type, then the index is made from the address 19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * pair of phase 1. 19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: This function is only for responder. 19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int 19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_proposal_r(iph2) 19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph2handle *iph2; 19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct policyindex spidx; 19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct secpolicy *sp_in, *sp_out; 19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */ 19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = ISAKMP_INTERNAL_ERROR; 19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* check the existence of ID payload */ 19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((iph2->id_p != NULL && iph2->id == NULL) 19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || (iph2->id_p == NULL && iph2->id != NULL)) { 19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Both IDs wasn't found in payload.\n"); 19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1924c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* make sure if id[src,dst] is null. */ 1925c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (iph2->src_id || iph2->dst_id) { 19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Why do ID[src,dst] exist already.\n"); 19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(&spidx, 0, sizeof(spidx)); 19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type 19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make a spidx; a key to search SPD */ 19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.dir = IPSEC_DIR_INBOUND; 19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.ul_proto = 0; 19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make destination address in spidx from either ID payload 19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * or phase 1 address into a address in spidx. 19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id != NULL 19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR 19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR 19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET 19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get a destination address of a policy */ 19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ipsecdoi_id2sockaddr(iph2->id, 19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (struct sockaddr *)&spidx.dst, 19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang &spidx.prefd, &spidx.ul_proto); 19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) 19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6 19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get scopeid from the SA address. 19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * note that the phase 1 source address is used as 19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * a destination address to search for a inbound policy entry 19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * because rcoon is responder. 19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) { 19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = setscopeid((struct sockaddr *)&spidx.dst, 19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->src); 19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) 19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR 19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) 19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang idi2type = _XIDT(iph2->id); 19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "get a destination address of SP index " 19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "from phase1 address " 19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "due to no ID payloads found " 19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "OR because ID type is not address.\n"); 19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * copy the SOURCE address of IKE into the DESTINATION address 19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * of the key to search the SPD because the direction of policy 19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is inbound. 19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src)); 19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (spidx.dst.ss_family) { 19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case AF_INET: 19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefd = sizeof(struct in_addr) << 3; 19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6 19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case AF_INET6: 19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefd = sizeof(struct in6_addr) << 3; 19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefd = 0; 19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* make source address in spidx */ 20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->id_p != NULL 20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR 20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR 20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET 20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) { 20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get a source address of inbound SA */ 20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = ipsecdoi_id2sockaddr(iph2->id_p, 20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (struct sockaddr *)&spidx.src, 20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang &spidx.prefs, &spidx.ul_proto); 20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) 20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6 20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get scopeid from the SA address. 20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * for more detail, see above of this function. 20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) { 20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = setscopeid((struct sockaddr *)&spidx.src, 20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->dst); 20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) 20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2029c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh /* make id[src,dst] if both ID types are IP address and same */ 2030c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (_XIDT(iph2->id_p) == idi2type 2031c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh && spidx.dst.ss_family == spidx.src.ss_family) { 2032c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst); 2033c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (iph2->src_id == NULL) { 20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "buffer allocation failed.\n"); 20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2038c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src); 2039c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (iph2->dst_id == NULL) { 20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "buffer allocation failed.\n"); 20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2045c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 2048c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "get a source address of SP index " 2049c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "from phase1 address " 2050c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "due to no ID payloads found " 2051c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "OR because ID type is not address.\n"); 20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* see above comment. */ 20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst)); 20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (spidx.src.ss_family) { 20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case AF_INET: 20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefs = sizeof(struct in_addr) << 3; 20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6 20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case AF_INET6: 20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefs = sizeof(struct in6_addr) << 3; 20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefs = 0; 20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef _XIDT 20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 2073c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh "get a src address from ID payload " 20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "%s prefixlen=%u ul_proto=%u\n", 20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str((struct sockaddr *)&spidx.src), 20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefs, spidx.ul_proto); 20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "get dst address from ID payload " 20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "%s prefixlen=%u ul_proto=%u\n", 20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str((struct sockaddr *)&spidx.dst), 20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefd, spidx.ul_proto); 20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert the ul_proto if it is 0 20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * because 0 in ID payload means a wild card. 20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (spidx.ul_proto == 0) 20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.ul_proto = IPSEC_ULPROTO_ANY; 20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX 20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Need to use security context in spidx to ensure the correct 20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * policy is selected. The only way to get the security context 20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is to look into the proposal sent by peer ahead of time. 20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (get_security_context(iph2->sa, &spidx)) { 20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "error occurred trying to get security context.\n"); 20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */ 21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get inbound policy */ 21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang sp_in = getsp_r(&spidx); 21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (sp_in == NULL) { 21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->ph1->rmconf->gen_policy) { 21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_INFO, LOCATION, NULL, 21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "no policy found, " 21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "try to generate the policy : %s\n", 21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx2str(&spidx)); 21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->spidx_gen = racoon_malloc(sizeof(spidx)); 21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!iph2->spidx_gen) { 21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "buffer allocation failed.\n"); 21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); 21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -2; /* special value */ 21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "no policy found: %s\n", spidx2str(&spidx)); 21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Refresh existing generated policies 21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph2->ph1->rmconf->gen_policy) { 21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_INFO, LOCATION, NULL, 21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Update the generated policy : %s\n", 21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx2str(&spidx)); 21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph2->spidx_gen = racoon_malloc(sizeof(spidx)); 21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!iph2->spidx_gen) { 21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "buffer allocation failed.\n"); 21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); 21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get outbound policy */ 21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { 21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr_storage addr; 21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int8_t pref; 21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.dir = IPSEC_DIR_OUTBOUND; 21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr = spidx.src; 21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.src = spidx.dst; 21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.dst = addr; 21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang pref = spidx.prefs; 21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefs = spidx.prefd; 21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx.prefd = pref; 21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang sp_out = getsp_r(&spidx); 21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!sp_out) { 21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_WARNING, LOCATION, NULL, 21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "no outbound policy found: %s\n", 21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx2str(&spidx)); 21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_DEBUG, LOCATION, NULL, 21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "suitable SP found:%s\n", spidx2str(&spidx)); 21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * In the responder side, the inbound policy should be using IPsec. 21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * outbound policy is not checked currently. 21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (sp_in->policy != IPSEC_POLICY_IPSEC) { 21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "policy found, but no IPsec required: %s\n", 21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang spidx2str(&spidx)); 21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* set new proposal derived from a policy into the iph2->proposal. */ 21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) { 21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "failed to create saprop.\n"); 21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ISAKMP_INTERNAL_ERROR; 21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX 21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (spidx.sec_ctx.ctx_str) { 21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang set_secctx_in_proposal(iph2, spidx); 21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */ 21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2190