12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* $NetBSD: isakmp_inf.c,v 1.14.4.17 2009/05/18 17:07:46 tteras Exp $ */ 22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 32228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */ 42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi/* 62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * All rights reserved. 82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 92228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * modification, are permitted provided that the following conditions 112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * are met: 122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * documentation and/or other materials provided with the distribution. 172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 3. Neither the name of the project nor the names of its contributors 182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * may be used to endorse or promote products derived from this software 192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * without specific prior written permission. 202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * SUCH DAMAGE. 322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "config.h" 352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <sys/types.h> 372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <sys/param.h> 382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <sys/socket.h> 392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <net/pfkeyv2.h> 412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <netinet/in.h> 422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <sys/queue.h> 432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include PATH_IPSEC_H 442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <stdlib.h> 462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <stdio.h> 472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <string.h> 482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <errno.h> 492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if TIME_WITH_SYS_TIME 502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# include <sys/time.h> 512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# include <time.h> 522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else 532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# if HAVE_SYS_TIME_H 542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# include <sys/time.h> 552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# else 562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# include <time.h> 572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project# endif 582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_HYBRID 602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <resolv.h> 612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "libpfkey.h" 642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "var.h" 662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "vmbuf.h" 672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "schedule.h" 682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "str2val.h" 692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "misc.h" 702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "plog.h" 712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "debug.h" 722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "localconf.h" 742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "remoteconf.h" 752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "sockmisc.h" 762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "handler.h" 772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "policy.h" 782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "proposal.h" 792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp_var.h" 802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "evt.h" 812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp.h" 822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_HYBRID 832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp_xauth.h" 842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp_unity.h" 852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp_cfg.h" 862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "isakmp_inf.h" 882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "oakley.h" 892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "ipsec_doi.h" 902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "crypto_openssl.h" 912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "pfkey.h" 922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "policy.h" 932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "algorithm.h" 942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "proposal.h" 952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "admin.h" 962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "strnames.h" 972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_NATT 982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "nattraversal.h" 992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* information exchange */ 1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int); 1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int); 1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_DPD 1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int isakmp_info_recv_r_u __P((struct ph1handle *, 1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_ru *, u_int32_t)); 1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int isakmp_info_recv_r_u_ack __P((struct ph1handle *, 1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_ru *, u_int32_t)); 1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void isakmp_info_send_r_u __P((void *)); 1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void purge_isakmp_spi __P((int, isakmp_index *, size_t)); 1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void info_recv_initialcontact __P((struct ph1handle *)); 1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* %%% 1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Information Exchange 1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * receive Information 1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_recv(iph1, msg0) 1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *msg0; 1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *msg = NULL; 1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *pbuf = NULL; 1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t msgid = 0; 1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = -1; 1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp *isakmp; 1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_gen *gen; 1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_parse_t *pa, *pap; 1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void *p; 1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *hash, *payload; 1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_gen *nd; 1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int8_t np; 1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int encrypted; 1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n"); 1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); 1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msgid = ((struct isakmp *)msg0->v)->msgid; 1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Use new IV to decrypt Informational message. */ 1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (encrypted) { 1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_ivm *ivm; 1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1->ivm == NULL) { 1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n"); 1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* compute IV */ 1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); 1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ivm == NULL) 1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); 1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project oakley_delivm(ivm); 1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (msg == NULL) 1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = vdup(msg0); 1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Safety check */ 1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (msg->l < sizeof(*isakmp) + sizeof(*gen)) { 1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information because the " 1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "message is way too short - %zu byte(s).\n", msg->l); 1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp = (struct isakmp *)msg->v; 1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp)); 1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project np = gen->np; 1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (encrypted) { 1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (isakmp->np != ISAKMP_NPTYPE_HASH) { 1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information because the" 1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "message has no hash payload.\n"); 1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1->status != PHASE1ST_ESTABLISHED) { 1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information because ISAKMP-SA" 1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "has not been established yet.\n"); 1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Safety check */ 1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) { 1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information because the " 1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "message is too short - %zu byte(s).\n", msg->l); 1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project p = (caddr_t) gen + sizeof(struct isakmp_gen); 2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len)); 2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* nd length check */ 2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + 2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ntohs(gen->len))) { 2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "too long payload length (broken message?)\n"); 2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ntohs(nd->len) < sizeof(*nd)) { 2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "too short payload length (broken message?)\n"); 2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(ntohs(nd->len)); 2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (payload == NULL) { 2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "cannot allocate memory\n"); 2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(payload->v, (caddr_t) nd, ntohs(nd->len)); 2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* compute HASH */ 2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hash = oakley_compute_hash1(iph1, isakmp->msgid, payload); 2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (hash == NULL) { 2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "cannot compute hash\n"); 2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) { 2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information due to hash length mismatch\n"); 2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(hash); 2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (memcmp(p, hash->v, hash->l) != 0) { 2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore information due to hash mismatch\n"); 2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(hash); 2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n"); 2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(hash); 2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* make sure the packet was encrypted after the beginning of phase 1. */ 2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (iph1->etype) { 2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_ETYPE_AGG: 2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_ETYPE_BASE: 2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_ETYPE_IDENT: 2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT) 2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) { 2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /*FALLTHRU*/ 2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "%s message must be encrypted\n", 2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project s_isakmp_nptype(np)); 2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = 0; 2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(pbuf = isakmp_parse(msg))) { 2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = -1; 2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = 0; 2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { 2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (pa->type) { 2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_NPTYPE_HASH: 2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Handled above */ 2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_NPTYPE_N: 2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_recv_n(iph1, 2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (struct isakmp_pl_n *)pa->ptr, 2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msgid, encrypted); 2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_NPTYPE_D: 2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_recv_d(iph1, 2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (struct isakmp_pl_d *)pa->ptr, 2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msgid, encrypted); 3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ISAKMP_NPTYPE_NONCE: 3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX to be 6.4.2 ike-01.txt */ 3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX IV is to be synchronized. */ 3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "ignore Acknowledged Informational\n"); 3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* don't send information, see isakmp_ident_r1() */ 3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = 0; 3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "reject the packet, " 3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "received unexpected payload type %s.\n", 3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project s_isakmp_nptype(gen->np)); 3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (error < 0) 3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project end: 3193aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi if (msg != NULL) 3203aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi vfree(msg); 3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pbuf != NULL) 3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(pbuf); 3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * handling of Notification payload 3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int 3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_recv_n(iph1, notify, msgid, encrypted) 3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_n *notify; 3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t msgid; 3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int encrypted; 3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int type; 3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *pbuf; 3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project char *nraw, *ndata; 3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project size_t l; 3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project char *spi; 3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type = ntohs(notify->type); 3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (type) { 3459f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_CONNECTED: 3469f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_RESPONDER_LIFETIME: 3479f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_REPLAY_STATUS: 3489f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi#ifdef ENABLE_HYBRID 3499f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_UNITY_HEARTBEAT: 3509f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi#endif 3519f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi /* do something */ 3529f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi break; 3539f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_INITIAL_CONTACT: 3549f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi if (encrypted) 3559f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi info_recv_initialcontact(iph1); 3569f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi return 0; 3579f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi break; 3589f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi#ifdef ENABLE_DPD 3599f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_R_U_THERE: 3609f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi if (encrypted) 3619f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi return isakmp_info_recv_r_u(iph1, 3629f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi (struct isakmp_pl_ru *)notify, msgid); 3639f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi break; 3649f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi case ISAKMP_NTYPE_R_U_THERE_ACK: 3659f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi if (encrypted) 3669f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi return isakmp_info_recv_r_u_ack(iph1, 3679f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi (struct isakmp_pl_ru *)notify, msgid); 3689f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi break; 3699f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi#endif 3709f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi default: 3719f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi { 3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX there is a potential of dos attack. */ 3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(type >= ISAKMP_NTYPE_MINERROR && 3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type <= ISAKMP_NTYPE_MAXERROR) { 3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (msgid == 0) { 3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* don't think this realy deletes ph1 ? */ 3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete phase1 handle.\n"); 3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 380fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } else { 381fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi if (getph2bymsgid(iph1, msgid) == NULL) { 382fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi plog(LLV_ERROR, LOCATION, iph1->remote, 383fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "fatal %s notify messsage, " 384fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "phase1 should be deleted.\n", 385fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi s_isakmp_notify_msg(type)); 386fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } else { 387fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi plog(LLV_ERROR, LOCATION, iph1->remote, 388fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "fatal %s notify messsage, " 389fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "phase2 should be deleted.\n", 390fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi s_isakmp_notify_msg(type)); 391fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } 392fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } 393fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } else { 3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "unhandled notify message %s, " 3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "no phase2 handle found.\n", 3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project s_isakmp_notify_msg(type)); 3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* get spi if specified and allocate */ 4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(notify->spi_size > 0) { 4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { 4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "invalid spi_size in notification payload.\n"); 4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 409fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } 410fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi spi = val2str((char *)(notify + 1), notify->spi_size); 411fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi 412fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi plog(LLV_DEBUG, LOCATION, iph1->remote, 413fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "notification message %d:%s, " 414fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi "doi=%d proto_id=%d spi=%s(size=%d).\n", 415fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi type, s_isakmp_notify_msg(type), 416fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); 417fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi 418fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi racoon_free(spi); 419fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi } 420fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi 421fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi /* Send the message data to the logs */ 422fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi if(type >= ISAKMP_NTYPE_MINERROR && 4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type <= ISAKMP_NTYPE_MAXERROR) { 4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; 4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (l > 0) { 4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nraw = (char*)notify; 4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nraw += sizeof(*notify) + notify->spi_size; 4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ndata = binsanitize(nraw, l); 4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ndata != NULL) { 4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "Message: '%s'.\n", 4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ndata); 4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project racoon_free(ndata); 4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "Cannot allocate memory\n"); 4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * handling of Deletion payload 4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int 4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_recv_d(iph1, delete, msgid, encrypted) 4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_d *delete; 4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t msgid; 4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int encrypted; 4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen, num_spi; 4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *pbuf; 4553aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi int protected = 0; 4563aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi struct ph1handle *del_ph1; 4573aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi struct ph2handle *iph2; 4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project union { 4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t spi32; 4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int16_t spi16[2]; 4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } spi; 4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ntohl(delete->doi) != IPSEC_DOI) { 4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete payload with invalid doi:%d.\n", 4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ntohl(delete->doi)); 4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_HYBRID 4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * At deconnexion time, Cisco VPN client does this 4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * with a zero DOI. Don't give up in that situation. 4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (((iph1->mode_cfg->flags & 4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0)) 4743aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi return 0; 4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else 4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project num_spi = ntohs(delete->num_spi); 4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); 4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (tlen != num_spi * delete->spi_size) { 4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "deletion payload with invalid length.\n"); 4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG, LOCATION, iph1->remote, 4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete payload for protocol %s\n", 4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project s_ipsecdoi_proto(delete->proto_id)); 4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(!iph1->rmconf->weak_phase1_check && !encrypted) { 4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_WARNING, LOCATION, iph1->remote, 4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "Ignoring unencrypted delete payload " 4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "(check the weak_phase1_check option)\n"); 4973aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi return 0; 4983aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi } 4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (delete->proto_id) { 5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case IPSECDOI_PROTO_ISAKMP: 5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (delete->spi_size != sizeof(isakmp_index)) { 5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete payload with strange spi " 5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "size %d(proto_id:%d)\n", 5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delete->spi_size, delete->proto_id); 5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project del_ph1=getph1byindex((isakmp_index *)(delete + 1)); 5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(del_ph1 != NULL){ 5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project EVT_PUSH(del_ph1->local, del_ph1->remote, 5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project EVTT_PEERPH1_NOPROP, NULL); 5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (del_ph1->scr) 5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHED_KILL(del_ph1->scr); 5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Do not delete IPsec SAs when receiving an IKE delete notification. 5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Just delete the IKE SA. 5213aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi */ 5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp_ph1expire(del_ph1); 5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case IPSECDOI_PROTO_IPSEC_AH: 5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case IPSECDOI_PROTO_IPSEC_ESP: 5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (delete->spi_size != sizeof(u_int32_t)) { 5293aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi plog(LLV_ERROR, LOCATION, iph1->remote, 5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete payload with strange spi " 5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "size %d(proto_id:%d)\n", 5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delete->spi_size, delete->proto_id); 5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project EVT_PUSH(iph1->local, iph1->remote, 5363aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi EVTT_PEER_DELETE, NULL); 5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project purge_ipsec_spi(iph1->remote, delete->proto_id, 5383aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi (u_int32_t *)(delete + 1), num_spi); 5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 5403aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 5413aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi case IPSECDOI_PROTO_IPCOMP: 5423aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi /* need to handle both 16bit/32bit SPI */ 5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memset(&spi, 0, sizeof(spi)); 5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (delete->spi_size == sizeof(spi.spi16[1])) { 5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(&spi.spi16[1], delete + 1, 5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sizeof(spi.spi16[1])); 5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else if (delete->spi_size == sizeof(spi.spi32)) 5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); 5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "delete payload with strange spi " 5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "size %d(proto_id:%d)\n", 5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delete->spi_size, delete->proto_id); 5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project purge_ipsec_spi(iph1->remote, delete->proto_id, 5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &spi.spi32, num_spi); 5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, iph1->remote, 5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "deletion message received, " 5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "invalid proto_id: %d\n", 5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delete->proto_id); 5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n"); 5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5733aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi/* 5743aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi * send Delete payload (for ISAKMP SA) in Informational exchange. 5753aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi */ 5763aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Triviint 5773aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Triviisakmp_info_send_d1(iph1) 5783aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi struct ph1handle *iph1; 5793aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi{ 5803aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi struct isakmp_pl_d *d; 5813aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi vchar_t *payload = NULL; 5823aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi int tlen; 5833aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi int error = 0; 5843aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 5853aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi if (iph1->status != PHASE2ST_ESTABLISHED) 5863aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi return 0; 5873aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* create delete payload */ 5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* send SPIs of inbound SAs. */ 5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX should send outbound SAs's ? */ 5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*d) + sizeof(isakmp_index); 5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(tlen); 5943aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi if (payload == NULL) { 5953aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi plog(LLV_ERROR, LOCATION, NULL, 5963aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi "failed to get buffer for payload.\n"); 5973aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi return errno; 5983aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi } 5993aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d = (struct isakmp_pl_d *)payload->v; 6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->h.np = ISAKMP_NPTYPE_NONE; 6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->h.len = htons(tlen); 6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->doi = htonl(IPSEC_DOI); 6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->proto_id = IPSECDOI_PROTO_ISAKMP; 6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->spi_size = sizeof(isakmp_index); 6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->num_spi = htons(1); 6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(d + 1, &iph1->index, sizeof(isakmp_index)); 6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_send_common(iph1, payload, 6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ISAKMP_NPTYPE_D, 0); 6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * send Delete payload (for IPsec SA) in Informational exchange, based on 6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * pfkey msg. It sends always single SPI. 6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_send_d2(iph2) 6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph2handle *iph2; 6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct saproto *pr; 6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_d *d; 6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *payload = NULL; 6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = 0; 6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int8_t *spi; 6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph2->status != PHASE2ST_ESTABLISHED) 6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * don't send delete information if there is no phase 1 handler. 6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * It's nonsensical to negotiate phase 1 to send the information. 6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1 = getph1byaddr(iph2->src, iph2->dst, 0); 6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1 == NULL){ 6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, 6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "No ph1 handler found, could not send DELETE_SA\n"); 6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* create delete payload */ 6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* send SPIs of inbound SAs. */ 6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * XXX should I send outbound SAs's ? 6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * I send inbound SAs's SPI only at the moment because I can't 6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * decode any more if peer send encoded packet without aware of 6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * deletion of SA. Outbound SAs don't come under the situation. 6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*d) + pr->spisize; 6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(tlen); 6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (payload == NULL) { 6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get buffer for payload.\n"); 6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return errno; 6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d = (struct isakmp_pl_d *)payload->v; 6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->h.np = ISAKMP_NPTYPE_NONE; 6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->h.len = htons(tlen); 6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->doi = htonl(IPSEC_DOI); 6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->proto_id = pr->proto_id; 6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->spi_size = pr->spisize; 6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project d->num_spi = htons(1); 6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * XXX SPI bits are left-filled, for use with IPComp. 6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * we should be switching to variable-length spi field... 6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project spi = (u_int8_t *)&pr->spi; 6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project spi += sizeof(pr->spi); 6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project spi -= pr->spisize; 6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(d + 1, spi, pr->spisize); 6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_send_common(iph1, payload, 6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ISAKMP_NPTYPE_D, 0); 6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * send Notification payload (for without ISAKMP SA) in Informational exchange 6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_send_nx(isakmp, remote, local, type, data) 6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp *isakmp; 6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sockaddr *remote, *local; 6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int type; 6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *data; 6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1 = NULL; 6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct remoteconf *rmconf; 7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *payload = NULL; 7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = -1; 7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_n *n; 7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int spisiz = 0; /* see below */ 7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* search appropreate configuration */ 7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rmconf = getrmconf(remote); 7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (rmconf == NULL) { 7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, remote, 7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "no configuration found for peer address.\n"); 7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* add new entry to isakmp status table. */ 7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1 = newph1(); 7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1 == NULL) 7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return -1; 7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); 7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); 7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->status = PHASE1ST_START; 7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->rmconf = rmconf; 7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->side = INITIATOR; 7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->version = isakmp->v; 7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->flags = 0; 7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->msgid = 0; /* XXX */ 7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_HYBRID 7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) 7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_FRAG 7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->frag = 0; 7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->frag_chain = NULL; 7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* copy remote address */ 7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) 7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*n) + spisiz; 7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen += data->l; 7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(tlen); 7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (payload == NULL) { 7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get buffer to send.\n"); 7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n = (struct isakmp_pl_n *)payload->v; 7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.np = ISAKMP_NPTYPE_NONE; 7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.len = htons(tlen); 7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->doi = htonl(IPSEC_DOI); 7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->proto_id = IPSECDOI_KEY_IKE; 7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->spi_size = spisiz; 7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->type = htons(type); 7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (spisiz) 7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ 7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project end: 7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1 != NULL) 7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delph1(iph1); 7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * send Notification payload (for ISAKMP SA) in Informational exchange 7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_send_n1(iph1, type, data) 7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int type; 7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *data; 7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *payload = NULL; 7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = 0; 7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_n *n; 7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int spisiz; 7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * note on SPI size: which description is correct? I have chosen 7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * this to be 0. 7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by 7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Initiator/Responder cookie and SPI has no meaning, SPI size = 0. 7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified 7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * by cookie and SPI has no meaning, 0 <= SPI size <= 16. 7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16. 7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (type == ISAKMP_NTYPE_INITIAL_CONTACT) 7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project spisiz = sizeof(isakmp_index); 7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project spisiz = 0; 8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*n) + spisiz; 8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen += data->l; 8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(tlen); 8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (payload == NULL) { 8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get buffer to send.\n"); 8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return errno; 8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n = (struct isakmp_pl_n *)payload->v; 8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.np = ISAKMP_NPTYPE_NONE; 8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.len = htons(tlen); 8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->doi = htonl(iph1->rmconf->doitype); 8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */ 8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->spi_size = spisiz; 8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->type = htons(type); 8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (spisiz) 8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(n + 1, &iph1->index, sizeof(isakmp_index)); 8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); 8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * send Notification payload (for IPsec SA) in Informational exchange 8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_send_n2(iph2, type, data) 8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph2handle *iph2; 8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int type; 8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *data; 8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1 = iph2->ph1; 8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *payload = NULL; 8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = 0; 8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_n *n; 8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct saproto *pr; 8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!iph2->approval) 8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return EINVAL; 8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pr = iph2->approval->head; 8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX must be get proper spi */ 8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*n) + pr->spisize; 8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen += data->l; 8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project payload = vmalloc(tlen); 8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (payload == NULL) { 8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get buffer to send.\n"); 8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return errno; 8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n = (struct isakmp_pl_n *)payload->v; 8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.np = ISAKMP_NPTYPE_NONE; 8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.len = htons(tlen); 8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->spi_size = pr->spisize; 8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->type = htons(type); 8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(u_int32_t *)(n + 1) = pr->spi; 8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ 8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); 8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(payload); 8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * send Information 8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * When ph1->skeyid_a == NULL, send message without encoding. 8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_info_send_common(iph1, payload, np, flags) 8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *payload; 8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t np; 8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int flags; 8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph2handle *iph2 = NULL; 8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *hash = NULL; 8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp *isakmp; 8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_gen *gen; 8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project char *p; 8962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 8972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int error = -1; 8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* add new entry to isakmp status table */ 9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2 = newph2(); 9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph2 == NULL) 9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->dst = dupsaddr(iph1->remote); 9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph2->dst == NULL) { 9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delph2(iph2); 9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->src = dupsaddr(iph1->local); 9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph2->src == NULL) { 9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delph2(iph2); 9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) 9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (set_port(iph2->dst, 0) == NULL || 9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project set_port(iph2->src, 0) == NULL) { 9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "invalid family: %d\n", iph1->remote->sa_family); 9199f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi delph2(iph2); 9209f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi goto end; 9219f455bea1c38f7275a65ab79be2d41a34428fb8bJean-Michel Trivi } 9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->ph1 = iph1; 9242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->side = INITIATOR; 9252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->status = PHASE2ST_START; 9262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->msgid = isakmp_newmsgid2(iph1); 927381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi 928381d69840ad3af2259f0b7ef49236f9ee9c76b76Jean-Michel Trivi /* get IV and HASH(1) if skeyid_a was generated. */ 9292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph1->skeyid_a != NULL) { 9302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->ivm = oakley_newiv2(iph1, iph2->msgid); 931fa3eba16446cc8f2f5e2dfc20d86a49dbd37299eJean-Michel Trivi if (iph2->ivm == NULL) { 9322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delph2(iph2); 9332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 9342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* generate HASH(1) */ 9373aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); 9383aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi if (hash == NULL) { 9393aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi delph2(iph2); 9403aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi goto end; 9413aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi } 9423aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 9433aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi /* initialized total buffer length */ 9443aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi tlen = hash->l; 9453aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi tlen += sizeof(*gen); 9462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 9472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* IKE-SA is not established */ 9482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hash = NULL; 9492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* initialized total buffer length */ 9512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = 0; 9522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((flags & ISAKMP_FLAG_A) == 0) 9542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 9552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 9562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 9572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project insph2(iph2); 9592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bindph12(iph1, iph2); 9602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen += sizeof(*isakmp) + payload->l; 9622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* create buffer for isakmp payload */ 9642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph2->sendbuf = vmalloc(tlen); 9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (iph2->sendbuf == NULL) { 9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get buffer to send.\n"); 9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto err; 9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* create isakmp header */ 9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp = (struct isakmp *)iph2->sendbuf->v; 9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp->v = iph1->version; 977dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi isakmp->etype = ISAKMP_ETYPE_INFO; 978dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi isakmp->flags = iph2->flags; 979dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 980dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi isakmp->len = htonl(tlen); 981dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi p = (char *)(isakmp + 1); 982dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 983dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi /* create HASH payload */ 984dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi if (hash != NULL) { 985dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi gen = (struct isakmp_gen *)p; 986dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi gen->np = np & 0xff; 987dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi gen->len = htons(sizeof(*gen) + hash->l); 988dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi p += sizeof(*gen); 989dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi memcpy(p, hash->v, hash->l); 990dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi p += hash->l; 991dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi } 992dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 993dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi /* add payload */ 994dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi memcpy(p, payload->v, payload->l); 995dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi p += payload->l; 996dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 997dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi#ifdef HAVE_PRINT_ISAKMP_C 998dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 999dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi#endif 1000dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 1001dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi /* encoding */ 1002dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 1003dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi vchar_t *tmp; 1004dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 1005dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, 1006dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi iph2->ivm->iv); 1007dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi VPTRINIT(iph2->sendbuf); 1008dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi if (tmp == NULL) 1009dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi goto err; 1010dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi iph2->sendbuf = tmp; 1011dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi } 1012dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 1013dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi /* HDR*, HASH(1), N */ 1014dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 1015dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi VPTRINIT(iph2->sendbuf); 1016dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi goto err; 1017dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi } 1018dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi 1019dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi plog(LLV_DEBUG, LOCATION, NULL, 1020dbf96806482b2c48de4ba1da9a03e2bb7516b8c2Jean-Michel Trivi "sendto Information %s.\n", s_isakmp_nptype(np)); 10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * don't resend notify message because peer can use Acknowledged 10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Informational if peer requires the reply of the notify message. 10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX If Acknowledged Informational required, don't delete ph2handle */ 10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project error = 0; 10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project VPTRINIT(iph2->sendbuf); 10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto err; /* XXX */ 10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectend: 10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (hash) 10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vfree(hash); 10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return error; 10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projecterr: 10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unbindph12(iph2); 10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project remph2(iph2); 10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project delph2(iph2); 10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project goto end; 10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* 10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * add a notify payload to buffer by reallocating buffer. 10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * If buf == NULL, the function only create a notify payload. 10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * 10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * XXX Which is SPI to be included, inbound or outbound ? 10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvchar_t * 10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectisakmp_add_pl_n(buf0, np_p, type, pr, data) 10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *buf0; 10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int8_t **np_p; 10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int type; 10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct saproto *pr; 10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *data; 10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *buf = NULL; 10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct isakmp_pl_n *n; 10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tlen; 10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int oldlen = 0; 10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (*np_p) 10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **np_p = ISAKMP_NPTYPE_N; 10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen = sizeof(*n) + pr->spisize; 10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tlen += data->l; 10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (buf0) { 10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project oldlen = buf0->l; 10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project buf = vrealloc(buf0, buf0->l + tlen); 10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project buf = vmalloc(tlen); 10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!buf) { 10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "failed to get a payload buffer.\n"); 10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return NULL; 10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n = (struct isakmp_pl_n *)(buf->v + oldlen); 10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.np = ISAKMP_NPTYPE_NONE; 10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->h.len = htons(tlen); 10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->spi_size = pr->spisize; 10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project n->type = htons(type); 10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(u_int32_t *)(n + 1) = pr->spi; /* XXX */ 10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (data) 10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* save the pointer of next payload type */ 10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *np_p = &n->h.np; 10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return buf; 10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void 10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpurge_isakmp_spi(proto, spi, n) 11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int proto; 11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp_index *spi; /*network byteorder*/ 11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project size_t n; 11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph1handle *iph1; 11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project size_t i; 11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < n; i++) { 11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1 = getph1byindex(&spi[i]); 11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!iph1) 11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_INFO, LOCATION, NULL, 11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "purged ISAKMP-SA proto_id=%s spi=%s.\n", 11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project s_ipsecdoi_proto(proto), 11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isakmp_pindex(&spi[i], 0)); 11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHED_KILL(iph1->sce); 11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->status = PHASE1ST_EXPIRED; 11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); 11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpurge_ipsec_spi(dst0, proto, spi, n) 11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sockaddr *dst0; 11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int proto; 11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int32_t *spi; /*network byteorder*/ 11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project size_t n; 11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project vchar_t *buf = NULL; 11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sadb_msg *msg, *next, *end; 11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sadb_sa *sa; 11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sadb_lifetime *lt; 11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sockaddr *src, *dst; 11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct ph2handle *iph2; 11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project u_int64_t created; 11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project size_t i; 11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project caddr_t mhp[SADB_EXT_MAX + 1]; 11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_NATT 11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sadb_x_nat_t_type *natt_type; 11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct sadb_x_nat_t_port *natt_port; 11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, 11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "purge_ipsec_spi:\n"); 11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0)); 11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0])); 11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); 11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (buf == NULL) { 11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG, LOCATION, NULL, 11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "pfkey_dump_sadb returned nothing.\n"); 11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return; 11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = (struct sadb_msg *)buf->v; 11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project end = (struct sadb_msg *)(buf->v + buf->l); 11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project while (msg < end) { 11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (msg->sadb_msg_type != SADB_DUMP) { 11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = next; 11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 11712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_ERROR, LOCATION, NULL, 11722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project "pfkey_check (%s)\n", ipsec_strerror()); 11732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = next; 11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); 11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!sa 11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project || !mhp[SADB_EXT_ADDRESS_SRC] 11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project || !mhp[SADB_EXT_ADDRESS_DST]) { 11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = next; 11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; 11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(lt != NULL) 11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project created = lt->sadb_lifetime_addtime; 11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project created = 0; 11912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sa->sadb_sa_state != SADB_SASTATE_MATURE 11932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project && sa->sadb_sa_state != SADB_SASTATE_DYING) { 11942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = next; 11952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 11962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef ENABLE_NATT 11982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE]; 11992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (natt_type && natt_type->sadb_x_nat_t_type_type) { 12002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* NAT-T is enabled for this SADB entry; copy 12012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * the ports from NAT-T extensions */ 12022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT]; 12032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (extract_port(src) == 0 && natt_port != NULL) 12042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port)); 12052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT]; 12072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (extract_port(dst) == 0 && natt_port != NULL) 12082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port)); 12092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }else{ 12102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation 12112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 12122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project set_port(src, PORT_ISAKMP); 12132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project set_port(dst, PORT_ISAKMP); 12142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 12162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); 12172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); 12182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX n^2 algorithm, inefficient */ 12202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* don't delete inbound SAs at the moment */ 12222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* XXX should we remove SAs with opposite direction as well? */ 12232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (CMPSADDR(dst0, dst)) { 12242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project msg = next; 12252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 1226 } 1227 1228#ifdef ENABLE_NATT 1229 if (natt_type == NULL || 1230 ! natt_type->sadb_x_nat_t_type_type) { 1231 /* Set back port to 0 if it was forced to default UDP port 1232 */ 1233 set_port(src, 0); 1234 set_port(dst, 0); 1235 } 1236#endif 1237 for (i = 0; i < n; i++) { 1238 plog(LLV_DEBUG, LOCATION, NULL, 1239 "check spi(packet)=%u spi(db)=%u.\n", 1240 ntohl(spi[i]), ntohl(sa->sadb_sa_spi)); 1241 if (spi[i] != sa->sadb_sa_spi) 1242 continue; 1243 1244 pfkey_send_delete(lcconf->sock_pfkey, 1245 msg->sadb_msg_satype, 1246 IPSEC_MODE_ANY, 1247 src, dst, sa->sadb_sa_spi); 1248 1249 /* 1250 * delete a relative phase 2 handler. 1251 * continue to process if no relative phase 2 handler 1252 * exists. 1253 */ 1254 iph2 = getph2bysaidx(src, dst, proto, spi[i]); 1255 if(iph2 != NULL){ 1256 delete_spd(iph2, created); 1257 unbindph12(iph2); 1258 remph2(iph2); 1259 delph2(iph2); 1260 } 1261 1262 plog(LLV_INFO, LOCATION, NULL, 1263 "purged IPsec-SA proto_id=%s spi=%u.\n", 1264 s_ipsecdoi_proto(proto), 1265 ntohl(spi[i])); 1266 } 1267 1268 msg = next; 1269 } 1270 1271 if (buf) 1272 vfree(buf); 1273} 1274 1275/* 1276 * delete all phase2 sa relatived to the destination address. 1277 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore 1278 * an INITIAL-CONTACT if we have contacted the peer. This matches the 1279 * Sun IKE behavior, and makes rekeying work much better when the peer 1280 * restarts. 1281 */ 1282static void 1283info_recv_initialcontact(iph1) 1284 struct ph1handle *iph1; 1285{ 1286 vchar_t *buf = NULL; 1287 struct sadb_msg *msg, *next, *end; 1288 struct sadb_sa *sa; 1289 struct sockaddr *src, *dst; 1290 caddr_t mhp[SADB_EXT_MAX + 1]; 1291 int proto_id, i; 1292 struct ph2handle *iph2; 1293#if 0 1294 char *loc, *rem; 1295#endif 1296 1297 if (f_local) 1298 return; 1299 1300#if 0 1301 loc = racoon_strdup(saddrwop2str(iph1->local)); 1302 rem = racoon_strdup(saddrwop2str(iph1->remote)); 1303 STRDUP_FATAL(loc); 1304 STRDUP_FATAL(rem); 1305 1306 /* 1307 * Purge all IPSEC-SAs for the peer. We can do this 1308 * the easy way (using a PF_KEY SADB_DELETE extension) 1309 * or we can do it the hard way. 1310 */ 1311 for (i = 0; i < pfkey_nsatypes; i++) { 1312 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype); 1313 1314 plog(LLV_INFO, LOCATION, NULL, 1315 "purging %s SAs for %s -> %s\n", 1316 pfkey_satypes[i].ps_name, loc, rem); 1317 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1318 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1319 iph1->local, iph1->remote) == -1) { 1320 plog(LLV_ERROR, LOCATION, NULL, 1321 "delete_all %s -> %s failed for %s (%s)\n", 1322 loc, rem, 1323 pfkey_satypes[i].ps_name, ipsec_strerror()); 1324 goto the_hard_way; 1325 } 1326 1327 deleteallph2(iph1->local, iph1->remote, proto_id); 1328 1329 plog(LLV_INFO, LOCATION, NULL, 1330 "purging %s SAs for %s -> %s\n", 1331 pfkey_satypes[i].ps_name, rem, loc); 1332 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1333 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1334 iph1->remote, iph1->local) == -1) { 1335 plog(LLV_ERROR, LOCATION, NULL, 1336 "delete_all %s -> %s failed for %s (%s)\n", 1337 rem, loc, 1338 pfkey_satypes[i].ps_name, ipsec_strerror()); 1339 goto the_hard_way; 1340 } 1341 1342 deleteallph2(iph1->remote, iph1->local, proto_id); 1343 } 1344 1345 racoon_free(loc); 1346 racoon_free(rem); 1347 return; 1348 1349 the_hard_way: 1350 racoon_free(loc); 1351 racoon_free(rem); 1352#endif 1353 1354 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); 1355 if (buf == NULL) { 1356 plog(LLV_DEBUG, LOCATION, NULL, 1357 "pfkey_dump_sadb returned nothing.\n"); 1358 return; 1359 } 1360 1361 msg = (struct sadb_msg *)buf->v; 1362 end = (struct sadb_msg *)(buf->v + buf->l); 1363 1364 while (msg < end) { 1365 if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 1366 break; 1367 next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 1368 if (msg->sadb_msg_type != SADB_DUMP) { 1369 msg = next; 1370 continue; 1371 } 1372 1373 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 1374 plog(LLV_ERROR, LOCATION, NULL, 1375 "pfkey_check (%s)\n", ipsec_strerror()); 1376 msg = next; 1377 continue; 1378 } 1379 1380 if (mhp[SADB_EXT_SA] == NULL 1381 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1382 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 1383 msg = next; 1384 continue; 1385 } 1386 sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; 1387 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1388 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1389 1390 if (sa->sadb_sa_state != SADB_SASTATE_MATURE 1391 && sa->sadb_sa_state != SADB_SASTATE_DYING) { 1392 msg = next; 1393 continue; 1394 } 1395 1396 /* 1397 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that 1398 * announces the sender of the message was rebooted. 1399 * it is interpreted to delete all SAs which source address 1400 * is the sender of the message. 1401 * racoon only deletes SA which is matched both the 1402 * source address and the destination accress. 1403 */ 1404#ifdef ENABLE_NATT 1405 /* 1406 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs 1407 * from this peer ! 1408 */ 1409 if(iph1->natt_flags & NAT_DETECTED){ 1410 if (CMPSADDR(iph1->local, src) == 0 && 1411 CMPSADDR(iph1->remote, dst) == 0) 1412 ; 1413 else if (CMPSADDR(iph1->remote, src) == 0 && 1414 CMPSADDR(iph1->local, dst) == 0) 1415 ; 1416 else { 1417 msg = next; 1418 continue; 1419 } 1420 } else 1421#endif 1422 /* If there is no NAT-T, we don't have to check addr + port... 1423 * XXX what about a configuration with a remote peers which is not 1424 * NATed, but which NATs some other peers ? 1425 * Here, the INITIAl-CONTACT would also flush all those NATed peers !! 1426 */ 1427 if (cmpsaddrwop(iph1->local, src) == 0 && 1428 cmpsaddrwop(iph1->remote, dst) == 0) 1429 ; 1430 else if (cmpsaddrwop(iph1->remote, src) == 0 && 1431 cmpsaddrwop(iph1->local, dst) == 0) 1432 ; 1433 else { 1434 msg = next; 1435 continue; 1436 } 1437 1438 /* 1439 * Make sure this is an SATYPE that we manage. 1440 * This is gross; too bad we couldn't do it the 1441 * easy way. 1442 */ 1443 for (i = 0; i < pfkey_nsatypes; i++) { 1444 if (pfkey_satypes[i].ps_satype == 1445 msg->sadb_msg_satype) 1446 break; 1447 } 1448 if (i == pfkey_nsatypes) { 1449 msg = next; 1450 continue; 1451 } 1452 1453 plog(LLV_INFO, LOCATION, NULL, 1454 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); 1455 pfkey_send_delete(lcconf->sock_pfkey, 1456 msg->sadb_msg_satype, 1457 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi); 1458 1459 /* 1460 * delete a relative phase 2 handler. 1461 * continue to process if no relative phase 2 handler 1462 * exists. 1463 */ 1464 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1465 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); 1466 if (iph2) { 1467 delete_spd(iph2, 0); 1468 unbindph12(iph2); 1469 remph2(iph2); 1470 delph2(iph2); 1471 } 1472 1473 msg = next; 1474 } 1475 1476 vfree(buf); 1477} 1478 1479void 1480isakmp_check_notify(gen, iph1) 1481 struct isakmp_gen *gen; /* points to Notify payload */ 1482 struct ph1handle *iph1; 1483{ 1484 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; 1485 1486 plog(LLV_DEBUG, LOCATION, iph1->remote, 1487 "Notify Message received\n"); 1488 1489 switch (ntohs(notify->type)) { 1490 case ISAKMP_NTYPE_CONNECTED: 1491 case ISAKMP_NTYPE_RESPONDER_LIFETIME: 1492 case ISAKMP_NTYPE_REPLAY_STATUS: 1493 case ISAKMP_NTYPE_HEARTBEAT: 1494#ifdef ENABLE_HYBRID 1495 case ISAKMP_NTYPE_UNITY_HEARTBEAT: 1496#endif 1497 plog(LLV_WARNING, LOCATION, iph1->remote, 1498 "ignore %s notification.\n", 1499 s_isakmp_notify_msg(ntohs(notify->type))); 1500 break; 1501 case ISAKMP_NTYPE_INITIAL_CONTACT: 1502 plog(LLV_WARNING, LOCATION, iph1->remote, 1503 "ignore INITIAL-CONTACT notification, " 1504 "because it is only accepted after phase1.\n"); 1505 break; 1506 default: 1507 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 1508 plog(LLV_ERROR, LOCATION, iph1->remote, 1509 "received unknown notification type %s.\n", 1510 s_isakmp_notify_msg(ntohs(notify->type))); 1511 } 1512 1513 return; 1514} 1515 1516 1517#ifdef ENABLE_DPD 1518static int 1519isakmp_info_recv_r_u (iph1, ru, msgid) 1520 struct ph1handle *iph1; 1521 struct isakmp_pl_ru *ru; 1522 u_int32_t msgid; 1523{ 1524 struct isakmp_pl_ru *ru_ack; 1525 vchar_t *payload = NULL; 1526 int tlen; 1527 int error = 0; 1528 1529 plog(LLV_DEBUG, LOCATION, iph1->remote, 1530 "DPD R-U-There received\n"); 1531 1532 /* XXX should compare cookies with iph1->index? 1533 Or is this already done by calling function? */ 1534 tlen = sizeof(*ru_ack); 1535 payload = vmalloc(tlen); 1536 if (payload == NULL) { 1537 plog(LLV_ERROR, LOCATION, NULL, 1538 "failed to get buffer to send.\n"); 1539 return errno; 1540 } 1541 1542 ru_ack = (struct isakmp_pl_ru *)payload->v; 1543 ru_ack->h.np = ISAKMP_NPTYPE_NONE; 1544 ru_ack->h.len = htons(tlen); 1545 ru_ack->doi = htonl(IPSEC_DOI); 1546 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK); 1547 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */ 1548 ru_ack->spi_size = sizeof(isakmp_index); 1549 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t)); 1550 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t)); 1551 ru_ack->data = ru->data; 1552 1553 /* XXX Should we do FLAG_A ? */ 1554 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 1555 ISAKMP_FLAG_E); 1556 vfree(payload); 1557 1558 plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n"); 1559 1560 /* Should we mark tunnel as active ? */ 1561 return error; 1562} 1563 1564static int 1565isakmp_info_recv_r_u_ack (iph1, ru, msgid) 1566 struct ph1handle *iph1; 1567 struct isakmp_pl_ru *ru; 1568 u_int32_t msgid; 1569{ 1570 1571 plog(LLV_DEBUG, LOCATION, iph1->remote, 1572 "DPD R-U-There-Ack received\n"); 1573 1574 /* XXX Maintain window of acceptable sequence numbers ? 1575 * => ru->data <= iph2->dpd_seq && 1576 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */ 1577 if (ntohl(ru->data) != iph1->dpd_seq-1) { 1578 plog(LLV_ERROR, LOCATION, iph1->remote, 1579 "Wrong DPD sequence number (%d, %d expected).\n", 1580 ntohl(ru->data), iph1->dpd_seq-1); 1581 return 0; 1582 } 1583 1584 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) || 1585 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) { 1586 plog(LLV_ERROR, LOCATION, iph1->remote, 1587 "Cookie mismatch in DPD ACK!.\n"); 1588 return 0; 1589 } 1590 1591 iph1->dpd_fails = 0; 1592 1593 /* Useless ??? */ 1594 iph1->dpd_lastack = time(NULL); 1595 1596 SCHED_KILL(iph1->dpd_r_u); 1597 1598 isakmp_sched_r_u(iph1, 0); 1599 1600 plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n"); 1601 1602 return 0; 1603} 1604 1605 1606 1607 1608/* 1609 * send DPD R-U-THERE payload in Informational exchange. 1610 */ 1611static void 1612isakmp_info_send_r_u(arg) 1613 void *arg; 1614{ 1615 struct ph1handle *iph1 = arg; 1616 1617 /* create R-U-THERE payload */ 1618 struct isakmp_pl_ru *ru; 1619 vchar_t *payload = NULL; 1620 int tlen; 1621 int error = 0; 1622 1623 plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n"); 1624 1625 iph1->dpd_r_u=NULL; 1626 1627 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { 1628 1629 plog(LLV_INFO, LOCATION, iph1->remote, 1630 "DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n", 1631 isakmp_pindex(&iph1->index, 0)); 1632 1633 EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL); 1634 purge_remote(iph1); 1635 1636 /* Do not reschedule here: phase1 is deleted, 1637 * DPD will be reactivated when a new ph1 will be negociated 1638 */ 1639 return; 1640 } 1641 1642 /* TODO: check recent activity to avoid useless sends... */ 1643 1644 tlen = sizeof(*ru); 1645 payload = vmalloc(tlen); 1646 if (payload == NULL) { 1647 plog(LLV_ERROR, LOCATION, NULL, 1648 "failed to get buffer for payload.\n"); 1649 return; 1650 } 1651 ru = (struct isakmp_pl_ru *)payload->v; 1652 ru->h.np = ISAKMP_NPTYPE_NONE; 1653 ru->h.len = htons(tlen); 1654 ru->doi = htonl(IPSEC_DOI); 1655 ru->type = htons(ISAKMP_NTYPE_R_U_THERE); 1656 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/ 1657 ru->spi_size = sizeof(isakmp_index); 1658 1659 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)); 1660 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t)); 1661 1662 if (iph1->dpd_seq == 0){ 1663 /* generate a random seq which is not too big */ 1664 srand(time(NULL)); 1665 iph1->dpd_seq = rand() & 0x0fff; 1666 } 1667 1668 ru->data = htonl(iph1->dpd_seq); 1669 1670 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 1671 vfree(payload); 1672 1673 plog(LLV_DEBUG, LOCATION, iph1->remote, 1674 "DPD R-U-There sent (%d)\n", error); 1675 1676 /* will be decreased if ACK received... */ 1677 iph1->dpd_fails++; 1678 1679 /* XXX should be increased only when ACKed ? */ 1680 iph1->dpd_seq++; 1681 1682 /* Reschedule the r_u_there with a short delay, 1683 * will be deleted/rescheduled if ACK received before */ 1684 isakmp_sched_r_u(iph1, 1); 1685 1686 plog(LLV_DEBUG, LOCATION, iph1->remote, 1687 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); 1688} 1689 1690/* Schedule a new R-U-THERE */ 1691int 1692isakmp_sched_r_u(iph1, retry) 1693 struct ph1handle *iph1; 1694 int retry; 1695{ 1696 if(iph1 == NULL || 1697 iph1->rmconf == NULL) 1698 return 1; 1699 1700 1701 if(iph1->dpd_support == 0 || 1702 iph1->rmconf->dpd_interval == 0) 1703 return 0; 1704 1705 if(retry) 1706 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry, 1707 isakmp_info_send_r_u, iph1); 1708 else 1709 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval, 1710 isakmp_info_send_r_u, iph1); 1711 1712 return 0; 1713} 1714#endif 1715