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

    1: /*	$NetBSD: isakmp_inf.c,v 1.47 2011/03/15 13:20:14 vanhu Exp $	*/
    2: 
    3: /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
    4: 
    5: /*
    6:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    7:  * All rights reserved.
    8:  * 
    9:  * Redistribution and use in source and binary forms, with or without
   10:  * modification, are permitted provided that the following conditions
   11:  * are met:
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer.
   14:  * 2. Redistributions in binary form must reproduce the above copyright
   15:  *    notice, this list of conditions and the following disclaimer in the
   16:  *    documentation and/or other materials provided with the distribution.
   17:  * 3. Neither the name of the project nor the names of its contributors
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  * 
   21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  */
   33: 
   34: #include "config.h"
   35: 
   36: #include <sys/types.h>
   37: #include <sys/param.h>
   38: #include <sys/socket.h>
   39: 
   40: #include <net/pfkeyv2.h>
   41: #include <netinet/in.h>
   42: #include <sys/queue.h>
   43: #include PATH_IPSEC_H
   44: 
   45: #include <stdlib.h>
   46: #include <stdio.h>
   47: #include <string.h>
   48: #include <errno.h>
   49: #if TIME_WITH_SYS_TIME
   50: # include <sys/time.h>
   51: # include <time.h>
   52: #else
   53: # if HAVE_SYS_TIME_H
   54: #  include <sys/time.h>
   55: # else
   56: #  include <time.h>
   57: # endif
   58: #endif
   59: #ifdef ENABLE_HYBRID
   60: #include <resolv.h>
   61: #endif
   62: 
   63: #include "libpfkey.h"
   64: 
   65: #include "var.h"
   66: #include "vmbuf.h"
   67: #include "schedule.h"
   68: #include "str2val.h"
   69: #include "misc.h"
   70: #include "plog.h"
   71: #include "debug.h"
   72: 
   73: #include "localconf.h"
   74: #include "remoteconf.h"
   75: #include "sockmisc.h"
   76: #include "handler.h"
   77: #include "policy.h"
   78: #include "proposal.h"
   79: #include "isakmp_var.h"
   80: #include "evt.h"
   81: #include "isakmp.h"
   82: #ifdef ENABLE_HYBRID
   83: #include "isakmp_xauth.h"
   84: #include "isakmp_unity.h"
   85: #include "isakmp_cfg.h" 
   86: #endif
   87: #include "isakmp_inf.h"
   88: #include "oakley.h"
   89: #include "ipsec_doi.h"
   90: #include "crypto_openssl.h"
   91: #include "pfkey.h"
   92: #include "policy.h"
   93: #include "algorithm.h"
   94: #include "proposal.h"
   95: #include "admin.h"
   96: #include "strnames.h"
   97: #ifdef ENABLE_NATT
   98: #include "nattraversal.h"
   99: #endif
  100: 
  101: /* information exchange */
  102: static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int);
  103: static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int);
  104: 
  105: #ifdef ENABLE_DPD
  106: static int isakmp_info_recv_r_u __P((struct ph1handle *,
  107: 	struct isakmp_pl_ru *, u_int32_t));
  108: static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
  109: 	struct isakmp_pl_ru *, u_int32_t));
  110: static void isakmp_info_send_r_u __P((struct sched *));
  111: #endif
  112: 
  113: static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
  114: 
  115: /* %%%
  116:  * Information Exchange
  117:  */
  118: /*
  119:  * receive Information
  120:  */
  121: int
  122: isakmp_info_recv(iph1, msg0)
  123: 	struct ph1handle *iph1;
  124: 	vchar_t *msg0;
  125: {
  126: 	vchar_t *msg = NULL;
  127: 	vchar_t *pbuf = NULL;
  128: 	u_int32_t msgid = 0;
  129: 	int error = -1;
  130: 	struct isakmp *isakmp;
  131: 	struct isakmp_gen *gen;
  132: 	struct isakmp_parse_t *pa, *pap;
  133: 	void *p;
  134: 	vchar_t *hash, *payload;
  135: 	struct isakmp_gen *nd;
  136: 	u_int8_t np;
  137: 	int encrypted;
  138: 
  139: 	plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
  140: 
  141: 	encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
  142: 	msgid = ((struct isakmp *)msg0->v)->msgid;
  143: 
  144: 	/* Use new IV to decrypt Informational message. */
  145: 	if (encrypted) {
  146: 		struct isakmp_ivm *ivm;
  147: 
  148: 		if (iph1->ivm == NULL) {
  149: 			plog(LLV_ERROR, LOCATION, NULL, "iph1->ivm == NULL\n");
  150: 			return -1;
  151: 		}
  152: 
  153: 		/* compute IV */
  154: 		ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
  155: 		if (ivm == NULL)
  156: 			return -1;
  157: 
  158: 		msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
  159: 		oakley_delivm(ivm);
  160: 		if (msg == NULL)
  161: 			return -1;
  162: 
  163: 	} else
  164: 		msg = vdup(msg0);
  165: 
  166: 	/* Safety check */
  167: 	if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
  168: 		plog(LLV_ERROR, LOCATION, NULL, 
  169: 			"ignore information because the "
  170: 			"message is way too short - %zu byte(s).\n",
  171: 			msg->l);
  172: 		goto end;
  173: 	}
  174: 
  175: 	isakmp = (struct isakmp *)msg->v;
  176: 	gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
  177: 	np = gen->np;
  178: 
  179: 	if (encrypted) {
  180: 		if (isakmp->np != ISAKMP_NPTYPE_HASH) {
  181: 			plog(LLV_ERROR, LOCATION, NULL,
  182: 			    "ignore information because the "
  183: 			    "message has no hash payload.\n");
  184: 			goto end;
  185: 		}
  186: 
  187: 		if (iph1->status != PHASE1ST_ESTABLISHED &&
  188: 		    iph1->status != PHASE1ST_DYING) {
  189: 			plog(LLV_ERROR, LOCATION, NULL,
  190: 			    "ignore information because ISAKMP-SA "
  191: 			    "has not been established yet.\n");
  192: 			goto end;
  193: 		}
  194: 		
  195: 		/* Safety check */
  196: 		if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) {
  197: 			plog(LLV_ERROR, LOCATION, NULL, 
  198: 				"ignore information because the "
  199: 				"message is too short - %zu byte(s).\n",
  200: 				msg->l);
  201: 			goto end;
  202: 		}
  203: 
  204: 		p = (caddr_t) gen + sizeof(struct isakmp_gen);
  205: 		nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
  206: 
  207: 		/* nd length check */
  208: 		if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
  209: 		    ntohs(gen->len))) {
  210: 			plog(LLV_ERROR, LOCATION, NULL,
  211: 				 "too long payload length (broken message?)\n");
  212: 			goto end;
  213: 		}
  214: 
  215: 		if (ntohs(nd->len) < sizeof(*nd)) {
  216: 			plog(LLV_ERROR, LOCATION, NULL,
  217: 				"too short payload length (broken message?)\n");
  218: 			goto end;
  219: 		}
  220: 
  221: 		payload = vmalloc(ntohs(nd->len));
  222: 		if (payload == NULL) {
  223: 			plog(LLV_ERROR, LOCATION, NULL,
  224: 			    "cannot allocate memory\n");
  225: 			goto end;
  226: 		}
  227: 
  228: 		memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
  229: 
  230: 		/* compute HASH */
  231: 		hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
  232: 		if (hash == NULL) {
  233: 			plog(LLV_ERROR, LOCATION, NULL,
  234: 			    "cannot compute hash\n");
  235: 
  236: 			vfree(payload);
  237: 			goto end;
  238: 		}
  239: 		
  240: 		if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
  241: 			plog(LLV_ERROR, LOCATION, NULL,
  242: 			    "ignore information due to hash length mismatch\n");
  243: 
  244: 			vfree(hash);
  245: 			vfree(payload);
  246: 			goto end;
  247: 		}
  248: 
  249: 		if (memcmp(p, hash->v, hash->l) != 0) {
  250: 			plog(LLV_ERROR, LOCATION, NULL,
  251: 			    "ignore information due to hash mismatch\n");
  252: 
  253: 			vfree(hash);
  254: 			vfree(payload);
  255: 			goto end;
  256: 		}
  257: 
  258: 		plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
  259: 
  260: 		vfree(hash);
  261: 		vfree(payload);
  262: 	} else {
  263: 		/* make sure the packet was encrypted after the beginning of phase 1. */
  264: 		switch (iph1->etype) {
  265: 		case ISAKMP_ETYPE_AGG:
  266: 		case ISAKMP_ETYPE_BASE:
  267: 		case ISAKMP_ETYPE_IDENT:
  268: 			if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT)
  269: 			 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) {
  270: 				break;
  271: 			}
  272: 			/*FALLTHRU*/
  273: 		default:
  274: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  275: 				"%s message must be encrypted\n",
  276: 				s_isakmp_nptype(np));
  277: 			error = 0;
  278: 			goto end;
  279: 		}
  280: 	}
  281: 
  282: 	if (!(pbuf = isakmp_parse(msg))) {
  283: 		error = -1;
  284: 		goto end;
  285: 	}
  286: 
  287: 	error = 0;
  288: 	for (pa = (struct isakmp_parse_t *)pbuf->v; pa->type; pa++) {
  289: 		switch (pa->type) {
  290: 		case ISAKMP_NPTYPE_HASH:
  291: 			/* Handled above */
  292: 			break;
  293: 		case ISAKMP_NPTYPE_N:
  294: 			error = isakmp_info_recv_n(iph1,
  295: 				(struct isakmp_pl_n *)pa->ptr,
  296: 				msgid, encrypted);
  297: 			break;
  298: 		case ISAKMP_NPTYPE_D:
  299: 			error = isakmp_info_recv_d(iph1,
  300: 				(struct isakmp_pl_d *)pa->ptr,
  301: 				msgid, encrypted);
  302: 			break;
  303: 		case ISAKMP_NPTYPE_NONCE:
  304: 			/* XXX to be 6.4.2 ike-01.txt */
  305: 			/* XXX IV is to be synchronized. */
  306: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  307: 				"ignore Acknowledged Informational\n");
  308: 			break;
  309: 		default:
  310: 			/* don't send information, see isakmp_ident_r1() */
  311: 			error = 0;
  312: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  313: 				"reject the packet, "
  314: 				"received unexpected payload type %s.\n",
  315: 				s_isakmp_nptype(gen->np));
  316: 		}
  317: 		if (error < 0)
  318: 			break;
  319: 	}
  320:     end:
  321: 	if (msg != NULL)
  322: 		vfree(msg);
  323: 	if (pbuf != NULL)
  324: 		vfree(pbuf);
  325: 	return error;
  326: }
  327: 
  328: 
  329: /*
  330:  * log unhandled / unallowed Notification payload
  331:  */
  332: int
  333: isakmp_log_notify(iph1, notify, exchange)
  334: 	struct ph1handle *iph1;
  335: 	struct isakmp_pl_n *notify;
  336: 	const char *exchange;
  337: {
  338: 	u_int type;
  339: 	char *nraw, *ndata, *nhex;
  340: 	size_t l;
  341: 
  342: 	type = ntohs(notify->type);
  343: 	if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
  344: 		plog(LLV_ERROR, LOCATION, iph1->remote,
  345: 			"invalid spi_size in %s notification in %s.\n",
  346: 			s_isakmp_notify_msg(type), exchange);
  347: 		return -1;
  348: 	}
  349: 
  350: 	plog(LLV_ERROR, LOCATION, iph1->remote,
  351: 		"notification %s received in %s.\n",
  352: 		s_isakmp_notify_msg(type), exchange);
  353: 
  354: 	nraw = ((char*) notify) + sizeof(*notify) + notify->spi_size;
  355: 	l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
  356: 	if (l > 0) {
  357: 		if (type >= ISAKMP_NTYPE_MINERROR &&
  358: 		    type <= ISAKMP_NTYPE_MAXERROR) {
  359: 			ndata = binsanitize(nraw, l);
  360: 			if (ndata != NULL) {
  361: 				plog(LLV_ERROR, LOCATION, iph1->remote,
  362: 					"error message: '%s'.\n",
  363: 					ndata);
  364: 				racoon_free(ndata);
  365: 			} else {
  366: 				plog(LLV_ERROR, LOCATION, iph1->remote,
  367: 					"Cannot allocate memory\n");
  368: 			}
  369: 		} else {
  370: 			nhex = val2str(nraw, l);
  371: 			if (nhex != NULL) {
  372: 				plog(LLV_ERROR, LOCATION, iph1->remote,
  373: 					"notification payload: %s.\n",
  374: 					nhex);
  375: 				racoon_free(nhex);
  376: 			} else {
  377: 				plog(LLV_ERROR, LOCATION, iph1->remote,
  378: 					"Cannot allocate memory\n");
  379: 			}
  380: 		}
  381: 	}
  382: 
  383: 	return 0;
  384: }
  385: 
  386: 
  387: /*
  388:  * handling of Notification payload
  389:  */
  390: static int
  391: isakmp_info_recv_n(iph1, notify, msgid, encrypted)
  392: 	struct ph1handle *iph1;
  393: 	struct isakmp_pl_n *notify;
  394: 	u_int32_t msgid;
  395: 	int encrypted;
  396: {
  397: 	u_int type;
  398: 
  399: 	type = ntohs(notify->type);
  400: 	switch (type) {
  401: 	case ISAKMP_NTYPE_CONNECTED:
  402: 	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
  403: 	case ISAKMP_NTYPE_REPLAY_STATUS:
  404: #ifdef ENABLE_HYBRID
  405: 	case ISAKMP_NTYPE_UNITY_HEARTBEAT:
  406: #endif
  407: 		/* do something */
  408: 		break;
  409: 	case ISAKMP_NTYPE_INITIAL_CONTACT:
  410: 		if (encrypted)
  411: 			return isakmp_info_recv_initialcontact(iph1, NULL);
  412: 		break;
  413: #ifdef ENABLE_DPD
  414: 	case ISAKMP_NTYPE_R_U_THERE:
  415: 		if (encrypted)
  416: 			return isakmp_info_recv_r_u(iph1,
  417: 				(struct isakmp_pl_ru *)notify, msgid);
  418: 		break;
  419: 	case ISAKMP_NTYPE_R_U_THERE_ACK:
  420: 		if (encrypted)
  421: 			return isakmp_info_recv_r_u_ack(iph1,
  422: 				(struct isakmp_pl_ru *)notify, msgid);
  423: 		break;
  424: #endif
  425: 	}
  426: 
  427: 	/* If we receive a error notification we should delete the related
  428: 	 * phase1 / phase2 handle, and send an event to racoonctl.
  429: 	 * However, since phase1 error notifications are not encrypted and
  430: 	 * can not be authenticated, it would allow a DoS attack possibility
  431: 	 * to handle them.
  432: 	 * Phase2 error notifications should be encrypted, so we could handle
  433: 	 * those, but it needs implementing (the old code didn't implement
  434: 	 * that either).
  435: 	 * So we are good to just log the messages here.
  436: 	 */
  437: 	if (encrypted)
  438: 		isakmp_log_notify(iph1, notify, "informational exchange");
  439: 	else
  440: 		isakmp_log_notify(iph1, notify, "unencrypted informational exchange");
  441: 
  442: 	return 0;
  443: }
  444: 
  445: /*
  446:  * handling of Deletion payload
  447:  */
  448: static int
  449: isakmp_info_recv_d(iph1, delete, msgid, encrypted)
  450: 	struct ph1handle *iph1;
  451: 	struct isakmp_pl_d *delete;
  452: 	u_int32_t msgid;
  453: 	int encrypted;
  454: {
  455: 	int tlen, num_spi;
  456: 	vchar_t *pbuf;
  457: 	int protected = 0;
  458: 	struct ph1handle *del_ph1;
  459: 	struct ph2handle *iph2;
  460: 	union {
  461: 		u_int32_t spi32;
  462: 		u_int16_t spi16[2];
  463: 	} spi;
  464: 
  465: 	if (ntohl(delete->doi) != IPSEC_DOI) {
  466: 		plog(LLV_ERROR, LOCATION, iph1->remote,
  467: 			"delete payload with invalid doi:%d.\n",
  468: 			ntohl(delete->doi));
  469: #ifdef ENABLE_HYBRID
  470: 		/*
  471: 		 * At deconnexion time, Cisco VPN client does this
  472: 		 * with a zero DOI. Don't give up in that situation.
  473: 		 */
  474: 		if (((iph1->mode_cfg->flags &
  475: 		    ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0))
  476: 			return 0;
  477: #else
  478: 		return 0;
  479: #endif
  480: 	}
  481: 
  482: 	num_spi = ntohs(delete->num_spi);
  483: 	tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d);
  484: 
  485: 	if (tlen != num_spi * delete->spi_size) {
  486: 		plog(LLV_ERROR, LOCATION, iph1->remote,
  487: 			"deletion payload with invalid length.\n");
  488: 		return 0;
  489: 	}
  490: 
  491: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
  492: 		"delete payload for protocol %s\n",
  493: 		s_ipsecdoi_proto(delete->proto_id));
  494: 
  495: 	if(!iph1->rmconf->weak_phase1_check && !encrypted) {
  496: 		plog(LLV_WARNING, LOCATION, iph1->remote,
  497: 			"Ignoring unencrypted delete payload "
  498: 			"(check the weak_phase1_check option)\n");
  499: 		return 0;
  500: 	}
  501: 
  502: 	switch (delete->proto_id) {
  503: 	case IPSECDOI_PROTO_ISAKMP:
  504: 		if (delete->spi_size != sizeof(isakmp_index)) {
  505: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  506: 				"delete payload with strange spi "
  507: 				"size %d(proto_id:%d)\n",
  508: 				delete->spi_size, delete->proto_id);
  509: 			return 0;
  510: 		}
  511: 
  512: 		del_ph1=getph1byindex((isakmp_index *)(delete + 1));
  513: 		if(del_ph1 != NULL){
  514: 
  515: 			evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL);
  516: 			sched_cancel(&del_ph1->scr);
  517: 
  518: 			/*
  519: 			 * Delete also IPsec-SAs if rekeying is enabled.
  520: 			 */
  521: 			if (ph1_rekey_enabled(del_ph1))
  522: 				purge_remote(del_ph1);
  523: 			else
  524: 				isakmp_ph1expire(del_ph1);
  525: 		}
  526: 		break;
  527: 
  528: 	case IPSECDOI_PROTO_IPSEC_AH:
  529: 	case IPSECDOI_PROTO_IPSEC_ESP:
  530: 		if (delete->spi_size != sizeof(u_int32_t)) {
  531: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  532: 				"delete payload with strange spi "
  533: 				"size %d(proto_id:%d)\n",
  534: 				delete->spi_size, delete->proto_id);
  535: 			return 0;
  536: 		}
  537: 		purge_ipsec_spi(iph1->remote, delete->proto_id,
  538: 		    (u_int32_t *)(delete + 1), num_spi);
  539: 		break;
  540: 
  541: 	case IPSECDOI_PROTO_IPCOMP:
  542: 		/* need to handle both 16bit/32bit SPI */
  543: 		memset(&spi, 0, sizeof(spi));
  544: 		if (delete->spi_size == sizeof(spi.spi16[1])) {
  545: 			memcpy(&spi.spi16[1], delete + 1,
  546: 			    sizeof(spi.spi16[1]));
  547: 		} else if (delete->spi_size == sizeof(spi.spi32))
  548: 			memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32));
  549: 		else {
  550: 			plog(LLV_ERROR, LOCATION, iph1->remote,
  551: 				"delete payload with strange spi "
  552: 				"size %d(proto_id:%d)\n",
  553: 				delete->spi_size, delete->proto_id);
  554: 			return 0;
  555: 		}
  556: 		purge_ipsec_spi(iph1->remote, delete->proto_id,
  557: 		    &spi.spi32, num_spi);
  558: 		break;
  559: 
  560: 	default:
  561: 		plog(LLV_ERROR, LOCATION, iph1->remote,
  562: 			"deletion message received, "
  563: 			"invalid proto_id: %d\n",
  564: 			delete->proto_id);
  565: 		return 0;
  566: 	}
  567: 
  568: 	plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
  569: 
  570: 	return 0;
  571: }
  572: 
  573: /*
  574:  * send Delete payload (for ISAKMP SA) in Informational exchange.
  575:  */
  576: int
  577: isakmp_info_send_d1(iph1)
  578: 	struct ph1handle *iph1;
  579: {
  580: 	struct isakmp_pl_d *d;
  581: 	vchar_t *payload = NULL;
  582: 	int tlen;
  583: 	int error = 0;
  584: 
  585: 	if (iph1->status != PHASE2ST_ESTABLISHED)
  586: 		return 0;
  587: 
  588: 	/* create delete payload */
  589: 
  590: 	/* send SPIs of inbound SAs. */
  591: 	/* XXX should send outbound SAs's ? */
  592: 	tlen = sizeof(*d) + sizeof(isakmp_index);
  593: 	payload = vmalloc(tlen);
  594: 	if (payload == NULL) {
  595: 		plog(LLV_ERROR, LOCATION, NULL, 
  596: 			"failed to get buffer for payload.\n");
  597: 		return errno;
  598: 	}
  599: 
  600: 	d = (struct isakmp_pl_d *)payload->v;
  601: 	d->h.np = ISAKMP_NPTYPE_NONE;
  602: 	d->h.len = htons(tlen);
  603: 	d->doi = htonl(IPSEC_DOI);
  604: 	d->proto_id = IPSECDOI_PROTO_ISAKMP;
  605: 	d->spi_size = sizeof(isakmp_index);
  606: 	d->num_spi = htons(1);
  607: 	memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
  608: 
  609: 	error = isakmp_info_send_common(iph1, payload,
  610: 					ISAKMP_NPTYPE_D, 0);
  611: 	vfree(payload);
  612: 
  613: 	return error;
  614: }
  615: 
  616: /*
  617:  * send Delete payload (for IPsec SA) in Informational exchange, based on
  618:  * pfkey msg.  It sends always single SPI.
  619:  */
  620: int
  621: isakmp_info_send_d2(iph2)
  622: 	struct ph2handle *iph2;
  623: {
  624: 	struct ph1handle *iph1;
  625: 	struct saproto *pr;
  626: 	struct isakmp_pl_d *d;
  627: 	vchar_t *payload = NULL;
  628: 	int tlen;
  629: 	int error = 0;
  630: 	u_int8_t *spi;
  631: 
  632: 	if (iph2->status != PHASE2ST_ESTABLISHED)
  633: 		return 0;
  634: 
  635: 	/*
  636: 	 * don't send delete information if there is no phase 1 handler.
  637: 	 * It's nonsensical to negotiate phase 1 to send the information.
  638: 	 */
  639: 	iph1 = getph1byaddr(iph2->src, iph2->dst, 0); 
  640: 	if (iph1 == NULL){
  641: 		plog(LLV_DEBUG2, LOCATION, NULL,
  642: 			 "No ph1 handler found, could not send DELETE_SA\n");
  643: 		return 0;
  644: 	}
  645: 
  646: 	/* create delete payload */
  647: 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
  648: 
  649: 		/* send SPIs of inbound SAs. */
  650: 		/*
  651: 		 * XXX should I send outbound SAs's ?
  652: 		 * I send inbound SAs's SPI only at the moment because I can't
  653: 		 * decode any more if peer send encoded packet without aware of
  654: 		 * deletion of SA.  Outbound SAs don't come under the situation.
  655: 		 */
  656: 		tlen = sizeof(*d) + pr->spisize;
  657: 		payload = vmalloc(tlen);
  658: 		if (payload == NULL) {
  659: 			plog(LLV_ERROR, LOCATION, NULL, 
  660: 				"failed to get buffer for payload.\n");
  661: 			return errno;
  662: 		}
  663: 
  664: 		d = (struct isakmp_pl_d *)payload->v;
  665: 		d->h.np = ISAKMP_NPTYPE_NONE;
  666: 		d->h.len = htons(tlen);
  667: 		d->doi = htonl(IPSEC_DOI);
  668: 		d->proto_id = pr->proto_id;
  669: 		d->spi_size = pr->spisize;
  670: 		d->num_spi = htons(1);
  671: 		/*
  672: 		 * XXX SPI bits are left-filled, for use with IPComp.
  673: 		 * we should be switching to variable-length spi field...
  674: 		 */
  675: 		spi = (u_int8_t *)&pr->spi;
  676: 		spi += sizeof(pr->spi);
  677: 		spi -= pr->spisize;
  678: 		memcpy(d + 1, spi, pr->spisize);
  679: 
  680: 		error = isakmp_info_send_common(iph1, payload,
  681: 						ISAKMP_NPTYPE_D, 0);
  682: 		vfree(payload);
  683: 	}
  684: 
  685: 	return error;
  686: }
  687: 
  688: /*
  689:  * send Notification payload (for without ISAKMP SA) in Informational exchange
  690:  */
  691: int
  692: isakmp_info_send_nx(isakmp, remote, local, type, data)
  693: 	struct isakmp *isakmp;
  694: 	struct sockaddr *remote, *local;
  695: 	int type;
  696: 	vchar_t *data;
  697: {
  698: 	struct ph1handle *iph1 = NULL;
  699: 	vchar_t *payload = NULL;
  700: 	int tlen;
  701: 	int error = -1;
  702: 	struct isakmp_pl_n *n;
  703: 	int spisiz = 0;		/* see below */
  704: 
  705: 	/* add new entry to isakmp status table. */
  706: 	iph1 = newph1();
  707: 	if (iph1 == NULL)
  708: 		return -1;
  709: 
  710: 	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
  711: 	isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
  712: 	iph1->status = PHASE1ST_START;
  713: 	iph1->side = INITIATOR;
  714: 	iph1->version = isakmp->v;
  715: 	iph1->flags = 0;
  716: 	iph1->msgid = 0;	/* XXX */
  717: #ifdef ENABLE_HYBRID
  718: 	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
  719: 		goto end;
  720: #endif
  721: #ifdef ENABLE_FRAG
  722: 	iph1->frag = 0;
  723: 	iph1->frag_chain = NULL;
  724: #endif
  725: 
  726: 	/* copy remote address */
  727: 	if (copy_ph1addresses(iph1, NULL, remote, local) < 0)
  728: 		goto end;
  729: 
  730: 	tlen = sizeof(*n) + spisiz;
  731: 	if (data)
  732: 		tlen += data->l;
  733: 	payload = vmalloc(tlen);
  734: 	if (payload == NULL) { 
  735: 		plog(LLV_ERROR, LOCATION, NULL,
  736: 			"failed to get buffer to send.\n");
  737: 		goto end;
  738: 	}
  739: 
  740: 	n = (struct isakmp_pl_n *)payload->v;
  741: 	n->h.np = ISAKMP_NPTYPE_NONE;
  742: 	n->h.len = htons(tlen);
  743: 	n->doi = htonl(IPSEC_DOI);
  744: 	n->proto_id = IPSECDOI_KEY_IKE;
  745: 	n->spi_size = spisiz;
  746: 	n->type = htons(type);
  747: 	if (spisiz)
  748: 		memset(n + 1, 0, spisiz);	/* XXX spisiz is always 0 */
  749: 	if (data)
  750: 		memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
  751: 
  752: 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
  753: 	vfree(payload);
  754: 
  755:     end:
  756: 	if (iph1 != NULL)
  757: 		delph1(iph1);
  758: 
  759: 	return error;
  760: }
  761: 
  762: /*
  763:  * send Notification payload (for ISAKMP SA) in Informational exchange
  764:  */
  765: int
  766: isakmp_info_send_n1(iph1, type, data)
  767: 	struct ph1handle *iph1;
  768: 	int type;
  769: 	vchar_t *data;
  770: {
  771: 	vchar_t *payload = NULL;
  772: 	int tlen;
  773: 	int error = 0;
  774: 	struct isakmp_pl_n *n;
  775: 	int spisiz;
  776: 
  777: 	/*
  778: 	 * note on SPI size: which description is correct?  I have chosen
  779: 	 * this to be 0.
  780: 	 *
  781: 	 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
  782: 	 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
  783: 	 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
  784: 	 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
  785: 	 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
  786: 	 */
  787: 	if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
  788: 		spisiz = sizeof(isakmp_index);
  789: 	else
  790: 		spisiz = 0;
  791: 
  792: 	tlen = sizeof(*n) + spisiz;
  793: 	if (data)
  794: 		tlen += data->l;
  795: 	payload = vmalloc(tlen);
  796: 	if (payload == NULL) { 
  797: 		plog(LLV_ERROR, LOCATION, NULL,
  798: 			"failed to get buffer to send.\n");
  799: 		return errno;
  800: 	}
  801: 
  802: 	n = (struct isakmp_pl_n *)payload->v;
  803: 	n->h.np = ISAKMP_NPTYPE_NONE;
  804: 	n->h.len = htons(tlen);
  805: 	n->doi = htonl(iph1->rmconf->doitype);
  806: 	n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
  807: 	n->spi_size = spisiz;
  808: 	n->type = htons(type);
  809: 	if (spisiz)
  810: 		memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
  811: 	if (data)
  812: 		memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
  813: 
  814: 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
  815: 	vfree(payload);
  816: 
  817: 	return error;
  818: }
  819: 
  820: /*
  821:  * send Notification payload (for IPsec SA) in Informational exchange
  822:  */
  823: int
  824: isakmp_info_send_n2(iph2, type, data)
  825: 	struct ph2handle *iph2;
  826: 	int type;
  827: 	vchar_t *data;
  828: {
  829: 	struct ph1handle *iph1 = iph2->ph1;
  830: 	vchar_t *payload = NULL;
  831: 	int tlen;
  832: 	int error = 0;
  833: 	struct isakmp_pl_n *n;
  834: 	struct saproto *pr;
  835: 
  836: 	if (!iph2->approval)
  837: 		return EINVAL;
  838: 
  839: 	pr = iph2->approval->head;
  840: 
  841: 	/* XXX must be get proper spi */
  842: 	tlen = sizeof(*n) + pr->spisize;
  843: 	if (data)
  844: 		tlen += data->l;
  845: 	payload = vmalloc(tlen);
  846: 	if (payload == NULL) { 
  847: 		plog(LLV_ERROR, LOCATION, NULL,
  848: 			"failed to get buffer to send.\n");
  849: 		return errno;
  850: 	}
  851: 
  852: 	n = (struct isakmp_pl_n *)payload->v;
  853: 	n->h.np = ISAKMP_NPTYPE_NONE;
  854: 	n->h.len = htons(tlen);
  855: 	n->doi = htonl(IPSEC_DOI);		/* IPSEC DOI (1) */
  856: 	n->proto_id = pr->proto_id;		/* IPSEC AH/ESP/whatever*/
  857: 	n->spi_size = pr->spisize;
  858: 	n->type = htons(type);
  859: 	*(u_int32_t *)(n + 1) = pr->spi;
  860: 	if (data)
  861: 		memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
  862: 
  863: 	iph2->flags |= ISAKMP_FLAG_E;	/* XXX Should we do FLAG_A ? */
  864: 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
  865: 	vfree(payload);
  866: 
  867: 	return error;
  868: }
  869: 
  870: /*
  871:  * send Information
  872:  * When ph1->skeyid_a == NULL, send message without encoding.
  873:  */
  874: int
  875: isakmp_info_send_common(iph1, payload, np, flags)
  876: 	struct ph1handle *iph1;
  877: 	vchar_t *payload;
  878: 	u_int32_t np;
  879: 	int flags;
  880: {
  881: 	struct ph2handle *iph2 = NULL;
  882: 	vchar_t *hash = NULL;
  883: 	struct isakmp *isakmp;
  884: 	struct isakmp_gen *gen;
  885: 	char *p;
  886: 	int tlen;
  887: 	int error = -1;
  888: 
  889: 	/* add new entry to isakmp status table */
  890: 	iph2 = newph2();
  891: 	if (iph2 == NULL)
  892: 		goto end;
  893: 
  894: 	iph2->dst = dupsaddr(iph1->remote);
  895: 	if (iph2->dst == NULL) {
  896: 		delph2(iph2);
  897: 		goto end;
  898: 	}
  899: 	iph2->src = dupsaddr(iph1->local);
  900: 	if (iph2->src == NULL) {
  901: 		delph2(iph2);
  902: 		goto end;
  903: 	}
  904: 	iph2->side = INITIATOR;
  905: 	iph2->status = PHASE2ST_START;
  906: 	iph2->msgid = isakmp_newmsgid2(iph1);
  907: 
  908: 	/* get IV and HASH(1) if skeyid_a was generated. */
  909: 	if (iph1->skeyid_a != NULL) {
  910: 		iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
  911: 		if (iph2->ivm == NULL) {
  912: 			delph2(iph2);
  913: 			goto end;
  914: 		}
  915: 
  916: 		/* generate HASH(1) */
  917: 		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
  918: 		if (hash == NULL) {
  919: 			delph2(iph2);
  920: 			goto end;
  921: 		}
  922: 
  923: 		/* initialized total buffer length */
  924: 		tlen = hash->l;
  925: 		tlen += sizeof(*gen);
  926: 	} else {
  927: 		/* IKE-SA is not established */
  928: 		hash = NULL;
  929: 
  930: 		/* initialized total buffer length */
  931: 		tlen = 0;
  932: 	}
  933: 	if ((flags & ISAKMP_FLAG_A) == 0)
  934: 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
  935: 	else
  936: 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
  937: 
  938: 	insph2(iph2);
  939: 	bindph12(iph1, iph2);
  940: 
  941: 	tlen += sizeof(*isakmp) + payload->l;
  942: 
  943: 	/* create buffer for isakmp payload */
  944: 	iph2->sendbuf = vmalloc(tlen);
  945: 	if (iph2->sendbuf == NULL) { 
  946: 		plog(LLV_ERROR, LOCATION, NULL,
  947: 			"failed to get buffer to send.\n");
  948: 		goto err;
  949: 	}
  950: 
  951: 	/* create isakmp header */
  952: 	isakmp = (struct isakmp *)iph2->sendbuf->v;
  953: 	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
  954: 	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
  955: 	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
  956: 	isakmp->v = iph1->version;
  957: 	isakmp->etype = ISAKMP_ETYPE_INFO;
  958: 	isakmp->flags = iph2->flags;
  959: 	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
  960: 	isakmp->len   = htonl(tlen);
  961: 	p = (char *)(isakmp + 1);
  962: 
  963: 	/* create HASH payload */
  964: 	if (hash != NULL) {
  965: 		gen = (struct isakmp_gen *)p;
  966: 		gen->np = np & 0xff;
  967: 		gen->len = htons(sizeof(*gen) + hash->l);
  968: 		p += sizeof(*gen);
  969: 		memcpy(p, hash->v, hash->l);
  970: 		p += hash->l;
  971: 	}
  972: 
  973: 	/* add payload */
  974: 	memcpy(p, payload->v, payload->l);
  975: 	p += payload->l;
  976: 
  977: #ifdef HAVE_PRINT_ISAKMP_C
  978: 	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
  979: #endif
  980: 
  981: 	/* encoding */
  982: 	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
  983: 		vchar_t *tmp;
  984: 
  985: 		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
  986: 				iph2->ivm->iv);
  987: 		VPTRINIT(iph2->sendbuf);
  988: 		if (tmp == NULL)
  989: 			goto err;
  990: 		iph2->sendbuf = tmp;
  991: 	}
  992: 
  993: 	/* HDR*, HASH(1), N */
  994: 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
  995: 		VPTRINIT(iph2->sendbuf);
  996: 		goto err;
  997: 	}
  998: 
  999: 	plog(LLV_DEBUG, LOCATION, NULL,
 1000: 		"sendto Information %s.\n", s_isakmp_nptype(np));
 1001: 
 1002: 	/*
 1003: 	 * don't resend notify message because peer can use Acknowledged
 1004: 	 * Informational if peer requires the reply of the notify message.
 1005: 	 */
 1006: 
 1007: 	/* XXX If Acknowledged Informational required, don't delete ph2handle */
 1008: 	error = 0;
 1009: 	VPTRINIT(iph2->sendbuf);
 1010: 	goto err;	/* XXX */
 1011: 
 1012: end:
 1013: 	if (hash)
 1014: 		vfree(hash);
 1015: 	return error;
 1016: 
 1017: err:
 1018: 	remph2(iph2);
 1019: 	delph2(iph2);
 1020: 	goto end;
 1021: }
 1022: 
 1023: /*
 1024:  * add a notify payload to buffer by reallocating buffer.
 1025:  * If buf == NULL, the function only create a notify payload.
 1026:  *
 1027:  * XXX Which is SPI to be included, inbound or outbound ?
 1028:  */
 1029: vchar_t *
 1030: isakmp_add_pl_n(buf0, np_p, type, pr, data)
 1031: 	vchar_t *buf0;
 1032: 	u_int8_t **np_p;
 1033: 	int type;
 1034: 	struct saproto *pr;
 1035: 	vchar_t *data;
 1036: {
 1037: 	vchar_t *buf = NULL;
 1038: 	struct isakmp_pl_n *n;
 1039: 	int tlen;
 1040: 	int oldlen = 0;
 1041: 
 1042: 	if (*np_p)
 1043: 		**np_p = ISAKMP_NPTYPE_N;
 1044: 
 1045: 	tlen = sizeof(*n) + pr->spisize;
 1046: 
 1047: 	if (data)
 1048: 		tlen += data->l;
 1049: 	if (buf0) {
 1050: 		oldlen = buf0->l;
 1051: 		buf = vrealloc(buf0, buf0->l + tlen);
 1052: 	} else
 1053: 		buf = vmalloc(tlen);
 1054: 	if (!buf) {
 1055: 		plog(LLV_ERROR, LOCATION, NULL,
 1056: 			"failed to get a payload buffer.\n");
 1057: 		return NULL;
 1058: 	}
 1059: 
 1060: 	n = (struct isakmp_pl_n *)(buf->v + oldlen);
 1061: 	n->h.np = ISAKMP_NPTYPE_NONE;
 1062: 	n->h.len = htons(tlen);
 1063: 	n->doi = htonl(IPSEC_DOI);		/* IPSEC DOI (1) */
 1064: 	n->proto_id = pr->proto_id;		/* IPSEC AH/ESP/whatever*/
 1065: 	n->spi_size = pr->spisize;
 1066: 	n->type = htons(type);
 1067: 	*(u_int32_t *)(n + 1) = pr->spi;	/* XXX */
 1068: 	if (data)
 1069: 		memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
 1070: 
 1071: 	/* save the pointer of next payload type */
 1072: 	*np_p = &n->h.np;
 1073: 
 1074: 	return buf;
 1075: }
 1076: 
 1077: static void
 1078: purge_isakmp_spi(proto, spi, n)
 1079: 	int proto;
 1080: 	isakmp_index *spi;	/*network byteorder*/
 1081: 	size_t n;
 1082: {
 1083: 	struct ph1handle *iph1;
 1084: 	size_t i;
 1085: 
 1086: 	for (i = 0; i < n; i++) {
 1087: 		iph1 = getph1byindex(&spi[i]);
 1088: 		if (!iph1)
 1089: 			continue;
 1090: 
 1091: 		plog(LLV_INFO, LOCATION, NULL,
 1092: 			"purged ISAKMP-SA proto_id=%s spi=%s.\n",
 1093: 			s_ipsecdoi_proto(proto),
 1094: 			isakmp_pindex(&spi[i], 0));
 1095: 
 1096: 		iph1->status = PHASE1ST_EXPIRED;
 1097: 		isakmp_ph1delete(iph1);
 1098: 	}
 1099: }
 1100: 
 1101: 
 1102: 
 1103: void
 1104: purge_ipsec_spi(dst0, proto, spi, n)
 1105: 	struct sockaddr *dst0;
 1106: 	int proto;
 1107: 	u_int32_t *spi;	/*network byteorder*/
 1108: 	size_t n;
 1109: {
 1110: 	vchar_t *buf = NULL;
 1111: 	struct sadb_msg *msg, *next, *end;
 1112: 	struct sadb_sa *sa;
 1113: 	struct sadb_lifetime *lt;
 1114: 	struct sockaddr *src, *dst;
 1115: 	struct ph2handle *iph2;
 1116: 	u_int64_t created;
 1117: 	size_t i;
 1118: 	caddr_t mhp[SADB_EXT_MAX + 1];
 1119: 
 1120: 	plog(LLV_DEBUG2, LOCATION, NULL,
 1121: 		 "purge_ipsec_spi:\n");
 1122: 	plog(LLV_DEBUG2, LOCATION, NULL, "dst0: %s\n", saddr2str(dst0));
 1123: 	plog(LLV_DEBUG2, LOCATION, NULL, "SPI: %08X\n", ntohl(spi[0]));
 1124: 
 1125: 	buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
 1126: 	if (buf == NULL) {
 1127: 		plog(LLV_DEBUG, LOCATION, NULL,
 1128: 			"pfkey_dump_sadb returned nothing.\n");
 1129: 		return;
 1130: 	}
 1131: 
 1132: 	msg = (struct sadb_msg *)buf->v;
 1133: 	end = (struct sadb_msg *)(buf->v + buf->l);
 1134: 
 1135: 	while (msg < end) {
 1136: 		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
 1137: 			break;
 1138: 		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
 1139: 		if (msg->sadb_msg_type != SADB_DUMP) {
 1140: 			msg = next;
 1141: 			continue;
 1142: 		}
 1143: 
 1144: 		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
 1145: 			plog(LLV_ERROR, LOCATION, NULL,
 1146: 				"pfkey_check (%s)\n", ipsec_strerror());
 1147: 			msg = next;
 1148: 			continue;
 1149: 		}
 1150: 
 1151: 		sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
 1152: 		if (!sa
 1153: 		 || !mhp[SADB_EXT_ADDRESS_SRC]
 1154: 		 || !mhp[SADB_EXT_ADDRESS_DST]) {
 1155: 			msg = next;
 1156: 			continue;
 1157: 		}
 1158: 		pk_fixup_sa_addresses(mhp);
 1159: 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 1160: 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 1161: 		lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
 1162: 		if(lt != NULL)
 1163: 			created = lt->sadb_lifetime_addtime;
 1164: 		else
 1165: 			created = 0;
 1166: 
 1167: 		if (sa->sadb_sa_state != SADB_SASTATE_MATURE
 1168: 		 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
 1169: 			msg = next;
 1170: 			continue;
 1171: 		}
 1172: 
 1173: 		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
 1174: 		plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
 1175: 
 1176: 		/* XXX n^2 algorithm, inefficient */
 1177: 
 1178: 		/* don't delete inbound SAs at the moment */
 1179: 		/* XXX should we remove SAs with opposite direction as well? */
 1180: 		if (cmpsaddr(dst0, dst) != CMPSADDR_MATCH) {
 1181: 			msg = next;
 1182: 			continue;
 1183: 		}
 1184: 
 1185: 		for (i = 0; i < n; i++) {
 1186: 			plog(LLV_DEBUG, LOCATION, NULL,
 1187: 				"check spi(packet)=%u spi(db)=%u.\n",
 1188: 				ntohl(spi[i]), ntohl(sa->sadb_sa_spi));
 1189: 			if (spi[i] != sa->sadb_sa_spi)
 1190: 				continue;
 1191: 
 1192: 			pfkey_send_delete(lcconf->sock_pfkey,
 1193: 				msg->sadb_msg_satype,
 1194: 				IPSEC_MODE_ANY,
 1195: 				src, dst, sa->sadb_sa_spi);
 1196: 
 1197: 			/*
 1198: 			 * delete a relative phase 2 handler.
 1199: 			 * continue to process if no relative phase 2 handler
 1200: 			 * exists.
 1201: 			 */
 1202: 			iph2 = getph2bysaidx(src, dst, proto, spi[i]);
 1203: 			if(iph2 != NULL){
 1204: 				delete_spd(iph2, created);
 1205: 				remph2(iph2);
 1206: 				delph2(iph2);
 1207: 			}
 1208: 
 1209: 			plog(LLV_INFO, LOCATION, NULL,
 1210: 				"purged IPsec-SA proto_id=%s spi=%u.\n",
 1211: 				s_ipsecdoi_proto(proto),
 1212: 				ntohl(spi[i]));
 1213: 		}
 1214: 
 1215: 		msg = next;
 1216: 	}
 1217: 
 1218: 	if (buf)
 1219: 		vfree(buf);
 1220: }
 1221: 
 1222: /*
 1223:  * delete all phase2 sa relatived to the destination address
 1224:  * (except the phase2 within which the INITIAL-CONTACT was received).
 1225:  * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
 1226:  * an INITIAL-CONTACT if we have contacted the peer.  This matches the
 1227:  * Sun IKE behavior, and makes rekeying work much better when the peer
 1228:  * restarts.
 1229:  */
 1230: int
 1231: isakmp_info_recv_initialcontact(iph1, protectedph2)
 1232: 	struct ph1handle *iph1;
 1233: 	struct ph2handle *protectedph2;
 1234: {
 1235: 	vchar_t *buf = NULL;
 1236: 	struct sadb_msg *msg, *next, *end;
 1237: 	struct sadb_sa *sa;
 1238: 	struct sockaddr *src, *dst;
 1239: 	caddr_t mhp[SADB_EXT_MAX + 1];
 1240: 	int proto_id, i;
 1241: 	struct ph2handle *iph2;
 1242: #if 0
 1243: 	char *loc, *rem;
 1244: #endif
 1245: 
 1246: 	plog(LLV_INFO, LOCATION, iph1->remote, "received INITIAL-CONTACT\n");
 1247: 
 1248: 	if (f_local)
 1249: 		return 0;
 1250: 
 1251: #if 0
 1252: 	loc = racoon_strdup(saddrwop2str(iph1->local));
 1253: 	rem = racoon_strdup(saddrwop2str(iph1->remote));
 1254: 	STRDUP_FATAL(loc);
 1255: 	STRDUP_FATAL(rem);
 1256: 
 1257: 	/*
 1258: 	 * Purge all IPSEC-SAs for the peer.  We can do this
 1259: 	 * the easy way (using a PF_KEY SADB_DELETE extension)
 1260: 	 * or we can do it the hard way.
 1261: 	 */
 1262: 	for (i = 0; i < pfkey_nsatypes; i++) {
 1263: 		proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
 1264: 
 1265: 		plog(LLV_INFO, LOCATION, NULL,
 1266: 		    "purging %s SAs for %s -> %s\n",
 1267: 		    pfkey_satypes[i].ps_name, loc, rem);
 1268: 		if (pfkey_send_delete_all(lcconf->sock_pfkey,
 1269: 		    pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
 1270: 		    iph1->local, iph1->remote) == -1) {
 1271: 			plog(LLV_ERROR, LOCATION, NULL,
 1272: 			    "delete_all %s -> %s failed for %s (%s)\n",
 1273: 			    loc, rem,
 1274: 			    pfkey_satypes[i].ps_name, ipsec_strerror());
 1275: 			goto the_hard_way;
 1276: 		}
 1277: 
 1278: 		deleteallph2(iph1->local, iph1->remote, proto_id);
 1279: 
 1280: 		plog(LLV_INFO, LOCATION, NULL,
 1281: 		    "purging %s SAs for %s -> %s\n",
 1282: 		    pfkey_satypes[i].ps_name, rem, loc);
 1283: 		if (pfkey_send_delete_all(lcconf->sock_pfkey,
 1284: 		    pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
 1285: 		    iph1->remote, iph1->local) == -1) {
 1286: 			plog(LLV_ERROR, LOCATION, NULL,
 1287: 			    "delete_all %s -> %s failed for %s (%s)\n",
 1288: 			    rem, loc,
 1289: 			    pfkey_satypes[i].ps_name, ipsec_strerror());
 1290: 			goto the_hard_way;
 1291: 		}
 1292: 
 1293: 		deleteallph2(iph1->remote, iph1->local, proto_id);
 1294: 	}
 1295: 
 1296: 	racoon_free(loc);
 1297: 	racoon_free(rem);
 1298: 	return 0;
 1299: 
 1300:  the_hard_way:
 1301: 	racoon_free(loc);
 1302: 	racoon_free(rem);
 1303: #endif
 1304: 
 1305: 	buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
 1306: 	if (buf == NULL) {
 1307: 		plog(LLV_DEBUG, LOCATION, NULL,
 1308: 			"pfkey_dump_sadb returned nothing.\n");
 1309: 		return 0;
 1310: 	}
 1311: 
 1312: 	msg = (struct sadb_msg *)buf->v;
 1313: 	end = (struct sadb_msg *)(buf->v + buf->l);
 1314: 
 1315: 	for (; msg < end; msg = next) {
 1316: 		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
 1317: 			break;
 1318: 
 1319: 		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
 1320: 		if (msg->sadb_msg_type != SADB_DUMP)
 1321: 			continue;
 1322: 
 1323: 		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
 1324: 			plog(LLV_ERROR, LOCATION, NULL,
 1325: 				"pfkey_check (%s)\n", ipsec_strerror());
 1326: 			continue;
 1327: 		}
 1328: 
 1329: 		if (mhp[SADB_EXT_SA] == NULL
 1330: 		 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
 1331: 		 || mhp[SADB_EXT_ADDRESS_DST] == NULL)
 1332: 			continue;
 1333: 
 1334: 		sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
 1335: 		pk_fixup_sa_addresses(mhp);
 1336: 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 1337: 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 1338: 
 1339: 		if (sa->sadb_sa_state != SADB_SASTATE_MATURE
 1340: 		 && sa->sadb_sa_state != SADB_SASTATE_DYING)
 1341: 			continue;
 1342: 
 1343: 		/*
 1344: 		 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
 1345: 		 * announces the sender of the message was rebooted.
 1346: 		 * it is interpreted to delete all SAs which source address
 1347: 		 * is the sender of the message.
 1348: 		 * racoon only deletes SA which is matched both the
 1349: 		 * source address and the destination accress.
 1350: 		 */
 1351: 
 1352: 		/*
 1353: 		 * Check that the IP and port match. But this is not optimal,
 1354: 		 * since NAT-T can make the peer have multiple different
 1355: 		 * ports. Correct thing to do is delete all entries with
 1356:                  * same identity. -TT
 1357:                  */
 1358: 		if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH ||
 1359: 		     cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) &&
 1360: 		    (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH ||
 1361: 		     cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH))
 1362: 			continue;
 1363: 
 1364: 		/*
 1365: 		 * Make sure this is an SATYPE that we manage.
 1366: 		 * This is gross; too bad we couldn't do it the
 1367: 		 * easy way.
 1368: 		 */
 1369: 		for (i = 0; i < pfkey_nsatypes; i++) {
 1370: 			if (pfkey_satypes[i].ps_satype ==
 1371: 			    msg->sadb_msg_satype)
 1372: 				break;
 1373: 		}
 1374: 		if (i == pfkey_nsatypes)
 1375: 			continue;
 1376: 
 1377: 		plog(LLV_INFO, LOCATION, NULL,
 1378: 			"purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
 1379: 		pfkey_send_delete(lcconf->sock_pfkey,
 1380: 			msg->sadb_msg_satype,
 1381: 			IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
 1382: 
 1383: 		/*
 1384: 		 * delete a relative phase 2 handler.
 1385: 		 * continue to process if no relative phase 2 handler
 1386: 		 * exists.
 1387: 		 */
 1388: 		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
 1389: 		iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
 1390: 		if (iph2 && iph2 != protectedph2) {
 1391: 			delete_spd(iph2, 0);
 1392: 			remph2(iph2);
 1393: 			delph2(iph2);
 1394: 		}
 1395: 	}
 1396: 
 1397: 	vfree(buf);
 1398: 	return 0;
 1399: }
 1400: 
 1401: 
 1402: #ifdef ENABLE_DPD
 1403: static int
 1404: isakmp_info_recv_r_u (iph1, ru, msgid)
 1405: 	struct ph1handle *iph1;
 1406: 	struct isakmp_pl_ru *ru;
 1407: 	u_int32_t msgid;
 1408: {
 1409: 	struct isakmp_pl_ru *ru_ack;
 1410: 	vchar_t *payload = NULL;
 1411: 	int tlen;
 1412: 	int error = 0;
 1413: 
 1414: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 1415: 		 "DPD R-U-There received\n");
 1416: 
 1417: 	/* XXX should compare cookies with iph1->index?
 1418: 	   Or is this already done by calling function?  */
 1419: 	tlen = sizeof(*ru_ack);
 1420: 	payload = vmalloc(tlen);
 1421: 	if (payload == NULL) { 
 1422: 		plog(LLV_ERROR, LOCATION, NULL,
 1423: 			"failed to get buffer to send.\n");
 1424: 		return errno;
 1425: 	}
 1426: 
 1427: 	ru_ack = (struct isakmp_pl_ru *)payload->v;
 1428: 	ru_ack->h.np = ISAKMP_NPTYPE_NONE;
 1429: 	ru_ack->h.len = htons(tlen);
 1430: 	ru_ack->doi = htonl(IPSEC_DOI);
 1431: 	ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
 1432: 	ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
 1433: 	ru_ack->spi_size = sizeof(isakmp_index);
 1434: 	memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
 1435: 	memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));	
 1436: 	ru_ack->data = ru->data;
 1437: 
 1438: 	/* XXX Should we do FLAG_A ?  */
 1439: 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
 1440: 					ISAKMP_FLAG_E);
 1441: 	vfree(payload);
 1442: 
 1443: 	plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
 1444: 
 1445: 	/* Should we mark tunnel as active ? */
 1446: 	return error;
 1447: }
 1448: 
 1449: static int
 1450: isakmp_info_recv_r_u_ack (iph1, ru, msgid)
 1451: 	struct ph1handle *iph1;
 1452: 	struct isakmp_pl_ru *ru;
 1453: 	u_int32_t msgid;
 1454: {
 1455: 	u_int32_t seq;
 1456: 
 1457: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 1458: 		 "DPD R-U-There-Ack received\n");
 1459: 
 1460: 	seq = ntohl(ru->data);
 1461: 	if (seq <= iph1->dpd_last_ack || seq > iph1->dpd_seq) {
 1462: 		plog(LLV_ERROR, LOCATION, iph1->remote,
 1463: 			 "Wrong DPD sequence number (%d; last_ack=%d, seq=%d).\n", 
 1464: 			 seq, iph1->dpd_last_ack, iph1->dpd_seq);
 1465: 		return 0;
 1466: 	}
 1467: 
 1468: 	if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
 1469: 	    memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
 1470: 		plog(LLV_ERROR, LOCATION, iph1->remote,
 1471: 			 "Cookie mismatch in DPD ACK!.\n");
 1472: 		return 0;
 1473: 	}
 1474: 
 1475: 	iph1->dpd_fails = 0;
 1476: 	iph1->dpd_last_ack = seq;
 1477: 	sched_cancel(&iph1->dpd_r_u);
 1478: 	isakmp_sched_r_u(iph1, 0);
 1479: 
 1480: 	plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
 1481: 
 1482: 	return 0;
 1483: }
 1484: 
 1485: 
 1486: 
 1487: 
 1488: /*
 1489:  * send DPD R-U-THERE payload in Informational exchange.
 1490:  */
 1491: static void
 1492: isakmp_info_send_r_u(sc)
 1493: 	struct sched *sc;
 1494: {
 1495: 	struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u);
 1496: 
 1497: 	/* create R-U-THERE payload */
 1498: 	struct isakmp_pl_ru *ru;
 1499: 	vchar_t *payload = NULL;
 1500: 	int tlen;
 1501: 	int error = 0;
 1502: 
 1503: 	plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
 1504: 
 1505: 	if (iph1->status == PHASE1ST_EXPIRED) {
 1506: 		/* This can happen after removing tunnels from the
 1507: 		 * config file and then reloading.
 1508: 		 * Such iph1 have rmconf=NULL, so return before the if
 1509: 		 * block below.
 1510: 		 */
 1511: 		return;
 1512: 	}
 1513: 
 1514: 	if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
 1515: 
 1516: 		plog(LLV_INFO, LOCATION, iph1->remote,
 1517: 			"DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n",
 1518: 			isakmp_pindex(&iph1->index, 0));
 1519: 
 1520: 		script_hook(iph1, SCRIPT_PHASE1_DEAD);
 1521: 		evt_phase1(iph1, EVT_PHASE1_DPD_TIMEOUT, NULL);
 1522: 		purge_remote(iph1);
 1523: 
 1524: 		/* Do not reschedule here: phase1 is deleted,
 1525: 		 * DPD will be reactivated when a new ph1 will be negociated
 1526: 		 */
 1527: 		return;
 1528: 	}
 1529: 
 1530: 	/* TODO: check recent activity to avoid useless sends... */
 1531: 
 1532: 	tlen = sizeof(*ru);
 1533: 	payload = vmalloc(tlen);
 1534: 	if (payload == NULL) {
 1535: 		plog(LLV_ERROR, LOCATION, NULL, 
 1536: 			 "failed to get buffer for payload.\n");
 1537: 		return;
 1538: 	}
 1539: 	ru = (struct isakmp_pl_ru *)payload->v;
 1540: 	ru->h.np = ISAKMP_NPTYPE_NONE;
 1541: 	ru->h.len = htons(tlen);
 1542: 	ru->doi = htonl(IPSEC_DOI);
 1543: 	ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
 1544: 	ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
 1545: 	ru->spi_size = sizeof(isakmp_index);
 1546: 
 1547: 	memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
 1548: 	memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
 1549: 
 1550: 	if (iph1->dpd_seq == 0) {
 1551: 		/* generate a random seq which is not too big */
 1552: 		iph1->dpd_seq = iph1->dpd_last_ack = rand() & 0x0fff;
 1553: 	}
 1554: 
 1555: 	iph1->dpd_seq++;
 1556: 	iph1->dpd_fails++;
 1557: 	ru->data = htonl(iph1->dpd_seq);
 1558: 
 1559: 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
 1560: 	vfree(payload);
 1561: 
 1562: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 1563: 		 "DPD R-U-There sent (%d)\n", error);
 1564: 
 1565: 	/* Reschedule the r_u_there with a short delay,
 1566: 	 * will be deleted/rescheduled if ACK received before */
 1567: 	isakmp_sched_r_u(iph1, 1);
 1568: 
 1569: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 1570: 		 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
 1571: }
 1572: 
 1573: /* Schedule a new R-U-THERE */
 1574: int
 1575: isakmp_sched_r_u(iph1, retry)
 1576: 	struct ph1handle *iph1;
 1577: 	int retry;
 1578: {
 1579: 	if(iph1 == NULL ||
 1580: 	   iph1->rmconf == NULL)
 1581: 		return 1;
 1582: 
 1583: 
 1584: 	if(iph1->dpd_support == 0 ||
 1585: 	   iph1->rmconf->dpd_interval == 0)
 1586: 		return 0;
 1587: 
 1588: 	if(retry)
 1589: 		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry,
 1590: 			       isakmp_info_send_r_u);
 1591: 	else
 1592: 		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval,
 1593: 			       isakmp_info_send_r_u);
 1594: 
 1595: 	return 0;
 1596: }
 1597: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>