proposal.c revision c91307af2622f6625525f3c1f9c954376df950ad
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* $NetBSD: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu Exp $ */ 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* $Id: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu Exp $ */ 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * All rights reserved. 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * modification, are permitted provided that the following conditions 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * are met: 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 3. Neither the name of the project nor the names of its contributors 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * may be used to endorse or promote products derived from this software 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * without specific prior written permission. 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * SUCH DAMAGE. 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "config.h" 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <sys/param.h> 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <sys/types.h> 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <sys/socket.h> 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <sys/queue.h> 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <netinet/in.h> 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include PATH_IPSEC_H 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <stdlib.h> 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <stdio.h> 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string.h> 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <errno.h> 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "var.h" 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "misc.h" 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "vmbuf.h" 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "plog.h" 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sockmisc.h" 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "debug.h" 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "policy.h" 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "pfkey.h" 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "isakmp_var.h" 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "isakmp.h" 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ipsec_doi.h" 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "algorithm.h" 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "proposal.h" 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sainfo.h" 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "localconf.h" 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "remoteconf.h" 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "oakley.h" 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "handler.h" 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "strnames.h" 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "gcmalloc.h" 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifdef ENABLE_NATT 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "nattraversal.h" 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static uint g_nextreqid = 1; 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* %%% 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * modules for ipsec sa spec 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */ 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct saprop * 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)newsaprop() 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{ 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop *new; 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new = racoon_calloc(1, sizeof(*new)); 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new == NULL) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return new; 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct saproto * 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)newsaproto() 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct saproto *new; 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new = racoon_calloc(1, sizeof(*new)); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new == NULL) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* set saprop to last part of the prop tree */ 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inssaprop(head, new) 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop **head; 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop *new; 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop *p; 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (*head == NULL) { 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *head = new; 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (p = *head; p->next; p = p->next) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ; 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) p->next = new; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* set saproto to the end of the proto tree in saprop */ 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inssaproto(pp, new) 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop *pp; 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saproto *new; 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci{ 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct saproto *p; 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (p = pp->head; p && p->next; p = p->next) 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ; 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (p == NULL) 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pp->head = new; 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci p->next = new; 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/* set saproto to the top of the proto tree in saprop */ 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)inssaprotorev(pp, new) 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saprop *pp; 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saproto *new; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new->next = pp->head; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp->head = new; 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct satrns * 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)newsatrns() 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct satrns *new; 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new = racoon_calloc(1, sizeof(*new)); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new == NULL) 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* set saproto to last part of the proto tree in saprop */ 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inssatrns(pr, new) 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saproto *pr; 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct satrns *new; 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci{ 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct satrns *tr; 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (tr = pr->head; tr && tr->next; tr = tr->next) 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ; 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (tr == NULL) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pr->head = new; 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tr->next = new; 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * take a single match between saprop. allocate a new proposal and return it 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * for future use (like picking single proposal from a bundle). 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * pp1: peer's proposal. 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * pp2: my proposal. 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * NOTE: In the case of initiator, must be ensured that there is no 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * modification of the proposal by calling cmp_aproppair_i() before 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * this function. 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * XXX cannot understand the comment! 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct saprop * 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)cmpsaprop_alloc(ph1, pp1, pp2, side) 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct ph1handle *ph1; 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const struct saprop *pp1, *pp2; 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int side; 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct saprop *newpp = NULL; 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct saproto *pr1, *pr2, *newpr = NULL; 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct satrns *tr1, *tr2, *newtr; 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int ordermatters = 0; 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int npr1, npr2; 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int spisizematch; 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp = newsaprop(); 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (newpp == NULL) { 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "failed to allocate saprop.\n"); 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->prop_no = pp1->prop_no; 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* see proposal.h about lifetime/key length and PFS selection. */ 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* check time/bytes lifetime and PFS */ 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (ph1->rmconf->pcheck_level) { 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case PROP_CHECK_OBEY: 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch newpp->lifetime = pp1->lifetime; 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch newpp->lifebyte = pp1->lifebyte; 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch newpp->pfs_group = pp1->pfs_group; 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case PROP_CHECK_STRICT: 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifetime > pp2->lifetime) { 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "long lifetime proposed: " 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "my:%d peer:%d\n", 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (int)pp2->lifetime, (int)pp1->lifetime); 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifebyte > pp2->lifebyte) { 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "long lifebyte proposed: " 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "my:%d peer:%d\n", 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp2->lifebyte, pp1->lifebyte); 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->lifetime = pp1->lifetime; 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) newpp->lifebyte = pp1->lifebyte; 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prop_pfs_check: 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp2->pfs_group != 0 && pp1->pfs_group != pp2->pfs_group) { 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "pfs group mismatched: " 24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "my:%d peer:%d\n", 24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pp2->pfs_group, pp1->pfs_group); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) goto err; 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch newpp->pfs_group = pp1->pfs_group; 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case PROP_CHECK_CLAIM: 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* lifetime */ 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifetime <= pp2->lifetime) { 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->lifetime = pp1->lifetime; 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->lifetime = pp2->lifetime; 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_NOTIFY, LOCATION, NULL, 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "use own lifetime: " 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "my:%d peer:%d\n", 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (int)pp2->lifetime, (int)pp1->lifetime); 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* lifebyte */ 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifebyte > pp2->lifebyte) { 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch newpp->lifebyte = pp2->lifebyte; 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC; 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch plog(LLV_NOTIFY, LOCATION, NULL, 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "use own lifebyte: " 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "my:%d peer:%d\n", 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pp2->lifebyte, pp1->lifebyte); 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->lifebyte = pp1->lifebyte; 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto prop_pfs_check; 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case PROP_CHECK_EXACT: 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifetime != pp2->lifetime) { 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "lifetime mismatched: " 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "my:%d peer:%d\n", 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (int)pp2->lifetime, (int)pp1->lifetime); 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->lifebyte != pp2->lifebyte) { 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "lifebyte mismatched: " 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "my:%d peer:%d\n", 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp2->lifebyte, pp1->lifebyte); 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch goto err; 2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (pp1->pfs_group != pp2->pfs_group) { 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch plog(LLV_ERROR, LOCATION, NULL, 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "pfs group mismatched: " 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "my:%d peer:%d\n", 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pp2->pfs_group, pp1->pfs_group); 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch goto err; 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch newpp->lifetime = pp1->lifetime; 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->lifebyte = pp1->lifebyte; 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->pfs_group = pp1->pfs_group; 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default: 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "invalid pcheck_level why?.\n"); 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifdef HAVE_SECCTX 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* check the security_context properties. 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * It is possible for one side to have a security context 317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * and the other side doesn't. If so, this is an error. 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (*pp1->sctx.ctx_str && !(*pp2->sctx.ctx_str)) { 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "My proposal missing security context\n"); 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!(*pp1->sctx.ctx_str) && *pp2->sctx.ctx_str) { 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Peer is missing security context\n"); 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (*pp1->sctx.ctx_str && *pp2->sctx.ctx_str) { 3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (pp1->sctx.ctx_doi == pp2->sctx.ctx_doi) 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch newpp->sctx.ctx_doi = pp1->sctx.ctx_doi; 3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else { 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch plog(LLV_ERROR, LOCATION, NULL, 3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "sec doi mismatched: my:%d peer:%d\n", 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp2->sctx.ctx_doi, pp1->sctx.ctx_doi); 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pp1->sctx.ctx_alg == pp2->sctx.ctx_alg) 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->sctx.ctx_alg = pp1->sctx.ctx_alg; 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else { 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "sec alg mismatched: my:%d peer:%d\n", 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp2->sctx.ctx_alg, pp1->sctx.ctx_alg); 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((pp1->sctx.ctx_strlen != pp2->sctx.ctx_strlen) || 351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch memcmp(pp1->sctx.ctx_str, pp2->sctx.ctx_str, 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pp1->sctx.ctx_strlen) != 0) { 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "sec ctx string mismatched: my:%s peer:%s\n", 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pp2->sctx.ctx_str, pp1->sctx.ctx_str); 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) goto err; 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpp->sctx.ctx_strlen = pp1->sctx.ctx_strlen; 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch memcpy(newpp->sctx.ctx_str, pp1->sctx.ctx_str, 360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pp1->sctx.ctx_strlen); 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif /* HAVE_SECCTX */ 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) npr1 = npr2 = 0; 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (pr1 = pp1->head; pr1; pr1 = pr1->next) 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) npr1++; 368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (pr2 = pp2->head; pr2; pr2 = pr2->next) 3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch npr2++; 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (npr1 != npr2) 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) goto err; 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /* check protocol order */ 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pr1 = pp1->head; 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pr2 = pp2->head; 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) while (1) { 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ordermatters) { 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * XXX does not work if we have multiple proposals 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * with the same proto_id 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (side) { 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case RESPONDER: 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!pr2) 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (pr1 = pp1->head; pr1; pr1 = pr1->next) { 3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (pr1->proto_id == pr2->proto_id) 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case INITIATOR: 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!pr1) 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (pr2 = pp2->head; pr2; pr2 = pr2->next) { 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (pr2->proto_id == pr1->proto_id) 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!pr1 || !pr2) 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (pr1->proto_id != pr2->proto_id) { 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch plog(LLV_ERROR, LOCATION, NULL, 4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "proto_id mismatched: " 4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "my:%s peer:%s\n", 4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s_ipsecdoi_proto(pr2->proto_id), 4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s_ipsecdoi_proto(pr1->proto_id)); 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci spisizematch = 0; 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pr1->spisize == pr2->spisize) 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) spisizematch = 1; 4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else if (pr1->proto_id == IPSECDOI_PROTO_IPCOMP) { 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * draft-shacham-ippcp-rfc2393bis-05.txt: 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * need to accept 16bit and 32bit SPI (CPI) for IPComp. 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pr1->spisize == sizeof(u_int16_t) && 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pr2->spisize == sizeof(u_int32_t)) { 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) spisizematch = 1; 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (pr2->spisize == sizeof(u_int16_t) && 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pr1->spisize == sizeof(u_int32_t)) { 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) spisizematch = 1; 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (spisizematch) { 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "IPComp SPI size promoted " 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "from 16bit to 32bit\n"); 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!spisizematch) { 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "spisize mismatched: " 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "my:%d peer:%d\n", 4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (int)pr2->spisize, (int)pr1->spisize); 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) goto err; 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifdef ENABLE_NATT 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ((ph1->natt_flags & NAT_DETECTED) && 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) natt_udp_encap (pr2->encmode)) 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n", 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s_ipsecdoi_encmode(pr2->encmode), 448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff)); 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pr2->encmode -= ph1->natt_options->mode_udp_diff; 450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pr2->udp_encap = 1; 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((ph1->natt_flags & NAT_DETECTED) && 454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch natt_udp_encap (pr1->encmode)) 4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch { 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n", 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) s_ipsecdoi_encmode(pr1->encmode), 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pr1->encmode, 4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff), 4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pr1->encmode - ph1->natt_options->mode_udp_diff); 461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pr1->encmode -= ph1->natt_options->mode_udp_diff; 4627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pr1->udp_encap = 1; 4637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 4657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pr1->encmode != pr2->encmode) { 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) plog(LLV_ERROR, LOCATION, NULL, 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "encmode mismatched: " 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "my:%s peer:%s\n", 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) s_ipsecdoi_encmode(pr2->encmode), 4717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s_ipsecdoi_encmode(pr1->encmode)); 472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (tr1 = pr1->head; tr1; tr1 = tr1->next) { 4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (tr2 = pr2->head; tr2; tr2 = tr2->next) { 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (cmpsatrns(pr1->proto_id, tr1, tr2, ph1->rmconf->pcheck_level) == 0) 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto found; 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) found: 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr = newsaproto(); 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (newpr == NULL) { 4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch plog(LLV_ERROR, LOCATION, NULL, 4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "failed to allocate saproto.\n"); 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto err; 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->proto_id = pr1->proto_id; 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->spisize = pr1->spisize; 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->encmode = pr1->encmode; 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->spi = pr2->spi; /* copy my SPI */ 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->spi_p = pr1->spi; /* copy peer's SPI */ 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) newpr->reqid_in = pr2->reqid_in; 497 newpr->reqid_out = pr2->reqid_out; 498#ifdef ENABLE_NATT 499 newpr->udp_encap = pr1->udp_encap | pr2->udp_encap; 500#endif 501 502 newtr = newsatrns(); 503 if (newtr == NULL) { 504 plog(LLV_ERROR, LOCATION, NULL, 505 "failed to allocate satrns.\n"); 506 racoon_free(newpr); 507 goto err; 508 } 509 newtr->trns_no = tr1->trns_no; 510 newtr->trns_id = tr1->trns_id; 511 newtr->encklen = tr1->encklen; 512 newtr->authtype = tr1->authtype; 513 514 inssatrns(newpr, newtr); 515 inssaproto(newpp, newpr); 516 517 pr1 = pr1->next; 518 pr2 = pr2->next; 519 } 520 521 /* XXX should check if we have visited all items or not */ 522 if (!ordermatters) { 523 switch (side) { 524 case RESPONDER: 525 if (!pr2) 526 pr1 = NULL; 527 break; 528 case INITIATOR: 529 if (!pr1) 530 pr2 = NULL; 531 break; 532 } 533 } 534 535 /* should be matched all protocols in a proposal */ 536 if (pr1 != NULL || pr2 != NULL) 537 goto err; 538 539 return newpp; 540 541err: 542 flushsaprop(newpp); 543 return NULL; 544} 545 546/* take a single match between saprop. returns 0 if pp1 equals to pp2. */ 547int 548cmpsaprop(pp1, pp2) 549 const struct saprop *pp1, *pp2; 550{ 551 if (pp1->pfs_group != pp2->pfs_group) { 552 plog(LLV_WARNING, LOCATION, NULL, 553 "pfs_group mismatch. mine:%d peer:%d\n", 554 pp1->pfs_group, pp2->pfs_group); 555 /* FALLTHRU */ 556 } 557 558 if (pp1->lifetime > pp2->lifetime) { 559 plog(LLV_WARNING, LOCATION, NULL, 560 "less lifetime proposed. mine:%d peer:%d\n", 561 (int)pp1->lifetime, (int)pp2->lifetime); 562 /* FALLTHRU */ 563 } 564 if (pp1->lifebyte > pp2->lifebyte) { 565 plog(LLV_WARNING, LOCATION, NULL, 566 "less lifebyte proposed. mine:%d peer:%d\n", 567 pp1->lifebyte, pp2->lifebyte); 568 /* FALLTHRU */ 569 } 570 571 return 0; 572} 573 574/* 575 * take a single match between satrns. returns 0 if tr1 equals to tr2. 576 * tr1: peer's satrns 577 * tr2: my satrns 578 */ 579int 580cmpsatrns(proto_id, tr1, tr2, check_level) 581 int proto_id; 582 const struct satrns *tr1, *tr2; 583 int check_level; 584{ 585 if (tr1->trns_id != tr2->trns_id) { 586 plog(LLV_WARNING, LOCATION, NULL, 587 "trns_id mismatched: " 588 "my:%s peer:%s\n", 589 s_ipsecdoi_trns(proto_id, tr2->trns_id), 590 s_ipsecdoi_trns(proto_id, tr1->trns_id)); 591 return 1; 592 } 593 594 if (tr1->authtype != tr2->authtype) { 595 plog(LLV_WARNING, LOCATION, NULL, 596 "authtype mismatched: " 597 "my:%s peer:%s\n", 598 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr2->authtype), 599 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr1->authtype)); 600 return 1; 601 } 602 603 /* Check key length regarding checkmode 604 * XXX Shall we send some kind of notify message when key length rejected ? 605 */ 606 switch(check_level){ 607 case PROP_CHECK_OBEY: 608 return 0; 609 break; 610 611 case PROP_CHECK_STRICT: 612 /* FALLTHROUGH */ 613 case PROP_CHECK_CLAIM: 614 if (tr1->encklen < tr2->encklen) { 615 plog(LLV_WARNING, LOCATION, NULL, 616 "low key length proposed, " 617 "mine:%d peer:%d.\n", 618 tr2->encklen, tr1->encklen); 619 return 1; 620 } 621 break; 622 case PROP_CHECK_EXACT: 623 if (tr1->encklen != tr2->encklen) { 624 plog(LLV_WARNING, LOCATION, NULL, 625 "key length mismatched, " 626 "mine:%d peer:%d.\n", 627 tr2->encklen, tr1->encklen); 628 return 1; 629 } 630 break; 631 } 632 633 return 0; 634} 635 636int 637set_satrnsbysainfo(pr, sainfo) 638 struct saproto *pr; 639 struct sainfo *sainfo; 640{ 641 struct sainfoalg *a, *b; 642 struct satrns *newtr; 643 int t; 644 645 switch (pr->proto_id) { 646 case IPSECDOI_PROTO_IPSEC_AH: 647 if (sainfo->algs[algclass_ipsec_auth] == NULL) { 648 plog(LLV_ERROR, LOCATION, NULL, 649 "no auth algorithm found\n"); 650 goto err; 651 } 652 t = 1; 653 for (a = sainfo->algs[algclass_ipsec_auth]; a; a = a->next) { 654 655 if (a->alg == IPSECDOI_ATTR_AUTH_NONE) 656 continue; 657 658 /* allocate satrns */ 659 newtr = newsatrns(); 660 if (newtr == NULL) { 661 plog(LLV_ERROR, LOCATION, NULL, 662 "failed to allocate satrns.\n"); 663 goto err; 664 } 665 666 newtr->trns_no = t++; 667 newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg); 668 newtr->authtype = a->alg; 669 670 inssatrns(pr, newtr); 671 } 672 break; 673 case IPSECDOI_PROTO_IPSEC_ESP: 674 if (sainfo->algs[algclass_ipsec_enc] == NULL) { 675 plog(LLV_ERROR, LOCATION, NULL, 676 "no encryption algorithm found\n"); 677 goto err; 678 } 679 t = 1; 680 for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) { 681 for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) { 682 /* allocate satrns */ 683 newtr = newsatrns(); 684 if (newtr == NULL) { 685 plog(LLV_ERROR, LOCATION, NULL, 686 "failed to allocate satrns.\n"); 687 goto err; 688 } 689 690 newtr->trns_no = t++; 691 newtr->trns_id = a->alg; 692 newtr->encklen = a->encklen; 693 newtr->authtype = b->alg; 694 695 inssatrns(pr, newtr); 696 } 697 } 698 break; 699 case IPSECDOI_PROTO_IPCOMP: 700 if (sainfo->algs[algclass_ipsec_comp] == NULL) { 701 plog(LLV_ERROR, LOCATION, NULL, 702 "no ipcomp algorithm found\n"); 703 goto err; 704 } 705 t = 1; 706 for (a = sainfo->algs[algclass_ipsec_comp]; a; a = a->next) { 707 708 /* allocate satrns */ 709 newtr = newsatrns(); 710 if (newtr == NULL) { 711 plog(LLV_ERROR, LOCATION, NULL, 712 "failed to allocate satrns.\n"); 713 goto err; 714 } 715 716 newtr->trns_no = t++; 717 newtr->trns_id = a->alg; 718 newtr->authtype = IPSECDOI_ATTR_AUTH_NONE; /*no auth*/ 719 720 inssatrns(pr, newtr); 721 } 722 break; 723 default: 724 plog(LLV_ERROR, LOCATION, NULL, 725 "unknown proto_id (%d).\n", pr->proto_id); 726 goto err; 727 } 728 729 /* no proposal found */ 730 if (pr->head == NULL) { 731 plog(LLV_ERROR, LOCATION, NULL, "no algorithms found.\n"); 732 return -1; 733 } 734 735 return 0; 736 737err: 738 flushsatrns(pr->head); 739 return -1; 740} 741 742struct saprop * 743aproppair2saprop(p0) 744 struct prop_pair *p0; 745{ 746 struct prop_pair *p, *t; 747 struct saprop *newpp; 748 struct saproto *newpr; 749 struct satrns *newtr; 750 u_int8_t *spi; 751 752 if (p0 == NULL) 753 return NULL; 754 755 /* allocate ipsec a sa proposal */ 756 newpp = newsaprop(); 757 if (newpp == NULL) { 758 plog(LLV_ERROR, LOCATION, NULL, 759 "failed to allocate saprop.\n"); 760 return NULL; 761 } 762 newpp->prop_no = p0->prop->p_no; 763 /* lifetime & lifebyte must be updated later */ 764 765 for (p = p0; p; p = p->next) { 766 767 /* allocate ipsec sa protocol */ 768 newpr = newsaproto(); 769 if (newpr == NULL) { 770 plog(LLV_ERROR, LOCATION, NULL, 771 "failed to allocate saproto.\n"); 772 goto err; 773 } 774 775 /* check spi size */ 776 /* XXX should be handled isakmp cookie */ 777 if (sizeof(newpr->spi) < p->prop->spi_size) { 778 plog(LLV_ERROR, LOCATION, NULL, 779 "invalid spi size %d.\n", p->prop->spi_size); 780 racoon_free(newpr); 781 goto err; 782 } 783 784 /* 785 * XXX SPI bits are left-filled, for use with IPComp. 786 * we should be switching to variable-length spi field... 787 */ 788 newpr->proto_id = p->prop->proto_id; 789 newpr->spisize = p->prop->spi_size; 790 memset(&newpr->spi, 0, sizeof(newpr->spi)); 791 spi = (u_int8_t *)&newpr->spi; 792 spi += sizeof(newpr->spi); 793 spi -= p->prop->spi_size; 794 memcpy(spi, p->prop + 1, p->prop->spi_size); 795 newpr->reqid_in = 0; 796 newpr->reqid_out = 0; 797 798 for (t = p; t; t = t->tnext) { 799 800 plog(LLV_DEBUG, LOCATION, NULL, 801 "prop#=%d prot-id=%s spi-size=%d " 802 "#trns=%d trns#=%d trns-id=%s\n", 803 t->prop->p_no, 804 s_ipsecdoi_proto(t->prop->proto_id), 805 t->prop->spi_size, t->prop->num_t, 806 t->trns->t_no, 807 s_ipsecdoi_trns(t->prop->proto_id, 808 t->trns->t_id)); 809 810 /* allocate ipsec sa transform */ 811 newtr = newsatrns(); 812 if (newtr == NULL) { 813 plog(LLV_ERROR, LOCATION, NULL, 814 "failed to allocate satrns.\n"); 815 racoon_free(newpr); 816 goto err; 817 } 818 819 if (ipsecdoi_t2satrns(t->trns, 820 newpp, newpr, newtr) < 0) { 821 flushsaprop(newpp); 822 racoon_free(newtr); 823 racoon_free(newpr); 824 return NULL; 825 } 826 827 inssatrns(newpr, newtr); 828 } 829 830 /* 831 * If the peer does not specify encryption mode, use 832 * transport mode by default. This is to conform to 833 * draft-shacham-ippcp-rfc2393bis-08.txt (explicitly specifies 834 * that unspecified == transport), as well as RFC2407 835 * (unspecified == implementation dependent default). 836 */ 837 if (newpr->encmode == 0) 838 newpr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS; 839 840 inssaproto(newpp, newpr); 841 } 842 843 return newpp; 844 845err: 846 flushsaprop(newpp); 847 return NULL; 848} 849 850void 851flushsaprop(head) 852 struct saprop *head; 853{ 854 struct saprop *p, *save; 855 856 for (p = head; p != NULL; p = save) { 857 save = p->next; 858 flushsaproto(p->head); 859 racoon_free(p); 860 } 861 862 return; 863} 864 865void 866flushsaproto(head) 867 struct saproto *head; 868{ 869 struct saproto *p, *save; 870 871 for (p = head; p != NULL; p = save) { 872 save = p->next; 873 flushsatrns(p->head); 874 vfree(p->keymat); 875 vfree(p->keymat_p); 876 racoon_free(p); 877 } 878 879 return; 880} 881 882void 883flushsatrns(head) 884 struct satrns *head; 885{ 886 struct satrns *p, *save; 887 888 for (p = head; p != NULL; p = save) { 889 save = p->next; 890 racoon_free(p); 891 } 892 893 return; 894} 895 896/* 897 * print multiple proposals 898 */ 899void 900printsaprop(pri, pp) 901 const int pri; 902 const struct saprop *pp; 903{ 904 const struct saprop *p; 905 906 if (pp == NULL) { 907 plog(pri, LOCATION, NULL, "(null)"); 908 return; 909 } 910 911 for (p = pp; p; p = p->next) { 912 printsaprop0(pri, p); 913 } 914 915 return; 916} 917 918/* 919 * print one proposal. 920 */ 921void 922printsaprop0(pri, pp) 923 int pri; 924 const struct saprop *pp; 925{ 926 const struct saproto *p; 927 928 if (pp == NULL) 929 return; 930 931 for (p = pp->head; p; p = p->next) { 932 printsaproto(pri, p); 933 } 934 935 return; 936} 937 938void 939printsaproto(pri, pr) 940 const int pri; 941 const struct saproto *pr; 942{ 943 struct satrns *tr; 944 945 if (pr == NULL) 946 return; 947 948 plog(pri, LOCATION, NULL, 949 " (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx " 950 "encmode=%s reqid=%d:%d)\n", 951 s_ipsecdoi_proto(pr->proto_id), 952 (int)pr->spisize, 953 (unsigned long)ntohl(pr->spi), 954 (unsigned long)ntohl(pr->spi_p), 955 s_ipsecdoi_attr_v(IPSECDOI_ATTR_ENC_MODE, pr->encmode), 956 (int)pr->reqid_in, (int)pr->reqid_out); 957 958 for (tr = pr->head; tr; tr = tr->next) { 959 printsatrns(pri, pr->proto_id, tr); 960 } 961 962 return; 963} 964 965void 966printsatrns(pri, proto_id, tr) 967 const int pri; 968 const int proto_id; 969 const struct satrns *tr; 970{ 971 if (tr == NULL) 972 return; 973 974 switch (proto_id) { 975 case IPSECDOI_PROTO_IPSEC_AH: 976 plog(pri, LOCATION, NULL, 977 " (trns_id=%s authtype=%s)\n", 978 s_ipsecdoi_trns(proto_id, tr->trns_id), 979 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); 980 break; 981 case IPSECDOI_PROTO_IPSEC_ESP: 982 plog(pri, LOCATION, NULL, 983 " (trns_id=%s encklen=%d authtype=%s)\n", 984 s_ipsecdoi_trns(proto_id, tr->trns_id), 985 tr->encklen, 986 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype)); 987 break; 988 case IPSECDOI_PROTO_IPCOMP: 989 plog(pri, LOCATION, NULL, 990 " (trns_id=%s)\n", 991 s_ipsecdoi_trns(proto_id, tr->trns_id)); 992 break; 993 default: 994 plog(pri, LOCATION, NULL, 995 "(unknown proto_id %d)\n", proto_id); 996 } 997 998 return; 999} 1000 1001void 1002print_proppair0(pri, p, level) 1003 int pri; 1004 struct prop_pair *p; 1005 int level; 1006{ 1007 char spc[21]; 1008 1009 memset(spc, ' ', sizeof(spc)); 1010 spc[sizeof(spc) - 1] = '\0'; 1011 if (level < 20) { 1012 spc[level] = '\0'; 1013 } 1014 1015 plog(pri, LOCATION, NULL, 1016 "%s%p: next=%p tnext=%p\n", spc, p, p->next, p->tnext); 1017 if (p->next) 1018 print_proppair0(pri, p->next, level + 1); 1019 if (p->tnext) 1020 print_proppair0(pri, p->tnext, level + 1); 1021} 1022 1023void 1024print_proppair(pri, p) 1025 int pri; 1026 struct prop_pair *p; 1027{ 1028 print_proppair0(pri, p, 1); 1029} 1030 1031int 1032set_proposal_from_policy(iph2, sp_main, sp_sub) 1033 struct ph2handle *iph2; 1034 struct secpolicy *sp_main, *sp_sub; 1035{ 1036 struct saprop *newpp; 1037 struct ipsecrequest *req; 1038 int encmodesv = IPSECDOI_ATTR_ENC_MODE_TRNS; /* use only when complex_bundle */ 1039 1040 newpp = newsaprop(); 1041 if (newpp == NULL) { 1042 plog(LLV_ERROR, LOCATION, NULL, 1043 "failed to allocate saprop.\n"); 1044 goto err; 1045 } 1046 newpp->prop_no = 1; 1047 newpp->lifetime = iph2->sainfo->lifetime; 1048 newpp->lifebyte = iph2->sainfo->lifebyte; 1049 newpp->pfs_group = iph2->sainfo->pfs_group; 1050 1051 if (lcconf->complex_bundle) 1052 goto skip1; 1053 1054 /* 1055 * decide the encryption mode of this SA bundle. 1056 * the mode becomes tunnel mode when there is even one policy 1057 * of tunnel mode in the SPD. otherwise the mode becomes 1058 * transport mode. 1059 */ 1060 for (req = sp_main->req; req; req = req->next) { 1061 if (req->saidx.mode == IPSEC_MODE_TUNNEL) { 1062 encmodesv = pfkey2ipsecdoi_mode(req->saidx.mode); 1063#ifdef ENABLE_NATT 1064 if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED)) 1065 encmodesv += iph2->ph1->natt_options->mode_udp_diff; 1066#endif 1067 break; 1068 } 1069 } 1070 1071 skip1: 1072 for (req = sp_main->req; req; req = req->next) { 1073 struct saproto *newpr; 1074 caddr_t paddr = NULL; 1075 1076 /* 1077 * check if SA bundle ? 1078 * nested SAs negotiation is NOT supported. 1079 * me +--- SA1 ---+ peer1 1080 * me +--- SA2 --------------+ peer2 1081 */ 1082#ifdef __linux__ 1083 if (req->saidx.src.ss_family && req->saidx.dst.ss_family) { 1084#else 1085 if (req->saidx.src.ss_len && req->saidx.dst.ss_len) { 1086#endif 1087 /* check the end of ip addresses of SA */ 1088 if (iph2->side == INITIATOR) 1089 paddr = (caddr_t)&req->saidx.dst; 1090 else 1091 paddr = (caddr_t)&req->saidx.src; 1092 } 1093 1094 /* allocate ipsec sa protocol */ 1095 newpr = newsaproto(); 1096 if (newpr == NULL) { 1097 plog(LLV_ERROR, LOCATION, NULL, 1098 "failed to allocate saproto.\n"); 1099 goto err; 1100 } 1101 1102 newpr->proto_id = ipproto2doi(req->saidx.proto); 1103 if (newpr->proto_id == IPSECDOI_PROTO_IPCOMP) 1104 newpr->spisize = 2; 1105 else 1106 newpr->spisize = 4; 1107 if (lcconf->complex_bundle) { 1108 newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode); 1109#ifdef ENABLE_NATT 1110 if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED)) 1111 newpr->encmode += 1112 iph2->ph1->natt_options->mode_udp_diff; 1113#endif 1114 } 1115 else 1116 newpr->encmode = encmodesv; 1117 1118 if (iph2->side == INITIATOR) 1119 newpr->reqid_out = req->saidx.reqid; 1120 else 1121 newpr->reqid_in = req->saidx.reqid; 1122 1123 if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) { 1124 plog(LLV_ERROR, LOCATION, NULL, 1125 "failed to get algorithms.\n"); 1126 racoon_free(newpr); 1127 goto err; 1128 } 1129 1130 /* set new saproto */ 1131 inssaprotorev(newpp, newpr); 1132 } 1133 1134 /* get reqid_in from inbound policy */ 1135 if (sp_sub) { 1136 struct saproto *pr; 1137 1138 req = sp_sub->req; 1139 pr = newpp->head; 1140 while (req && pr) { 1141 if (iph2->side == INITIATOR) 1142 pr->reqid_in = req->saidx.reqid; 1143 else 1144 pr->reqid_out = req->saidx.reqid; 1145 pr = pr->next; 1146 req = req->next; 1147 } 1148 if (pr || req) { 1149 plog(LLV_NOTIFY, LOCATION, NULL, 1150 "There is a difference " 1151 "between the in/out bound policies in SPD.\n"); 1152 } 1153 } 1154 1155 iph2->proposal = newpp; 1156 1157 printsaprop0(LLV_DEBUG, newpp); 1158 1159 return 0; 1160err: 1161 flushsaprop(newpp); 1162 return -1; 1163} 1164 1165/* 1166 * generate a policy from peer's proposal. 1167 * this function unconditionally choices first proposal in SA payload 1168 * passed by peer. 1169 */ 1170int 1171set_proposal_from_proposal(iph2) 1172 struct ph2handle *iph2; 1173{ 1174 struct saprop *newpp = NULL, *pp0, *pp_peer = NULL; 1175 struct saproto *newpr = NULL, *pr; 1176 struct prop_pair **pair; 1177 int error = -1; 1178 int i; 1179 1180 /* get proposal pair */ 1181 pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2); 1182 if (pair == NULL) 1183 goto end; 1184 1185 /* 1186 * make my proposal according as the client proposal. 1187 * XXX assumed there is only one proposal even if it's the SA bundle. 1188 */ 1189 for (i = 0; i < MAXPROPPAIRLEN; i++) { 1190 if (pair[i] == NULL) 1191 continue; 1192 1193 if (pp_peer != NULL) 1194 flushsaprop(pp_peer); 1195 1196 pp_peer = aproppair2saprop(pair[i]); 1197 if (pp_peer == NULL) 1198 goto end; 1199 1200 pp0 = newsaprop(); 1201 if (pp0 == NULL) { 1202 plog(LLV_ERROR, LOCATION, NULL, 1203 "failed to allocate saprop.\n"); 1204 goto end; 1205 } 1206 pp0->prop_no = 1; 1207 pp0->lifetime = iph2->sainfo->lifetime; 1208 pp0->lifebyte = iph2->sainfo->lifebyte; 1209 pp0->pfs_group = iph2->sainfo->pfs_group; 1210 1211#ifdef HAVE_SECCTX 1212 if (*pp_peer->sctx.ctx_str) { 1213 pp0->sctx.ctx_doi = pp_peer->sctx.ctx_doi; 1214 pp0->sctx.ctx_alg = pp_peer->sctx.ctx_alg; 1215 pp0->sctx.ctx_strlen = pp_peer->sctx.ctx_strlen; 1216 memcpy(pp0->sctx.ctx_str, pp_peer->sctx.ctx_str, 1217 pp_peer->sctx.ctx_strlen); 1218 } 1219#endif /* HAVE_SECCTX */ 1220 1221 if (pp_peer->next != NULL) { 1222 plog(LLV_ERROR, LOCATION, NULL, 1223 "pp_peer is inconsistency, ignore it.\n"); 1224 /*FALLTHROUGH*/ 1225 } 1226 1227 for (pr = pp_peer->head; pr; pr = pr->next) 1228 { 1229 struct remoteconf *conf; 1230 1231 newpr = newsaproto(); 1232 if (newpr == NULL) 1233 { 1234 plog(LLV_ERROR, LOCATION, NULL, 1235 "failed to allocate saproto.\n"); 1236 racoon_free(pp0); 1237 goto end; 1238 } 1239 newpr->proto_id = pr->proto_id; 1240 newpr->spisize = pr->spisize; 1241 newpr->encmode = pr->encmode; 1242 newpr->spi = 0; 1243 newpr->spi_p = pr->spi; /* copy peer's SPI */ 1244 newpr->reqid_in = 0; 1245 newpr->reqid_out = 0; 1246 1247 conf = getrmconf(iph2->dst); 1248 if (conf != NULL && 1249 conf->gen_policy == GENERATE_POLICY_UNIQUE){ 1250 newpr->reqid_in = g_nextreqid ; 1251 newpr->reqid_out = g_nextreqid ++; 1252 /* 1253 * XXX there is a (very limited) 1254 * risk of reusing the same reqid 1255 * as another SP entry for the same peer 1256 */ 1257 if(g_nextreqid >= IPSEC_MANUAL_REQID_MAX) 1258 g_nextreqid = 1; 1259 }else{ 1260 newpr->reqid_in = 0; 1261 newpr->reqid_out = 0; 1262 } 1263 1264 if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) 1265 { 1266 plog(LLV_ERROR, LOCATION, NULL, 1267 "failed to get algorithms.\n"); 1268 racoon_free(newpr); 1269 racoon_free(pp0); 1270 goto end; 1271 } 1272 inssaproto(pp0, newpr); 1273 } 1274 1275 inssaprop(&newpp, pp0); 1276 } 1277 1278 plog(LLV_DEBUG, LOCATION, NULL, "make a proposal from peer's:\n"); 1279 printsaprop0(LLV_DEBUG, newpp); 1280 1281 iph2->proposal = newpp; 1282 1283 error = 0; 1284 1285end: 1286 if (error && newpp) 1287 flushsaprop(newpp); 1288 1289 if (pp_peer) 1290 flushsaprop(pp_peer); 1291 if (pair) 1292 free_proppair(pair); 1293 return error; 1294} 1295