xref: /openbsd-src/sbin/isakmpd/exchange.c (revision 2f1aa25b0f696ec888d7fe80b22e760eed552d21)
1*2f1aa25bSmpi /* $OpenBSD: exchange.c,v 1.142 2018/01/15 09:54:48 mpi Exp $	 */
272c6dfaeSniklas /* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $	 */
32040585eSniklas 
42040585eSniklas /*
542af7185Sniklas  * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist.  All rights reserved.
642af7185Sniklas  * Copyright (c) 1999, 2001 Angelos D. Keromytis.  All rights reserved.
7d6351a66Sho  * Copyright (c) 1999, 2000, 2002 H�kan Olsson.  All rights reserved.
82040585eSniklas  *
92040585eSniklas  * Redistribution and use in source and binary forms, with or without
102040585eSniklas  * modification, are permitted provided that the following conditions
112040585eSniklas  * are met:
122040585eSniklas  * 1. Redistributions of source code must retain the above copyright
132040585eSniklas  *    notice, this list of conditions and the following disclaimer.
142040585eSniklas  * 2. Redistributions in binary form must reproduce the above copyright
152040585eSniklas  *    notice, this list of conditions and the following disclaimer in the
162040585eSniklas  *    documentation and/or other materials provided with the distribution.
172040585eSniklas  *
182040585eSniklas  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
192040585eSniklas  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
202040585eSniklas  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
212040585eSniklas  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
222040585eSniklas  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
232040585eSniklas  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242040585eSniklas  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252040585eSniklas  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262040585eSniklas  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
272040585eSniklas  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282040585eSniklas  */
292040585eSniklas 
302040585eSniklas /*
312040585eSniklas  * This code was written under funding by Ericsson Radio Systems.
322040585eSniklas  */
332040585eSniklas 
342040585eSniklas #include <sys/types.h>
352b81057dSniklas #include <sys/socket.h>
362b81057dSniklas #include <netinet/in.h>
372b81057dSniklas #include <arpa/inet.h>
382040585eSniklas #include <stdlib.h>
392040585eSniklas #include <string.h>
4092d6a220Shshoexer #include <regex.h>
4192d6a220Shshoexer #include <keynote.h>
422040585eSniklas 
432040585eSniklas #include "cert.h"
442b81057dSniklas #include "conf.h"
45ec172ef8Sniklas #include "connection.h"
462040585eSniklas #include "constants.h"
472040585eSniklas #include "cookie.h"
482040585eSniklas #include "crypto.h"
492040585eSniklas #include "doi.h"
502040585eSniklas #include "exchange.h"
512b81057dSniklas #include "ipsec_num.h"
522040585eSniklas #include "isakmp.h"
533b43e3b6Sniklas #include "isakmp_cfg.h"
54867bc2a7Sniklas #include "libcrypto.h"
552040585eSniklas #include "log.h"
562040585eSniklas #include "message.h"
572040585eSniklas #include "timer.h"
582b81057dSniklas #include "transport.h"
5980f73593Sniklas #include "ipsec.h"
602040585eSniklas #include "sa.h"
6114f1d06aSmpf #include "ui.h"
622040585eSniklas #include "util.h"
6300b1b4a9Sangelos #include "key.h"
64a31e0ec4Smarkus #include "dpd.h"
652040585eSniklas 
662040585eSniklas /* Initial number of bits from the cookies used as hash.  */
672040585eSniklas #define INITIAL_BUCKET_BITS 6
682040585eSniklas 
692040585eSniklas /*
702040585eSniklas  * Don't try to use more bits than this as a hash.
712040585eSniklas  * We only XOR 16 bits so going above that means changing the code below
722040585eSniklas  * too.
732040585eSniklas  */
742040585eSniklas #define MAX_BUCKET_BITS 16
752040585eSniklas 
762040585eSniklas static void     exchange_dump(char *, struct exchange *);
7722819a49Sniklas static void     exchange_free_aux(void *);
78cc6cc03eSho static struct exchange *exchange_lookup_active(char *, int);
792040585eSniklas 
80baf9095eShshoexer static
LIST_HEAD(exchange_list,exchange)81baf9095eShshoexer LIST_HEAD(exchange_list, exchange) *exchange_tab;
822040585eSniklas 
832040585eSniklas /* Works both as a maximum index and a mask.  */
842040585eSniklas static int      bucket_mask;
852040585eSniklas 
862040585eSniklas /*
872040585eSniklas  * Validation scripts used to test messages for correct content of
882040585eSniklas  * payloads depending on the exchange type.
892040585eSniklas  */
902040585eSniklas int16_t script_base[] = {
912040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Initiator -> responder.  */
922040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
932040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
942040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Responder -> initiator.  */
952040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
962040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
972040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,	/* Initiator -> responder.  */
982040585eSniklas 	ISAKMP_PAYLOAD_ID,
992040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1002040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1012040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,	/* Responder -> initiator.  */
1022040585eSniklas 	ISAKMP_PAYLOAD_ID,
1032040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1042040585eSniklas 	EXCHANGE_SCRIPT_END
1052040585eSniklas };
1062040585eSniklas 
1072040585eSniklas int16_t script_identity_protection[] = {
1082040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Initiator -> responder.  */
1092040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1102040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Responder -> initiator.  */
1112040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1122040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,	/* Initiator -> responder.  */
1132040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1142040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1152040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,	/* Responder -> initiator.  */
1162040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1172040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1182040585eSniklas 	ISAKMP_PAYLOAD_ID,	/* Initiator -> responder.  */
1192040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1202040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1212040585eSniklas 	ISAKMP_PAYLOAD_ID,	/* Responder -> initiator.  */
1222040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1232040585eSniklas 	EXCHANGE_SCRIPT_END
1242040585eSniklas };
1252040585eSniklas 
1262040585eSniklas int16_t script_authentication_only[] = {
1272040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Initiator -> responder.  */
1282040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1292040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1302040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Responder -> initiator.  */
1312040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1322040585eSniklas 	ISAKMP_PAYLOAD_ID,
1332040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1342040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1352040585eSniklas 	ISAKMP_PAYLOAD_ID,	/* Initiator -> responder.  */
1362040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1372040585eSniklas 	EXCHANGE_SCRIPT_END
1382040585eSniklas };
1392040585eSniklas 
1402040585eSniklas int16_t script_aggressive[] = {
1412040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Initiator -> responder.  */
1422040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,
1432040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1442040585eSniklas 	ISAKMP_PAYLOAD_ID,
1452040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1462040585eSniklas 	ISAKMP_PAYLOAD_SA,	/* Responder -> initiator.  */
1472040585eSniklas 	ISAKMP_PAYLOAD_KEY_EXCH,
1482040585eSniklas 	ISAKMP_PAYLOAD_NONCE,
1492040585eSniklas 	ISAKMP_PAYLOAD_ID,
1502040585eSniklas 	EXCHANGE_SCRIPT_AUTH,
1512040585eSniklas 	EXCHANGE_SCRIPT_SWITCH,
1522040585eSniklas 	EXCHANGE_SCRIPT_AUTH,	/* Initiator -> responder.  */
1532040585eSniklas 	EXCHANGE_SCRIPT_END
1542040585eSniklas };
1552040585eSniklas 
1562040585eSniklas int16_t script_informational[] = {
1572040585eSniklas 	EXCHANGE_SCRIPT_INFO,	/* Initiator -> responder.  */
1582040585eSniklas 	EXCHANGE_SCRIPT_END
1592040585eSniklas };
1602040585eSniklas 
1612040585eSniklas /*
1622040585eSniklas  * Check what exchange SA is negotiated with and return a suitable validation
1632040585eSniklas  * script.
1642040585eSniklas  */
165b26670e8Sho int16_t *
exchange_script(struct exchange * exchange)1662040585eSniklas exchange_script(struct exchange *exchange)
1672040585eSniklas {
168baf9095eShshoexer 	switch (exchange->type) {
1692040585eSniklas 	case ISAKMP_EXCH_BASE:
1702040585eSniklas 		return script_base;
1712040585eSniklas 	case ISAKMP_EXCH_ID_PROT:
1722040585eSniklas 		return script_identity_protection;
1732040585eSniklas 	case ISAKMP_EXCH_AUTH_ONLY:
1742040585eSniklas 		return script_authentication_only;
1752040585eSniklas 	case ISAKMP_EXCH_AGGRESSIVE:
1762040585eSniklas 		return script_aggressive;
1772040585eSniklas 	case ISAKMP_EXCH_INFO:
1782040585eSniklas 		return script_informational;
1793b43e3b6Sniklas 	case ISAKMP_EXCH_TRANSACTION:
1803b43e3b6Sniklas 		return script_transaction;
1812040585eSniklas 	default:
1829d6bd3cfSderaadt 		if (exchange->type >= ISAKMP_EXCH_DOI_MIN)
1832040585eSniklas 			return exchange->doi->exchange_script(exchange->type);
1842040585eSniklas 	}
1852040585eSniklas 	return 0;
1862040585eSniklas }
1872040585eSniklas 
1882040585eSniklas /*
1892040585eSniklas  * Validate the message MSG's contents wrt what payloads the exchange type
1905678a57aShshoexer  * requires at this point in the dialogue.  Return -1 if the validation fails,
1912040585eSniklas  * 0 if it succeeds and the script is not finished and 1 if it's ready.
1922040585eSniklas  */
1932040585eSniklas static int
exchange_validate(struct message * msg)1942040585eSniklas exchange_validate(struct message *msg)
1952040585eSniklas {
1962040585eSniklas 	struct exchange *exchange = msg->exchange;
1972040585eSniklas 	int16_t		*pc = exchange->exch_pc;
1982040585eSniklas 
199baf9095eShshoexer 	while (*pc != EXCHANGE_SCRIPT_END && *pc != EXCHANGE_SCRIPT_SWITCH) {
20051ca15aeSniklas 		LOG_DBG((LOG_EXCHANGE, 90,
201172c7fecSniklas 		    "exchange_validate: checking for required %s",
2022040585eSniklas 		    *pc >= ISAKMP_PAYLOAD_NONE
2032040585eSniklas 		    ? constant_name(isakmp_payload_cst, *pc)
20451ca15aeSniklas 		    : constant_name(exchange_script_cst, *pc)));
2052040585eSniklas 
2062040585eSniklas 		/* Check for existence of the required payloads.  */
2079d6bd3cfSderaadt 		if ((*pc > 0 && !payload_first(msg, *pc)) ||
2089d6bd3cfSderaadt 		    (*pc == EXCHANGE_SCRIPT_AUTH &&
2099d6bd3cfSderaadt 		    !payload_first(msg, ISAKMP_PAYLOAD_HASH) &&
2109d6bd3cfSderaadt 		    !payload_first(msg, ISAKMP_PAYLOAD_SIG)) ||
2119d6bd3cfSderaadt 		    (*pc == EXCHANGE_SCRIPT_INFO &&
2129d6bd3cfSderaadt 		    ((!payload_first(msg, ISAKMP_PAYLOAD_NOTIFY) &&
2139d6bd3cfSderaadt 		    !payload_first(msg, ISAKMP_PAYLOAD_DELETE)) ||
2149d6bd3cfSderaadt 		    (payload_first(msg, ISAKMP_PAYLOAD_DELETE) &&
2159d6bd3cfSderaadt 		    !payload_first(msg, ISAKMP_PAYLOAD_HASH))))) {
2162040585eSniklas 			/* Missing payload.  */
21751ca15aeSniklas 			LOG_DBG((LOG_MESSAGE, 70,
218baf9095eShshoexer 			    "exchange_validate: msg %p requires missing %s",
219baf9095eShshoexer 			    msg, *pc >= ISAKMP_PAYLOAD_NONE
2202040585eSniklas 			    ? constant_name(isakmp_payload_cst, *pc)
22151ca15aeSniklas 			    : constant_name(exchange_script_cst, *pc)));
2222040585eSniklas 			return -1;
2232040585eSniklas 		}
2242040585eSniklas 		pc++;
2252040585eSniklas 	}
2262040585eSniklas 	if (*pc == EXCHANGE_SCRIPT_END)
2272040585eSniklas 		/* Cleanup.  */
2282040585eSniklas 		return 1;
2292040585eSniklas 
2302040585eSniklas 	return 0;
2312040585eSniklas }
2322040585eSniklas 
233cc6cc03eSho /* Feed unhandled payloads to the DOI for handling. Help for exchange_run(). */
234cc6cc03eSho static void
exchange_handle_leftover_payloads(struct message * msg)235cc6cc03eSho exchange_handle_leftover_payloads(struct message *msg)
236cc6cc03eSho {
237cc6cc03eSho 	struct exchange *exchange = msg->exchange;
238cc6cc03eSho 	struct doi	*doi = exchange->doi;
239cc6cc03eSho 	struct payload	*p;
240cc6cc03eSho 	int	i;
241cc6cc03eSho 
242cc3c17beShshoexer 	for (i = ISAKMP_PAYLOAD_SA; i < ISAKMP_PAYLOAD_MAX; i++) {
243cc6cc03eSho 		if (i == ISAKMP_PAYLOAD_PROPOSAL ||
244cc6cc03eSho 		    i == ISAKMP_PAYLOAD_TRANSFORM)
245cc6cc03eSho 			continue;
246ed76d6b8Shshoexer 		TAILQ_FOREACH(p, &msg->payload[i], link) {
247cc6cc03eSho 			if (p->flags & PL_MARK)
248cc6cc03eSho 				continue;
249cc6cc03eSho 			if (!doi->handle_leftover_payload ||
250cc6cc03eSho 			    doi->handle_leftover_payload(msg, i, p))
251cc6cc03eSho 				LOG_DBG((LOG_EXCHANGE, 10,
2529aa1bed2Shshoexer 				    "exchange_handle_leftover_payloads: "
2539aa1bed2Shshoexer 				    "unexpected payload %s",
254cc6cc03eSho 				    constant_name(isakmp_payload_cst, i)));
255cc6cc03eSho 		}
256cc6cc03eSho 	}
257cc6cc03eSho }
258cc6cc03eSho 
2592040585eSniklas /*
2602040585eSniklas  * Run the exchange script from a point given by the "program counter"
2612040585eSniklas  * upto either the script's end or a transmittal of a message.  If we are
2622040585eSniklas  * at the point of a reception of a message, that message should be handed
2632040585eSniklas  * in here in the MSG argument.  Otherwise we are the initiator and should
2642040585eSniklas  * expect MSG to be a half-cooked message without payloads.
2652040585eSniklas  */
2662040585eSniklas void
exchange_run(struct message * msg)2672040585eSniklas exchange_run(struct message *msg)
2682040585eSniklas {
2692040585eSniklas 	struct exchange *exchange = msg->exchange;
27022819a49Sniklas 	struct doi	*doi = exchange->doi;
271baf9095eShshoexer 	int             (*handler)(struct message *) = exchange->initiator ?
272baf9095eShshoexer 			    doi->initiator : doi->responder;
273cc6cc03eSho 	int              done = 0;
2742040585eSniklas 
275baf9095eShshoexer 	while (!done) {
2762040585eSniklas 		/*
2772040585eSniklas 		 * It's our turn if we're either the initiator on an even step,
2782040585eSniklas 		 * or the responder on an odd step of the dialogue.
2792040585eSniklas 		 */
280baf9095eShshoexer 		if (exchange->initiator ^ (exchange->step % 2)) {
2812040585eSniklas 			done = 1;
2822040585eSniklas 			if (exchange->step)
2832040585eSniklas 				msg = message_alloc_reply(msg);
284baf9095eShshoexer 			message_setup_header(msg, exchange->type, 0,
285baf9095eShshoexer 			    exchange->message_id);
286baf9095eShshoexer 			if (handler(msg)) {
2872040585eSniklas 				/*
288baf9095eShshoexer 				 * This can happen when transient starvation
289baf9095eShshoexer 				 * of memory occurs.
290baf9095eShshoexer 				 * XXX The peer's retransmit ought to
291baf9095eShshoexer 				 * kick-start this exchange again.  If he's
292baf9095eShshoexer 				 * stopped retransmitting he's likely dropped
293baf9095eShshoexer 				 * the SA at his side so we need to do that
294baf9095eShshoexer 				 * too, i.e.  implement automatic SA teardown
295baf9095eShshoexer 				 * after a certain amount of inactivity.
2962040585eSniklas 				 */
29722819a49Sniklas 				log_print("exchange_run: doi->%s (%p) failed",
298baf9095eShshoexer 				    exchange->initiator ? "initiator" :
299baf9095eShshoexer 				    "responder", msg);
3002040585eSniklas 				message_free(msg);
3012040585eSniklas 				return;
3022040585eSniklas 			}
303baf9095eShshoexer 			switch (exchange_validate(msg)) {
3042040585eSniklas 			case 1:
3052040585eSniklas 				/*
306baf9095eShshoexer 				 * The last message of a multi-message
307baf9095eShshoexer 				 * exchange should not be retransmitted other
308baf9095eShshoexer 				 * than "on-demand", i.e. if we see
309baf9095eShshoexer 				 * retransmits of the last message of the peer
31022819a49Sniklas 				 * later.
3112040585eSniklas 				 */
31222819a49Sniklas 				msg->flags |= MSG_LAST;
313baf9095eShshoexer 				if (exchange->step > 0) {
31422819a49Sniklas 					if (exchange->last_sent)
31522819a49Sniklas 						message_free(exchange->last_sent);
31622819a49Sniklas 					exchange->last_sent = msg;
3171d9d87a5Sniklas 				}
3182040585eSniklas 				/*
319baf9095eShshoexer 				 * After we physically have sent our last
320baf9095eShshoexer 				 * message we need to do SA-specific
321baf9095eShshoexer 				 * finalization, like telling our application
322baf9095eShshoexer 				 * the SA is ready to be used, or issuing a
323baf9095eShshoexer 				 * CONNECTED notify if we set the COMMIT bit.
3242040585eSniklas 				 */
325cc6cc03eSho 				message_register_post_send(msg,
326cc6cc03eSho 				    exchange_finalize);
3272040585eSniklas 
32836d3c850Shshoexer 				/* FALLTHROUGH */
3292040585eSniklas 
3302040585eSniklas 			case 0:
33120c653ebSyasuoka 				/*
33220c653ebSyasuoka 				 * Don't retransmit responses for
33320c653ebSyasuoka 				 * unauthenticated messages.
33420c653ebSyasuoka 				 */
33520c653ebSyasuoka 				if ((exchange->type == ISAKMP_EXCH_ID_PROT ||
33620c653ebSyasuoka 				    exchange->type == ISAKMP_EXCH_AGGRESSIVE) &&
33720c653ebSyasuoka 				    exchange->phase == 1 && exchange->step == 1)
33820c653ebSyasuoka 					msg->flags |= MSG_DONTRETRANSMIT;
33920c653ebSyasuoka 
3402040585eSniklas 				/* XXX error handling.  */
3412040585eSniklas 				message_send(msg);
3422040585eSniklas 				break;
3432040585eSniklas 
3442040585eSniklas 			default:
345cc6cc03eSho 				log_print("exchange_run: exchange_validate "
346cc6cc03eSho 				    "failed, DOI error");
3472040585eSniklas 				exchange_free(exchange);
3482040585eSniklas 				message_free(msg);
3492040585eSniklas 				return;
3502040585eSniklas 			}
351baf9095eShshoexer 		} else {
3522040585eSniklas 			done = exchange_validate(msg);
353baf9095eShshoexer 			switch (done) {
3542040585eSniklas 			case 0:
3552040585eSniklas 			case 1:
3562040585eSniklas 				/* Feed the message to the DOI.  */
357baf9095eShshoexer 				if (handler(msg)) {
3582040585eSniklas 					/*
3592040585eSniklas 					 * Trust the peer to retransmit.
360baf9095eShshoexer 					 * XXX We have to implement SA aging
361baf9095eShshoexer 					 * with automatic teardown.
3622040585eSniklas 					 */
3632040585eSniklas 					message_free(msg);
3642040585eSniklas 					return;
3652040585eSniklas 				}
3662040585eSniklas 				/*
367baf9095eShshoexer 				 * Go over the yet unhandled payloads and feed
368baf9095eShshoexer 				 * them to DOI for handling.
3692040585eSniklas 				 */
370cc6cc03eSho 				exchange_handle_leftover_payloads(msg);
3712040585eSniklas 
3722040585eSniklas 				/*
373baf9095eShshoexer 				 * We have advanced the state.  If we have
374baf9095eShshoexer 				 * been processing an incoming message, record
375baf9095eShshoexer 				 * that message as the one to do duplication
376baf9095eShshoexer 				 * tests against.
3772040585eSniklas 				 */
3782040585eSniklas 				if (exchange->last_received)
3792040585eSniklas 					message_free(exchange->last_received);
3802040585eSniklas 				exchange->last_received = msg;
3812040585eSniklas 				if (exchange->flags & EXCHANGE_FLAG_ENCRYPT)
3822040585eSniklas 					crypto_update_iv(exchange->keystate);
3832040585eSniklas 
384baf9095eShshoexer 				if (done) {
3852040585eSniklas 					exchange_finalize(msg);
3862040585eSniklas 					return;
3872040585eSniklas 				}
3882040585eSniklas 				break;
3892040585eSniklas 
3902040585eSniklas 			case -1:
391cc6cc03eSho 				log_print("exchange_run: exchange_validate "
392cc6cc03eSho 				    "failed");
393baf9095eShshoexer 				/*
394baf9095eShshoexer 				 * XXX Is this the best error notification
395baf9095eShshoexer 				 * type?
396baf9095eShshoexer 				 */
397cc6cc03eSho 				message_drop(msg,
398cc6cc03eSho 				    ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 1);
3992040585eSniklas 				return;
4002040585eSniklas 			}
4012040585eSniklas 		}
4022040585eSniklas 
40351ca15aeSniklas 		LOG_DBG((LOG_EXCHANGE, 40,
404fd37c001Sniklas 		    "exchange_run: exchange %p finished step %d, advancing...",
40551ca15aeSniklas 		    exchange, exchange->step));
4062040585eSniklas 		exchange->step++;
4079d6bd3cfSderaadt 		while (*exchange->exch_pc != EXCHANGE_SCRIPT_SWITCH &&
4089d6bd3cfSderaadt 		    *exchange->exch_pc != EXCHANGE_SCRIPT_END)
4092040585eSniklas 			exchange->exch_pc++;
4102040585eSniklas 		exchange->exch_pc++;
4112040585eSniklas 	}
4122040585eSniklas }
4132040585eSniklas 
4142040585eSniklas void
exchange_init(void)4151616f820Sderaadt exchange_init(void)
4162040585eSniklas {
4172040585eSniklas 	int	i;
4182040585eSniklas 
4192040585eSniklas 	bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
420bfdaf066Sderaadt 	exchange_tab = calloc(bucket_mask + 1, sizeof(struct exchange_list));
4212040585eSniklas 	if (!exchange_tab)
4222040585eSniklas 		log_fatal("exchange_init: out of memory");
423cc6cc03eSho 	for (i = 0; i <= bucket_mask; i++)
4242040585eSniklas 		LIST_INIT(&exchange_tab[i]);
4252040585eSniklas }
4262040585eSniklas 
4272040585eSniklas /* Lookup a phase 1 exchange out of just the initiator cookie.  */
4282040585eSniklas struct exchange *
exchange_lookup_from_icookie(u_int8_t * cookie)4292040585eSniklas exchange_lookup_from_icookie(u_int8_t *cookie)
4302040585eSniklas {
4312040585eSniklas 	struct exchange *exchange;
432cc6cc03eSho 	int	i;
4332040585eSniklas 
434172c7fecSniklas 	for (i = 0; i <= bucket_mask; i++)
4352040585eSniklas 		for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
4362040585eSniklas 		    exchange = LIST_NEXT(exchange, link))
437baf9095eShshoexer 			if (memcmp(exchange->cookies, cookie,
438cc6cc03eSho 			    ISAKMP_HDR_ICOOKIE_LEN) == 0 &&
439cc6cc03eSho 			    exchange->phase == 1)
4402040585eSniklas 				return exchange;
4412040585eSniklas 	return 0;
4422040585eSniklas }
4432040585eSniklas 
444f5228d8eSniklas /* Lookup an exchange out of the name and phase.  */
445f5228d8eSniklas struct exchange *
exchange_lookup_by_name(char * name,int phase)4462b81057dSniklas exchange_lookup_by_name(char *name, int phase)
4472b81057dSniklas {
4482b81057dSniklas 	struct exchange *exchange;
449cc6cc03eSho 	int	i;
4502b81057dSniklas 
451172c7fecSniklas 	/* If we search for nothing, we will find nothing.  */
452172c7fecSniklas 	if (!name)
453172c7fecSniklas 		return 0;
454172c7fecSniklas 
455172c7fecSniklas 	for (i = 0; i <= bucket_mask; i++)
4562b81057dSniklas 		for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
457baf9095eShshoexer 		    exchange = LIST_NEXT(exchange, link)) {
45851ca15aeSniklas 			LOG_DBG((LOG_EXCHANGE, 90,
459baf9095eShshoexer 			    "exchange_lookup_by_name: %s == %s && %d == %d?",
460baf9095eShshoexer 			    name, exchange->name ? exchange->name :
461baf9095eShshoexer 			    "<unnamed>", phase, exchange->phase));
46222819a49Sniklas 
46322819a49Sniklas 			/*
464baf9095eShshoexer 			 * Match by name, but don't select finished exchanges,
465baf9095eShshoexer 			 * i.e where MSG_LAST are set in last_sent msg.
46622819a49Sniklas 			 */
467cc6cc03eSho 			if (exchange->name &&
468cc6cc03eSho 			    strcasecmp(exchange->name, name) == 0 &&
469cc6cc03eSho 			    exchange->phase == phase &&
470cc6cc03eSho 			    (!exchange->last_sent ||
471cc6cc03eSho 				(exchange->last_sent->flags & MSG_LAST) == 0))
4722b81057dSniklas 				return exchange;
473a06203bdSniklas 		}
4742b81057dSniklas 	return 0;
4752b81057dSniklas }
4762b81057dSniklas 
477172c7fecSniklas /* Lookup an exchange out of the name, phase and step > 1.  */
4784c8c122bSho static struct exchange *
exchange_lookup_active(char * name,int phase)479172c7fecSniklas exchange_lookup_active(char *name, int phase)
480172c7fecSniklas {
481172c7fecSniklas 	struct exchange *exchange;
482cc6cc03eSho 	int	i;
483172c7fecSniklas 
48422819a49Sniklas 	/* XXX Almost identical to exchange_lookup_by_name.  */
485172c7fecSniklas 
486172c7fecSniklas 	if (!name)
487172c7fecSniklas 		return 0;
488172c7fecSniklas 
489172c7fecSniklas 	for (i = 0; i <= bucket_mask; i++)
490172c7fecSniklas 		for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
491baf9095eShshoexer 		    exchange = LIST_NEXT(exchange, link)) {
49251ca15aeSniklas 			LOG_DBG((LOG_EXCHANGE, 90,
493172c7fecSniklas 			    "exchange_lookup_active: %s == %s && %d == %d?",
494baf9095eShshoexer 			    name, exchange->name ? exchange->name :
495baf9095eShshoexer 			    "<unnamed>", phase, exchange->phase));
496cc6cc03eSho 			if (exchange->name &&
497cc6cc03eSho 			    strcasecmp(exchange->name, name) == 0 &&
498cc6cc03eSho 			    exchange->phase == phase) {
499172c7fecSniklas 				if (exchange->step > 1)
500172c7fecSniklas 					return exchange;
501172c7fecSniklas 				else
50251ca15aeSniklas 					LOG_DBG((LOG_EXCHANGE, 80,
503cc6cc03eSho 					    "exchange_lookup_active: avoided "
504cc6cc03eSho 					    "early (pre-step 1) exchange %p",
505cc6cc03eSho 					    exchange));
506172c7fecSniklas 			}
507172c7fecSniklas 		}
508172c7fecSniklas 	return 0;
509172c7fecSniklas }
510172c7fecSniklas 
511a06203bdSniklas static void
exchange_enter(struct exchange * exchange)5122040585eSniklas exchange_enter(struct exchange *exchange)
5132040585eSniklas {
5142040585eSniklas 	u_int16_t	bucket = 0;
5152040585eSniklas 	u_int8_t       *cp;
516cc6cc03eSho 	int             i;
5172040585eSniklas 
5182040585eSniklas 	/* XXX We might resize if we are crossing a certain threshold */
5192040585eSniklas 
520baf9095eShshoexer 	for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
5212040585eSniklas 		cp = exchange->cookies + i;
5222040585eSniklas 		/* Doing it this way avoids alignment problems.  */
5232040585eSniklas 		bucket ^= cp[0] | cp[1] << 8;
5242040585eSniklas 	}
525baf9095eShshoexer 	for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
5262040585eSniklas 		cp = exchange->message_id + i;
5272040585eSniklas 		/* Doing it this way avoids alignment problems.  */
5282040585eSniklas 		bucket ^= cp[0] | cp[1] << 8;
5292040585eSniklas 	}
5302040585eSniklas 	bucket &= bucket_mask;
5312040585eSniklas 	LIST_INSERT_HEAD(&exchange_tab[bucket], exchange, link);
53210dd6cf1Smpi 	exchange->linked = 1;
5332040585eSniklas }
5342040585eSniklas 
5352040585eSniklas /*
5362040585eSniklas  * Lookup the exchange given by the header fields MSG.  PHASE2 is false when
5372040585eSniklas  * looking for phase 1 exchanges and true otherwise.
5382040585eSniklas  */
5392040585eSniklas struct exchange *
exchange_lookup(u_int8_t * msg,int phase2)5402040585eSniklas exchange_lookup(u_int8_t *msg, int phase2)
5412040585eSniklas {
5422040585eSniklas 	struct exchange *exchange;
543cc6cc03eSho 	u_int16_t       bucket = 0;
5442040585eSniklas 	u_int8_t       *cp;
545cc6cc03eSho 	int             i;
5462040585eSniklas 
5472040585eSniklas 	/*
548cc6cc03eSho 	 * We use the cookies to get bits to use as an index into exchange_tab,
549cc6cc03eSho 	 * as at least one (our cookie) is a good hash, xoring all the bits,
550cc6cc03eSho 	 * 16 at a time, and then masking, should do.  Doing it this way means
551cc6cc03eSho 	 * we can validate cookies very fast thus delimiting the effects of
552cc6cc03eSho 	 * "Denial of service"-attacks using packet flooding.
5532040585eSniklas 	 */
554baf9095eShshoexer 	for (i = 0; i < ISAKMP_HDR_COOKIES_LEN; i += 2) {
5552040585eSniklas 		cp = msg + ISAKMP_HDR_COOKIES_OFF + i;
5562040585eSniklas 		/* Doing it this way avoids alignment problems.  */
5572040585eSniklas 		bucket ^= cp[0] | cp[1] << 8;
5582040585eSniklas 	}
5592040585eSniklas 	if (phase2)
560baf9095eShshoexer 		for (i = 0; i < ISAKMP_HDR_MESSAGE_ID_LEN; i += 2) {
5612040585eSniklas 			cp = msg + ISAKMP_HDR_MESSAGE_ID_OFF + i;
5622040585eSniklas 			/* Doing it this way avoids alignment problems.  */
5632040585eSniklas 			bucket ^= cp[0] | cp[1] << 8;
5642040585eSniklas 		}
5652040585eSniklas 	bucket &= bucket_mask;
5662040585eSniklas 	for (exchange = LIST_FIRST(&exchange_tab[bucket]);
567cc6cc03eSho 	    exchange && (memcmp(msg + ISAKMP_HDR_COOKIES_OFF,
568cc6cc03eSho 		exchange->cookies, ISAKMP_HDR_COOKIES_LEN) != 0 ||
569cc6cc03eSho 		(phase2 && memcmp(msg + ISAKMP_HDR_MESSAGE_ID_OFF,
570cc6cc03eSho 		    exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN) != 0) ||
571cc6cc03eSho 		(!phase2 && !zero_test(msg + ISAKMP_HDR_MESSAGE_ID_OFF,
5722b81057dSniklas 		    ISAKMP_HDR_MESSAGE_ID_LEN)));
5732040585eSniklas 	    exchange = LIST_NEXT(exchange, link))
5742040585eSniklas 		;
5752040585eSniklas 
5762040585eSniklas 	return exchange;
5772040585eSniklas }
5782040585eSniklas 
5792040585eSniklas /*
5802040585eSniklas  * Create a phase PHASE exchange where INITIATOR denotes our role.  DOI
5812040585eSniklas  * is the domain of interpretation identifier and TYPE tells what exchange
5822040585eSniklas  * type to use per either the DOI document or the ISAKMP spec proper.
5832040585eSniklas  * NSA tells how many SAs we should pre-allocate, and should be zero
5842040585eSniklas  * when we have the responder role.
5852040585eSniklas  */
5862040585eSniklas static struct exchange *
exchange_create(int phase,int initiator,int doi,int type)5872040585eSniklas exchange_create(int phase, int initiator, int doi, int type)
5882040585eSniklas {
5892040585eSniklas 	struct exchange *exchange;
5906ee513e5Sjca 	struct timespec	 expiration;
5912b81057dSniklas 	int	delta;
5922040585eSniklas 
5932040585eSniklas 	/*
59422819a49Sniklas 	 * We want the exchange zeroed for exchange_free to be able to find
59522819a49Sniklas 	 * out what fields have been filled-in.
5962040585eSniklas 	 */
5972040585eSniklas 	exchange = calloc(1, sizeof *exchange);
598baf9095eShshoexer 	if (!exchange) {
5997eb3b581Sderaadt 		log_error("exchange_create: calloc (1, %lu) failed",
6007eb3b581Sderaadt 		    (unsigned long)sizeof *exchange);
6012040585eSniklas 		return 0;
60224d2f2e1Sniklas 	}
6032040585eSniklas 	exchange->phase = phase;
6042040585eSniklas 	exchange->step = 0;
6052040585eSniklas 	exchange->initiator = initiator;
6060dc10397Shshoexer 	bzero(exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
6070dc10397Shshoexer 	bzero(exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
6082040585eSniklas 	exchange->doi = doi_lookup(doi);
6092040585eSniklas 	exchange->type = type;
61032f522cdSniklas 	exchange->policy_id = -1;
6112040585eSniklas 	exchange->exch_pc = exchange_script(exchange);
6122040585eSniklas 	exchange->last_sent = exchange->last_received = 0;
6132040585eSniklas 	TAILQ_INIT(&exchange->sa_list);
6142040585eSniklas 	TAILQ_INIT(&exchange->aca_list);
6152040585eSniklas 
6162040585eSniklas 	/* Allocate the DOI-specific structure and initialize it to zeroes.  */
617baf9095eShshoexer 	if (exchange->doi->exchange_size) {
6182040585eSniklas 		exchange->data = calloc(1, exchange->doi->exchange_size);
619baf9095eShshoexer 		if (!exchange->data) {
6207eb3b581Sderaadt 			log_error("exchange_create: calloc (1, %lu) failed",
6217eb3b581Sderaadt 			    (unsigned long)exchange->doi->exchange_size);
6222040585eSniklas 			exchange_free(exchange);
6232040585eSniklas 			return 0;
6242040585eSniklas 		}
6259bfbb31eSniklas 	}
6266ee513e5Sjca 	clock_gettime(CLOCK_MONOTONIC, &expiration);
627cc6cc03eSho 	delta = conf_get_num("General", "Exchange-max-time",
628cc6cc03eSho 	    EXCHANGE_MAX_TIME);
6292b81057dSniklas 	expiration.tv_sec += delta;
630cc6cc03eSho 	exchange->death = timer_add_event("exchange_free_aux",
631cc6cc03eSho 	    exchange_free_aux, exchange, &expiration);
632baf9095eShshoexer 	if (!exchange->death) {
6332040585eSniklas 		/* If we don't give up we might start leaking...  */
63422819a49Sniklas 		exchange_free_aux(exchange);
6352040585eSniklas 		return 0;
6362040585eSniklas 	}
6372040585eSniklas 	return exchange;
6382040585eSniklas }
6392040585eSniklas 
640baf9095eShshoexer struct exchange_finalization_node {
641172c7fecSniklas 	void	(*first)(struct exchange *, void *, int);
642a06203bdSniklas 	void	*first_arg;
643172c7fecSniklas 	void	(*second)(struct exchange *, void *, int);
644a06203bdSniklas 	void	*second_arg;
645a06203bdSniklas };
646a06203bdSniklas 
647a06203bdSniklas /* Run the finalization functions of ARG.  */
648a06203bdSniklas static void
exchange_run_finalizations(struct exchange * exchange,void * arg,int fail)649172c7fecSniklas exchange_run_finalizations(struct exchange *exchange, void *arg, int fail)
650a06203bdSniklas {
651a06203bdSniklas 	struct exchange_finalization_node *node = arg;
652a06203bdSniklas 
653172c7fecSniklas 	node->first(exchange, node->first_arg, fail);
654172c7fecSniklas 	node->second(exchange, node->second_arg, fail);
655a06203bdSniklas 	free(node);
656a06203bdSniklas }
657a06203bdSniklas 
658a06203bdSniklas /*
659a06203bdSniklas  * Add a finalization function FINALIZE with argument ARG to the tail
660a06203bdSniklas  * of the finalization function list of EXCHANGE.
661a06203bdSniklas  */
662a06203bdSniklas static void
exchange_add_finalization(struct exchange * exchange,void (* finalize)(struct exchange *,void *,int),void * arg)663a06203bdSniklas exchange_add_finalization(struct exchange *exchange,
664baf9095eShshoexer     void (*finalize)(struct exchange *, void *, int), void *arg)
665a06203bdSniklas {
666a06203bdSniklas 	struct exchange_finalization_node *node;
667a06203bdSniklas 
668a06203bdSniklas 	if (!finalize)
669a06203bdSniklas 		return;
670a06203bdSniklas 
671baf9095eShshoexer 	if (!exchange->finalize) {
672a06203bdSniklas 		exchange->finalize = finalize;
673a06203bdSniklas 		exchange->finalize_arg = arg;
674a06203bdSniklas 		return;
675a06203bdSniklas 	}
676a06203bdSniklas 	node = malloc(sizeof *node);
677baf9095eShshoexer 	if (!node) {
6787eb3b581Sderaadt 		log_error("exchange_add_finalization: malloc (%lu) failed",
6797eb3b581Sderaadt 		    (unsigned long)sizeof *node);
680a06203bdSniklas 		free(arg);
681a06203bdSniklas 		return;
682a06203bdSniklas 	}
683a06203bdSniklas 	node->first = exchange->finalize;
684a06203bdSniklas 	node->first_arg = exchange->finalize_arg;
685a06203bdSniklas 	node->second = finalize;
686a06203bdSniklas 	node->second_arg = arg;
687a06203bdSniklas 	exchange->finalize = exchange_run_finalizations;
688a06203bdSniklas 	exchange->finalize_arg = node;
689a06203bdSniklas }
690a06203bdSniklas 
691d6351a66Sho static void
exchange_establish_transaction(struct exchange * exchange,void * arg,int fail)692d6351a66Sho exchange_establish_transaction(struct exchange *exchange, void *arg, int fail)
693d6351a66Sho {
694d6351a66Sho 	/* Establish a TRANSACTION exchange.  */
695baf9095eShshoexer 	struct exchange_finalization_node *node =
696baf9095eShshoexer 	    (struct exchange_finalization_node *)arg;
697d6351a66Sho 	struct sa *isakmp_sa = sa_lookup_by_name((char *) node->second_arg, 1);
698d6351a66Sho 
699d6351a66Sho 	if (isakmp_sa && !fail)
700d6351a66Sho 		exchange_establish_p2(isakmp_sa, ISAKMP_EXCH_TRANSACTION, 0, 0,
701d6351a66Sho 		    node->first, node->first_arg);
702d6351a66Sho 
703d6351a66Sho 	free(node);
704d6351a66Sho }
705d6351a66Sho 
7062040585eSniklas /* Establish a phase 1 exchange.  */
70710dd6cf1Smpi int
exchange_establish_p1(struct transport * t,u_int8_t type,u_int32_t doi,char * name,void * args,void (* finalize)(struct exchange *,void *,int),void * arg,int stayalive)7082040585eSniklas exchange_establish_p1(struct transport *t, u_int8_t type, u_int32_t doi,
709baf9095eShshoexer     char *name, void *args, void (*finalize)(struct exchange *, void *, int),
710a28d886cShshoexer     void *arg, int stayalive)
7112040585eSniklas {
7122040585eSniklas 	struct exchange		*exchange;
7132040585eSniklas 	struct message		*msg;
714d6351a66Sho 	struct conf_list	*flags;
715d6351a66Sho 	struct conf_list_node	*flag;
7162b81057dSniklas 	char	*tag = 0;
7172b81057dSniklas 	char	*str;
7182b81057dSniklas 
719baf9095eShshoexer 	if (name) {
7202b81057dSniklas 		/* If no exchange type given, fetch from the configuration.  */
721baf9095eShshoexer 		if (type == 0) {
722baf9095eShshoexer 			/*
723baf9095eShshoexer 			 * XXX Similar code can be found in
724baf9095eShshoexer 			 * exchange_setup_p1.  Share?
725baf9095eShshoexer 			 */
7262b81057dSniklas 
7272b81057dSniklas 			/* Find out our phase 1 mode.  */
7282b81057dSniklas 			tag = conf_get_str(name, "Configuration");
729baf9095eShshoexer 			if (!tag) {
730419caefeSho 				/* Use default setting.  */
731419caefeSho 				tag = CONF_DFLT_TAG_PHASE1_CONFIG;
7322b81057dSniklas 			}
733f5228d8eSniklas 			/* Figure out the DOI.  XXX Factor out?  */
7342b81057dSniklas 			str = conf_get_str(tag, "DOI");
73532f522cdSniklas 			if (!str || strcasecmp(str, "IPSEC") == 0)
7362b81057dSniklas 				doi = IPSEC_DOI_IPSEC;
73732f522cdSniklas 			else if (strcasecmp(str, "ISAKMP") == 0)
73832f522cdSniklas 				doi = ISAKMP_DOI_ISAKMP;
739baf9095eShshoexer 			else {
740cc6cc03eSho 				log_print("exchange_establish_p1: "
741cc6cc03eSho 				    "DOI \"%s\" unsupported", str);
74210dd6cf1Smpi 				return -1;
7432b81057dSniklas 			}
7442b81057dSniklas 
7452b81057dSniklas 			/* What exchange type do we want?  */
7462b81057dSniklas 			str = conf_get_str(tag, "EXCHANGE_TYPE");
747baf9095eShshoexer 			if (!str) {
7482b81057dSniklas 				log_print("exchange_establish_p1: "
749baf9095eShshoexer 				    "no \"EXCHANGE_TYPE\" tag in [%s] section",
750baf9095eShshoexer 				    tag);
75110dd6cf1Smpi 				return -1;
7522b81057dSniklas 			}
7532b81057dSniklas 			type = constant_value(isakmp_exch_cst, str);
754baf9095eShshoexer 			if (!type) {
7552c0f0c92Shshoexer 				log_print("exchange_establish_p1: "
756cc6cc03eSho 				    "unknown exchange type %s", str);
75710dd6cf1Smpi 				return -1;
7582b81057dSniklas 			}
7592b81057dSniklas 		}
7607f056c7bSniklas 	}
7612040585eSniklas 	exchange = exchange_create(1, 1, doi, type);
762baf9095eShshoexer 	if (!exchange) {
76310dd6cf1Smpi 		return -1;
7642040585eSniklas 	}
765baf9095eShshoexer 	if (name) {
7669bfbb31eSniklas 		exchange->name = strdup(name);
767baf9095eShshoexer 		if (!exchange->name) {
768cc6cc03eSho 			log_error("exchange_establish_p1: "
769cc6cc03eSho 			    "strdup (\"%s\") failed", name);
7702b81057dSniklas 			exchange_free(exchange);
77110dd6cf1Smpi 			return -1;
7722b81057dSniklas 		}
7739bfbb31eSniklas 	}
7742b81057dSniklas 	exchange->policy = name ? conf_get_str(name, "Configuration") : 0;
7750eb823c5Sniklas 	if (!exchange->policy && name)
776419caefeSho 		exchange->policy = CONF_DFLT_TAG_PHASE1_CONFIG;
777c40d7257Sniklas 
778cc6cc03eSho 	if (name && (flags = conf_get_list(name, "Flags")) != NULL) {
779d6351a66Sho 		for (flag = TAILQ_FIRST(&flags->fields); flag;
780d6351a66Sho 		    flag = TAILQ_NEXT(flag, link))
781baf9095eShshoexer 			if (strcasecmp(flag->field, "ikecfg") == 0) {
782d6351a66Sho 				struct exchange_finalization_node *node;
783d6351a66Sho 
784d6351a66Sho 				node = calloc(1, (unsigned long)sizeof *node);
785baf9095eShshoexer 				if (!node) {
786cc6cc03eSho 					log_print("exchange_establish_p1: "
787cc6cc03eSho 					    "calloc (1, %lu) failed",
788d6351a66Sho 					    (unsigned long)sizeof(*node));
789d6351a66Sho 					exchange_free(exchange);
79010dd6cf1Smpi 					return -1;
791d6351a66Sho 				}
792baf9095eShshoexer 				/*
793baf9095eShshoexer 				 * Insert this finalization inbetween
794baf9095eShshoexer 				 * the original.
795baf9095eShshoexer 				 */
796d6351a66Sho 				node->first = finalize;
797d6351a66Sho 				node->first_arg = arg;
798d6351a66Sho 				node->second_arg = name;
799d6351a66Sho 				exchange_add_finalization(exchange,
800d6351a66Sho 				    exchange_establish_transaction,
801d6351a66Sho 				    node);
802d6351a66Sho 				finalize = 0;
803d6351a66Sho 			}
804d6351a66Sho 		conf_free_list(flags);
805d6351a66Sho 	}
806fcd76f45Sho 
807d6351a66Sho 	exchange_add_finalization(exchange, finalize, arg);
8082040585eSniklas 	cookie_gen(t, exchange, exchange->cookies, ISAKMP_HDR_ICOOKIE_LEN);
8092040585eSniklas 	exchange_enter(exchange);
8102040585eSniklas 	exchange_dump("exchange_establish_p1", exchange);
8112040585eSniklas 
8122040585eSniklas 	msg = message_alloc(t, 0, ISAKMP_HDR_SZ);
813baf9095eShshoexer 	if (!msg) {
8145d97d718Sho 		log_print("exchange_establish_p1: message_alloc () failed");
8155d97d718Sho 		exchange_free(exchange);
81610dd6cf1Smpi 		return 0; /* exchange_free() runs finalize */
8175d97d718Sho 	}
8182040585eSniklas 	msg->exchange = exchange;
8192040585eSniklas 
820e0d722f1Sho 	/* Do not create SA for an information or transaction exchange. */
8219d6bd3cfSderaadt 	if (exchange->type != ISAKMP_EXCH_INFO &&
8229d6bd3cfSderaadt 	    exchange->type != ISAKMP_EXCH_TRANSACTION) {
8232040585eSniklas 		/*
824baf9095eShshoexer 		 * Don't install a transport into this SA as it will be an
825baf9095eShshoexer 		 * INADDR_ANY address in the local end, which is not good at
826baf9095eShshoexer 		 * all.  Let the reply packet install the transport instead.
8272040585eSniklas 		 */
8282040585eSniklas 		sa_create(exchange, 0);
8292040585eSniklas 		msg->isakmp_sa = TAILQ_FIRST(&exchange->sa_list);
830baf9095eShshoexer 		if (!msg->isakmp_sa) {
8315d97d718Sho 			message_free(msg);
8322040585eSniklas 			exchange_free(exchange);
83310dd6cf1Smpi 			return 0; /* exchange_free() runs finalize */
8342040585eSniklas 		}
835b36e8b75Sniklas 		sa_reference(msg->isakmp_sa);
836a28d886cShshoexer 
837a28d886cShshoexer 		if (stayalive)
838a28d886cShshoexer 			msg->isakmp_sa->flags |= SA_FLAG_STAYALIVE;
839bd4e5273Sniklas 	}
8402040585eSniklas 	msg->extra = args;
8412040585eSniklas 
8422040585eSniklas 	exchange_run(msg);
84310dd6cf1Smpi 	return 0;
8442040585eSniklas }
8452040585eSniklas 
8462040585eSniklas /* Establish a phase 2 exchange.  XXX With just one SA for now.  */
84710dd6cf1Smpi int
exchange_establish_p2(struct sa * isakmp_sa,u_int8_t type,char * name,void * args,void (* finalize)(struct exchange *,void *,int),void * arg)848a06203bdSniklas exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
849baf9095eShshoexer     void *args, void (*finalize)(struct exchange *, void *, int), void *arg)
8502040585eSniklas {
8512040585eSniklas 	struct exchange *exchange;
8522040585eSniklas 	struct message	*msg;
853a06203bdSniklas 	u_int32_t        doi = ISAKMP_DOI_ISAKMP;
8542bf8caf4Sangelos 	u_int32_t        seq = 0;
855cc6cc03eSho 	int              i;
856cc6cc03eSho 	char		*tag, *str;
857a06203bdSniklas 
8587db938adSniklas 	if (isakmp_sa)
8597db938adSniklas 		doi = isakmp_sa->doi->id;
8607db938adSniklas 
861baf9095eShshoexer 	if (name) {
8622b81057dSniklas 		/* Find out our phase 2 modes.  */
8632b81057dSniklas 		tag = conf_get_str(name, "Configuration");
864baf9095eShshoexer 		if (!tag) {
865cc6cc03eSho 			log_print("exchange_establish_p2: "
866cc6cc03eSho 			    "no configuration for peer \"%s\"", name);
86710dd6cf1Smpi 			return -1;
8682b81057dSniklas 		}
8692bf8caf4Sangelos 		seq = (u_int32_t)conf_get_num(name, "Acquire-ID", 0);
8702bf8caf4Sangelos 
8712b81057dSniklas 		/* Figure out the DOI.  */
8722b81057dSniklas 		str = conf_get_str(tag, "DOI");
87332f522cdSniklas 		if (!str || strcasecmp(str, "IPSEC") == 0)
8742b81057dSniklas 			doi = IPSEC_DOI_IPSEC;
87532f522cdSniklas 		else if (strcasecmp(str, "ISAKMP") == 0)
87632f522cdSniklas 			doi = ISAKMP_DOI_ISAKMP;
877baf9095eShshoexer 		else {
878cc6cc03eSho 			log_print("exchange_establish_p2: "
879cc6cc03eSho 			    "DOI \"%s\" unsupported", str);
88010dd6cf1Smpi 			return -1;
8812b81057dSniklas 		}
8822b81057dSniklas 
8832b81057dSniklas 		/* What exchange type do we want?  */
884baf9095eShshoexer 		if (!type) {
8852b81057dSniklas 			str = conf_get_str(tag, "EXCHANGE_TYPE");
886baf9095eShshoexer 			if (!str) {
8872b81057dSniklas 				log_print("exchange_establish_p2: "
888baf9095eShshoexer 				    "no \"EXCHANGE_TYPE\" tag in [%s] section",
889baf9095eShshoexer 				    tag);
89010dd6cf1Smpi 				return -1;
8912b81057dSniklas 			}
8922b81057dSniklas 			/* XXX IKE dependent.  */
8932b81057dSniklas 			type = constant_value(ike_exch_cst, str);
894baf9095eShshoexer 			if (!type) {
895baf9095eShshoexer 				log_print("exchange_establish_p2: unknown "
896baf9095eShshoexer 				    "exchange type %s", str);
89710dd6cf1Smpi 				return -1;
8982b81057dSniklas 			}
8992b81057dSniklas 		}
900a06203bdSniklas 	}
9012b81057dSniklas 	exchange = exchange_create(2, 1, doi, type);
902baf9095eShshoexer 	if (!exchange) {
90310dd6cf1Smpi 		return -1;
9042040585eSniklas 	}
905baf9095eShshoexer 	if (name) {
9069bfbb31eSniklas 		exchange->name = strdup(name);
907baf9095eShshoexer 		if (!exchange->name) {
908cc6cc03eSho 			log_error("exchange_establish_p2: "
909cc6cc03eSho 			    "strdup (\"%s\") failed", name);
9102b81057dSniklas 			exchange_free(exchange);
91110dd6cf1Smpi 			return -1;
9122b81057dSniklas 		}
9139bfbb31eSniklas 	}
9142b81057dSniklas 	exchange->policy = name ? conf_get_str(name, "Configuration") : 0;
915a06203bdSniklas 	exchange->finalize = finalize;
916a06203bdSniklas 	exchange->finalize_arg = arg;
9172bf8caf4Sangelos 	exchange->seq = seq;
9182040585eSniklas 	memcpy(exchange->cookies, isakmp_sa->cookies, ISAKMP_HDR_COOKIES_LEN);
919baf9c2dbSderaadt 	arc4random_buf(exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
9202040585eSniklas 	exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
921aa584aacSho 	if (isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE)
922aa584aacSho 		exchange->flags |= EXCHANGE_FLAG_NAT_T_ENABLE;
923aa584aacSho 	if (isakmp_sa->flags & SA_FLAG_NAT_T_KEEPALIVE)
924aa584aacSho 		exchange->flags |= EXCHANGE_FLAG_NAT_T_KEEPALIVE;
9252040585eSniklas 	exchange_enter(exchange);
9262040585eSniklas 	exchange_dump("exchange_establish_p2", exchange);
9272040585eSniklas 
928bd4e5273Sniklas 	/*
929bd4e5273Sniklas 	 * Do not create SA's for informational exchanges.
930bd4e5273Sniklas 	 * XXX How to handle new group mode?
931bd4e5273Sniklas 	 */
932c7adf84cSho 	if (exchange->type != ISAKMP_EXCH_INFO &&
933e0d722f1Sho 	    exchange->type != ISAKMP_EXCH_TRANSACTION) {
9342040585eSniklas 		/* XXX Number of SAs should come from the args structure.  */
9352040585eSniklas 		for (i = 0; i < 1; i++)
936baf9095eShshoexer 			if (sa_create(exchange, isakmp_sa->transport)) {
9372040585eSniklas 				exchange_free(exchange);
93810dd6cf1Smpi 				return 0; /* exchange_free() runs finalize */
9392040585eSniklas 			}
940bd4e5273Sniklas 	}
9412040585eSniklas 	msg = message_alloc(isakmp_sa->transport, 0, ISAKMP_HDR_SZ);
9422040585eSniklas 	msg->isakmp_sa = isakmp_sa;
943d19346c1Sniklas 	sa_reference(isakmp_sa);
944bd4e5273Sniklas 
9452040585eSniklas 	msg->extra = args;
9462040585eSniklas 
9472040585eSniklas 	/* This needs to be done late or else get_keystate won't work right. */
9482040585eSniklas 	msg->exchange = exchange;
9492040585eSniklas 
9502040585eSniklas 	exchange_run(msg);
95110dd6cf1Smpi 
95210dd6cf1Smpi 	return 0;
9532040585eSniklas }
9542040585eSniklas 
9552040585eSniklas /* Out of an incoming phase 1 message, setup an exchange.  */
9562040585eSniklas struct exchange *
exchange_setup_p1(struct message * msg,u_int32_t doi)9572040585eSniklas exchange_setup_p1(struct message *msg, u_int32_t doi)
9582040585eSniklas {
9592b81057dSniklas 	struct transport	*t = msg->transport;
9602040585eSniklas 	struct exchange		*exchange;
9612b81057dSniklas 	struct sockaddr		*dst;
9620c6ec862Sho 	struct conf_list	*flags;
9630c6ec862Sho 	struct conf_list_node	*flag;
964107c5904Sho 	char		*name = 0, *policy = 0, *str;
9652b81057dSniklas 	u_int32_t        want_doi;
9662b81057dSniklas 	u_int8_t         type;
9672040585eSniklas 
9682b81057dSniklas 	/* XXX Similar code can be found in exchange_establish_p1.  Share?  */
9692b81057dSniklas 
9704c7a9999Sniklas 	/*
971baf9095eShshoexer 	 * Unless this is an informational exchange, look up our policy for
972baf9095eShshoexer 	 * this peer.
973172c7fecSniklas 	 */
974172c7fecSniklas 	type = GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base);
975baf9095eShshoexer 	if (type != ISAKMP_EXCH_INFO) {
976172c7fecSniklas 		/*
9774c7a9999Sniklas 		 * Find out our inbound phase 1 mode.
9784c7a9999Sniklas 		 */
9793fd8781bSho 		t->vtbl->get_dst(t, &dst);
98077d42baeSniklas 		if (sockaddr2text(dst, &str, 0) == -1)
9813b43e3b6Sniklas 			return 0;
98277d42baeSniklas 		name = conf_get_str("Phase 1", str);
98377d42baeSniklas 		free(str);
984baf9095eShshoexer 		if (name) {
985172c7fecSniklas 			/*
986baf9095eShshoexer 			 * If another phase 1 exchange is ongoing don't bother
987baf9095eShshoexer 			 * returning the call. However, we will need to
988baf9095eShshoexer 			 * continue responding if our phase 1 exchange is
989baf9095eShshoexer 			 * still waiting for step 1 (i.e still half-open).
990172c7fecSniklas 			 */
9917788aeeeSmikeb 			exchange = exchange_lookup_active(name, 1);
9927788aeeeSmikeb 			if (exchange) {
9937788aeeeSmikeb 				LOG_DBG((LOG_EXCHANGE, 40,
9947788aeeeSmikeb 				    "exchange_establish: %s exchange already "
9957788aeeeSmikeb 				    "exists as %p", name, exchange));
996172c7fecSniklas 				return 0;
9977788aeeeSmikeb 			}
998baf9095eShshoexer 		} else {
9992b81057dSniklas 			name = conf_get_str("Phase 1", "Default");
1000baf9095eShshoexer 			if (!name) {
1001baf9095eShshoexer 				log_print("exchange_setup_p1: no \"Default\" "
1002baf9095eShshoexer 				    "tag in [Phase 1] section");
10032b81057dSniklas 				return 0;
10042b81057dSniklas 			}
10052b81057dSniklas 		}
10062b81057dSniklas 
10072b81057dSniklas 		policy = conf_get_str(name, "Configuration");
10082b81057dSniklas 		if (!policy)
1009419caefeSho 			policy = CONF_DFLT_TAG_PHASE1_CONFIG;
10102b81057dSniklas 
10112b81057dSniklas 		/* Figure out the DOI.  */
10122b81057dSniklas 		str = conf_get_str(policy, "DOI");
101396136e5eScloder 		if (!str || strcasecmp(str, "IPSEC") == 0) {
10142b81057dSniklas 			want_doi = IPSEC_DOI_IPSEC;
101596136e5eScloder 			str = "IPSEC";
101696136e5eScloder 		}
101732f522cdSniklas 		else if (strcasecmp(str, "ISAKMP") == 0)
101832f522cdSniklas 			want_doi = ISAKMP_DOI_ISAKMP;
1019baf9095eShshoexer 		else {
1020cc6cc03eSho 			log_print("exchange_setup_p1: "
1021cc6cc03eSho 			    "DOI \"%s\" unsupported", str);
10222b81057dSniklas 			return 0;
10232b81057dSniklas 		}
1024baf9095eShshoexer 		if (want_doi != doi) {
10252b81057dSniklas 			/* XXX Should I tell what DOI I got?  */
10262b81057dSniklas 			log_print("exchange_setup_p1: expected %s DOI", str);
10272b81057dSniklas 			return 0;
10282b81057dSniklas 		}
10292b81057dSniklas 		/* What exchange type do we want?  */
10302b81057dSniklas 		str = conf_get_str(policy, "EXCHANGE_TYPE");
1031baf9095eShshoexer 		if (!str) {
1032baf9095eShshoexer 			log_print("exchange_setup_p1: no \"EXCHANGE_TYPE\" "
1033baf9095eShshoexer 			    "tag in [%s] section", policy);
10342b81057dSniklas 			return 0;
10352b81057dSniklas 		}
10362b81057dSniklas 		type = constant_value(isakmp_exch_cst, str);
1037baf9095eShshoexer 		if (!type) {
1038cc6cc03eSho 			log_print("exchange_setup_p1: "
1039cc6cc03eSho 			    "unknown exchange type %s", str);
10402b81057dSniklas 			return 0;
10412b81057dSniklas 		}
1042baf9095eShshoexer 		if (type != GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base)) {
1043cc6cc03eSho 			log_print("exchange_setup_p1: "
1044cc6cc03eSho 			    "expected exchange type %s got %s", str,
1045cc6cc03eSho 			    constant_name(isakmp_exch_cst,
1046baf9095eShshoexer 				GET_ISAKMP_HDR_EXCH_TYPE(msg->iov[0].iov_base)));
10472b81057dSniklas 			return 0;
10482b81057dSniklas 		}
1049172c7fecSniklas 	}
10502b81057dSniklas 	exchange = exchange_create(1, 0, doi, type);
10512040585eSniklas 	if (!exchange)
10522040585eSniklas 		return 0;
10532b81057dSniklas 
1054172c7fecSniklas 	exchange->name = name ? strdup(name) : 0;
1055baf9095eShshoexer 	if (name && !exchange->name) {
10569bfbb31eSniklas 		log_error("exchange_setup_p1: strdup (\"%s\") failed", name);
10572b81057dSniklas 		exchange_free(exchange);
10582b81057dSniklas 		return 0;
10592b81057dSniklas 	}
10602b81057dSniklas 	exchange->policy = policy;
10610c6ec862Sho 
1062cc6cc03eSho 	if (name && (flags = conf_get_list(name, "Flags")) != NULL) {
10630c6ec862Sho 		for (flag = TAILQ_FIRST(&flags->fields); flag;
10640c6ec862Sho 		    flag = TAILQ_NEXT(flag, link))
1065baf9095eShshoexer 			if (strcasecmp(flag->field, "ikecfg") == 0) {
10660c6ec862Sho 				struct exchange_finalization_node *node;
10670c6ec862Sho 
10680c6ec862Sho 				node = calloc(1, (unsigned long)sizeof *node);
1069baf9095eShshoexer 				if (!node) {
1070cc6cc03eSho 					log_print("exchange_establish_p1: "
1071cc6cc03eSho 					    "calloc (1, %lu) failed",
10720c6ec862Sho 					    (unsigned long)sizeof(*node));
10730c6ec862Sho 					exchange_free(exchange);
10740c6ec862Sho 					return 0;
10750c6ec862Sho 				}
1076baf9095eShshoexer 				/*
1077baf9095eShshoexer 				 * Insert this finalization inbetween
1078baf9095eShshoexer 				 * the original.
1079baf9095eShshoexer 				 */
10800c6ec862Sho 				node->first = 0;
10810c6ec862Sho 				node->first_arg = 0;
10820c6ec862Sho 				node->second_arg = name;
10830c6ec862Sho 				exchange_add_finalization(exchange,
10840c6ec862Sho 				    exchange_establish_transaction,
10850c6ec862Sho 				    node);
10860c6ec862Sho 			}
10870c6ec862Sho 		conf_free_list(flags);
10880c6ec862Sho 	}
1089fcd76f45Sho 
1090baf9095eShshoexer 	cookie_gen(msg->transport, exchange, exchange->cookies +
1091baf9095eShshoexer 	    ISAKMP_HDR_ICOOKIE_LEN, ISAKMP_HDR_RCOOKIE_LEN);
10922040585eSniklas 	GET_ISAKMP_HDR_ICOOKIE(msg->iov[0].iov_base, exchange->cookies);
10932040585eSniklas 	exchange_enter(exchange);
10942040585eSniklas 	exchange_dump("exchange_setup_p1", exchange);
10952040585eSniklas 	return exchange;
10962040585eSniklas }
10972040585eSniklas 
10982040585eSniklas /* Out of an incoming phase 2 message, setup an exchange.  */
10992040585eSniklas struct exchange *
exchange_setup_p2(struct message * msg,u_int8_t doi)11002040585eSniklas exchange_setup_p2(struct message *msg, u_int8_t doi)
11012040585eSniklas {
11022040585eSniklas 	struct exchange *exchange;
11032040585eSniklas 	u_int8_t	*buf = msg->iov[0].iov_base;
11042040585eSniklas 
11052040585eSniklas 	exchange = exchange_create(2, 0, doi, GET_ISAKMP_HDR_EXCH_TYPE(buf));
11062040585eSniklas 	if (!exchange)
11072040585eSniklas 		return 0;
11082040585eSniklas 	GET_ISAKMP_HDR_ICOOKIE(buf, exchange->cookies);
1109cc6cc03eSho 	GET_ISAKMP_HDR_RCOOKIE(buf,
1110cc6cc03eSho 	    exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
11112040585eSniklas 	GET_ISAKMP_HDR_MESSAGE_ID(buf, exchange->message_id);
11124ab75681Shshoexer 	if (msg->isakmp_sa && (msg->isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE))
1113aa584aacSho 		exchange->flags |= EXCHANGE_FLAG_NAT_T_ENABLE;
11144ab75681Shshoexer 	if (msg->isakmp_sa && (msg->isakmp_sa->flags & SA_FLAG_NAT_T_KEEPALIVE))
1115aa584aacSho 		exchange->flags |= EXCHANGE_FLAG_NAT_T_KEEPALIVE;
11162040585eSniklas 	exchange_enter(exchange);
11172040585eSniklas 	exchange_dump("exchange_setup_p2", exchange);
11182040585eSniklas 	return exchange;
11192040585eSniklas }
11202040585eSniklas 
11212b81057dSniklas /* Dump interesting data about an exchange.  */
11222040585eSniklas static void
exchange_dump_real(char * header,struct exchange * exchange,int class,int level)1123172c7fecSniklas exchange_dump_real(char *header, struct exchange *exchange, int class,
1124172c7fecSniklas     int level)
11252040585eSniklas {
1126cc6cc03eSho 	struct sa	*sa;
1127172c7fecSniklas 	char             buf[LOG_SIZE];
1128172c7fecSniklas 	/* Don't risk overflowing the final log buffer.  */
1129c7c448f9Sho 	size_t           bufsize_max = LOG_SIZE - strlen(header) - 32;
1130172c7fecSniklas 
113151ca15aeSniklas 	LOG_DBG((class, level,
11322b81057dSniklas 	    "%s: %p %s %s policy %s phase %d doi %d exchange %d step %d",
1133a06203bdSniklas 	    header, exchange, exchange->name ? exchange->name : "<unnamed>",
1134a06203bdSniklas 	    exchange->policy ? exchange->policy : "<no policy>",
11352b81057dSniklas 	    exchange->initiator ? "initiator" : "responder", exchange->phase,
113651ca15aeSniklas 	    exchange->doi->id, exchange->type, exchange->step));
1137baf9095eShshoexer 	LOG_DBG((class, level, "%s: icookie %08x%08x rcookie %08x%08x", header,
11382040585eSniklas 	    decode_32(exchange->cookies), decode_32(exchange->cookies + 4),
113950eea14cSho 	    decode_32(exchange->cookies + 8),
114050eea14cSho 	    decode_32(exchange->cookies + 12)));
1141172c7fecSniklas 
1142172c7fecSniklas 	/* Include phase 2 SA list for this exchange */
1143baf9095eShshoexer 	if (exchange->phase == 2) {
1144b8380d91Sho 		snprintf(buf, bufsize_max, "sa_list ");
1145172c7fecSniklas 		for (sa = TAILQ_FIRST(&exchange->sa_list);
1146172c7fecSniklas 		    sa && strlen(buf) < bufsize_max; sa = TAILQ_NEXT(sa, next))
1147cc6cc03eSho 			snprintf(buf + strlen(buf), bufsize_max - strlen(buf),
1148cc6cc03eSho 			    "%p ", sa);
1149172c7fecSniklas 		if (sa)
1150b8380d91Sho 			strlcat(buf, "...", bufsize_max);
1151baf9095eShshoexer 	} else
1152172c7fecSniklas 		buf[0] = '\0';
1153172c7fecSniklas 
115451ca15aeSniklas 	LOG_DBG((class, level, "%s: msgid %08x %s", header,
115551ca15aeSniklas 	    decode_32(exchange->message_id), buf));
1156172c7fecSniklas }
1157172c7fecSniklas 
1158172c7fecSniklas static void
exchange_dump(char * header,struct exchange * exchange)1159172c7fecSniklas exchange_dump(char *header, struct exchange *exchange)
1160172c7fecSniklas {
1161172c7fecSniklas 	exchange_dump_real(header, exchange, LOG_EXCHANGE, 10);
11622040585eSniklas }
11632040585eSniklas 
11642040585eSniklas void
exchange_report(void)11652040585eSniklas exchange_report(void)
11662040585eSniklas {
11672040585eSniklas 	struct exchange	*exchange;
1168cc6cc03eSho 	int	i;
11692040585eSniklas 
1170172c7fecSniklas 	for (i = 0; i <= bucket_mask; i++)
11712040585eSniklas 		for (exchange = LIST_FIRST(&exchange_tab[i]); exchange;
11722040585eSniklas 		    exchange = LIST_NEXT(exchange, link))
1173cc6cc03eSho 			exchange_dump_real("exchange_report", exchange,
1174cc6cc03eSho 			    LOG_REPORT, 0);
11752040585eSniklas }
11762040585eSniklas 
117722819a49Sniklas /*
117822819a49Sniklas  * Release all resources this exchange is using *except* for the "death"
117922819a49Sniklas  * event.  When removing an exchange from the expiration handler that event
118022819a49Sniklas  * will be dealt with therein instead.
118122819a49Sniklas  */
118222819a49Sniklas static void
exchange_free_aux(void * v_exch)118322819a49Sniklas exchange_free_aux(void *v_exch)
11842040585eSniklas {
118522819a49Sniklas 	struct exchange		*exchange = v_exch;
11867db938adSniklas 	struct sa		*sa, *next_sa;
1187fb1921ccSniklas 	struct cert_handler	*handler;
11889bfbb31eSniklas 
118951ca15aeSniklas 	LOG_DBG((LOG_EXCHANGE, 80, "exchange_free_aux: freeing exchange %p",
119051ca15aeSniklas 	    exchange));
11919bfbb31eSniklas 
119222819a49Sniklas 	if (exchange->last_received)
119322819a49Sniklas 		message_free(exchange->last_received);
11941d9d87a5Sniklas 	if (exchange->last_sent)
11951d9d87a5Sniklas 		message_free(exchange->last_sent);
1196cc6cc03eSho 	if (exchange->in_transit &&
1197cc6cc03eSho 	    exchange->in_transit != exchange->last_sent)
11981d9d87a5Sniklas 		message_free(exchange->in_transit);
11992040585eSniklas 	free(exchange->nonce_i);
12002040585eSniklas 	free(exchange->nonce_r);
12012040585eSniklas 	free(exchange->id_i);
12022040585eSniklas 	free(exchange->id_r);
12032040585eSniklas 	free(exchange->keystate);
120410dd6cf1Smpi 	if (exchange->data) {
12052040585eSniklas 		if (exchange->doi && exchange->doi->free_exchange_data)
12062040585eSniklas 			exchange->doi->free_exchange_data(exchange->data);
12072040585eSniklas 		free(exchange->data);
120810dd6cf1Smpi 	}
12092b81057dSniklas 	free(exchange->name);
1210baf9095eShshoexer 	if (exchange->recv_cert) {
1211fb1921ccSniklas 		handler = cert_get(exchange->recv_certtype);
1212fb1921ccSniklas 		if (handler)
1213fb1921ccSniklas 			handler->cert_free(exchange->recv_cert);
121400b1b4a9Sangelos 	}
1215baf9095eShshoexer 	if (exchange->sent_cert) {
121600b1b4a9Sangelos 		handler = cert_get(exchange->sent_certtype);
121700b1b4a9Sangelos 		if (handler)
121800b1b4a9Sangelos 			handler->cert_free(exchange->sent_cert);
1219fb1921ccSniklas 	}
122032f522cdSniklas 	if (exchange->recv_key)
122100b1b4a9Sangelos 		key_free(exchange->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
122200b1b4a9Sangelos 		    exchange->recv_key);
122300b1b4a9Sangelos 	free(exchange->keynote_key);	/* This is just a string */
122432f522cdSniklas 
122532f522cdSniklas 	if (exchange->policy_id != -1)
1226f61a65acSho 		kn_close(exchange->policy_id);
122732f522cdSniklas 
12282040585eSniklas 	exchange_free_aca_list(exchange);
122910dd6cf1Smpi 	if (exchange->linked) {
123022819a49Sniklas 		LIST_REMOVE(exchange, link);
123110dd6cf1Smpi 		exchange->linked = 0;
123210dd6cf1Smpi 	}
123324d2f2e1Sniklas 
1234bd4e5273Sniklas 	/* Tell potential finalize routine we never got there.  */
123524d2f2e1Sniklas 	if (exchange->finalize)
1236172c7fecSniklas 		exchange->finalize(exchange, exchange->finalize_arg, 1);
1237bd4e5273Sniklas 
12389c28b8a1Sangelos 	/* Remove any SAs that have not been disassociated from us.  */
1239baf9095eShshoexer 	for (sa = TAILQ_FIRST(&exchange->sa_list); sa; sa = next_sa) {
12407db938adSniklas 		next_sa = TAILQ_NEXT(sa, next);
12419c28b8a1Sangelos 		/* One for the reference in exchange->sa_list.  */
12429c28b8a1Sangelos 		sa_release(sa);
12439c28b8a1Sangelos 		/* And two more for the expiration and SA linked list.  */
12447db938adSniklas 		sa_free(sa);
12457db938adSniklas 	}
124624d2f2e1Sniklas 
12472040585eSniklas 	free(exchange);
12482040585eSniklas }
12492040585eSniklas 
12502040585eSniklas /* Release all resources this exchange is using.  */
12512040585eSniklas void
exchange_free(struct exchange * exchange)12522040585eSniklas exchange_free(struct exchange *exchange)
12532040585eSniklas {
12542040585eSniklas 	if (exchange->death)
12552040585eSniklas 		timer_remove_event(exchange->death);
12562040585eSniklas 	exchange_free_aux(exchange);
12572040585eSniklas }
12582040585eSniklas 
12592040585eSniklas /*
12602040585eSniklas  * Upgrade the phase 1 exchange and its ISAKMP SA with the rcookie of our
12612040585eSniklas  * peer (found in his recently sent message MSG).
12622040585eSniklas  */
12632040585eSniklas void
exchange_upgrade_p1(struct message * msg)12642040585eSniklas exchange_upgrade_p1(struct message *msg)
12652040585eSniklas {
12662040585eSniklas 	struct exchange *exchange = msg->exchange;
12672040585eSniklas 
12682040585eSniklas 	LIST_REMOVE(exchange, link);
126910dd6cf1Smpi 	exchange->linked = 0;
1270baf9095eShshoexer 	GET_ISAKMP_HDR_RCOOKIE(msg->iov[0].iov_base, exchange->cookies +
1271baf9095eShshoexer 	    ISAKMP_HDR_ICOOKIE_LEN);
12722040585eSniklas 	exchange_enter(exchange);
12732040585eSniklas 	sa_isakmp_upgrade(msg);
12742040585eSniklas }
12752040585eSniklas 
1276172c7fecSniklas static int
exchange_check_old_sa(struct sa * sa,void * v_arg)1277172c7fecSniklas exchange_check_old_sa(struct sa *sa, void *v_arg)
1278172c7fecSniklas {
1279172c7fecSniklas 	struct sa	*new_sa = v_arg;
12802beb4bdbSangelos 	char		 res1[1024];
1281172c7fecSniklas 
1282baf9095eShshoexer 	if (sa == new_sa || !sa->name || !(sa->flags & SA_FLAG_READY) ||
1283baf9095eShshoexer 	    (sa->flags & SA_FLAG_REPLACED))
1284172c7fecSniklas 		return 0;
1285172c7fecSniklas 
1286baf9095eShshoexer 	if (sa->phase != new_sa->phase || new_sa->name == 0 ||
1287baf9095eShshoexer 	    strcasecmp(sa->name, new_sa->name))
12882beb4bdbSangelos 		return 0;
12892beb4bdbSangelos 
12902beb4bdbSangelos 	if (sa->initiator)
1291baf9095eShshoexer 		strlcpy(res1, ipsec_decode_ids("%s %s", sa->id_i, sa->id_i_len,
1292baf9095eShshoexer 		    sa->id_r, sa->id_r_len, 0), sizeof res1);
12932beb4bdbSangelos 	else
1294baf9095eShshoexer 		strlcpy(res1, ipsec_decode_ids("%s %s", sa->id_r, sa->id_r_len,
1295baf9095eShshoexer 		    sa->id_i, sa->id_i_len, 0), sizeof res1);
12962beb4bdbSangelos 
12972beb4bdbSangelos 	LOG_DBG((LOG_EXCHANGE, 30,
1298a7b8c2e4Sniklas 	    "checking whether new SA replaces existing SA with IDs %s", res1));
12992beb4bdbSangelos 
13002beb4bdbSangelos 	if (new_sa->initiator)
13012beb4bdbSangelos 		return strcasecmp(res1, ipsec_decode_ids("%s %s", new_sa->id_i,
1302baf9095eShshoexer 		    new_sa->id_i_len, new_sa->id_r, new_sa->id_r_len, 0)) == 0;
13032beb4bdbSangelos 	else
13042beb4bdbSangelos 		return strcasecmp(res1, ipsec_decode_ids("%s %s", new_sa->id_r,
1305baf9095eShshoexer 		    new_sa->id_r_len, new_sa->id_i, new_sa->id_i_len, 0)) == 0;
1306172c7fecSniklas }
1307172c7fecSniklas 
13082040585eSniklas void
exchange_finalize(struct message * msg)13092040585eSniklas exchange_finalize(struct message *msg)
13102040585eSniklas {
13112040585eSniklas 	struct exchange		*exchange = msg->exchange;
131222819a49Sniklas 	struct sa		*sa, *old_sa;
13132040585eSniklas 	struct proto		*proto;
131419a5b5f4Sniklas 	struct conf_list	*attrs;
131519a5b5f4Sniklas 	struct conf_list_node	*attr;
131600b1b4a9Sangelos 	struct cert_handler	*handler;
13172040585eSniklas 	int	 i;
13182cc3a730Shshoexer 	char	*id_doi, *id_trp;
13192040585eSniklas 
13202040585eSniklas 	exchange_dump("exchange_finalize", exchange);
13212040585eSniklas 
1322f37486b9Sho 	/* Copy the ID from phase 1 to exchange or phase 2 SA.  */
1323baf9095eShshoexer 	if (msg->isakmp_sa) {
1324baf9095eShshoexer 		if (exchange->id_i && exchange->id_r) {
1325cc6cc03eSho 			ipsec_clone_id(&msg->isakmp_sa->id_i,
1326cc6cc03eSho 			    &msg->isakmp_sa->id_i_len, exchange->id_i,
1327cc6cc03eSho 			    exchange->id_i_len);
1328cc6cc03eSho 			ipsec_clone_id(&msg->isakmp_sa->id_r,
1329cc6cc03eSho 			    &msg->isakmp_sa->id_r_len, exchange->id_r,
1330cc6cc03eSho 			    exchange->id_r_len);
1331baf9095eShshoexer 		} else if (msg->isakmp_sa->id_i && msg->isakmp_sa->id_r) {
1332f37486b9Sho 			ipsec_clone_id(&exchange->id_i, &exchange->id_i_len,
1333f37486b9Sho 			    msg->isakmp_sa->id_i, msg->isakmp_sa->id_i_len);
1334f37486b9Sho 			ipsec_clone_id(&exchange->id_r, &exchange->id_r_len,
1335f37486b9Sho 			    msg->isakmp_sa->id_r, msg->isakmp_sa->id_r_len);
1336f37486b9Sho 		}
1337f37486b9Sho 	}
13382040585eSniklas 	/*
133922819a49Sniklas 	 * Walk over all the SAs and noting them as ready.  If we set the
134022819a49Sniklas 	 * COMMIT bit, tell the peer each SA is connected.
134122819a49Sniklas 	 *
13422040585eSniklas 	 * XXX The decision should really be based on if a SA was installed
13432040585eSniklas 	 * successfully.
13442040585eSniklas 	 */
1345cc6cc03eSho 	for (sa = TAILQ_FIRST(&exchange->sa_list); sa;
1346cc6cc03eSho 	    sa = TAILQ_NEXT(sa, next)) {
1347a06203bdSniklas 		/* Move over the name to the SA.  */
13489bfbb31eSniklas 		sa->name = exchange->name ? strdup(exchange->name) : 0;
1349a06203bdSniklas 
1350baf9095eShshoexer 		if (exchange->flags & EXCHANGE_FLAG_I_COMMITTED) {
13512040585eSniklas 			for (proto = TAILQ_FIRST(&sa->protos); proto;
13522040585eSniklas 			    proto = TAILQ_NEXT(proto, link))
13532040585eSniklas 				for (i = 0; i < 2; i++)
13542040585eSniklas 					message_send_notification(exchange->last_received,
13552040585eSniklas 					    msg->isakmp_sa,
1356baf9095eShshoexer 					    ISAKMP_NOTIFY_STATUS_CONNECTED,
1357baf9095eShshoexer 					    proto, i);
13582040585eSniklas 		}
1359baf9095eShshoexer 		/*
1360baf9095eShshoexer 		 * Locate any old SAs and mark them replaced
1361baf9095eShshoexer 		 * (SA_FLAG_REPLACED).
1362baf9095eShshoexer 		 */
13635fc21c41Sho 		sa->initiator = exchange->initiator;
1364172c7fecSniklas 		while ((old_sa = sa_find(exchange_check_old_sa, sa)) != 0)
1365172c7fecSniklas 			sa_mark_replaced(old_sa);
1366172c7fecSniklas 
136719a5b5f4Sniklas 		/* Setup the SA flags.  */
13682040585eSniklas 		sa->flags |= SA_FLAG_READY;
1369baf9095eShshoexer 		if (exchange->name) {
1370a06203bdSniklas 			attrs = conf_get_list(exchange->name, "Flags");
1371baf9095eShshoexer 			if (attrs) {
137219a5b5f4Sniklas 				for (attr = TAILQ_FIRST(&attrs->fields); attr;
137319a5b5f4Sniklas 				    attr = TAILQ_NEXT(attr, link))
137419a5b5f4Sniklas 					sa->flags |= sa_flag(attr->field);
137524d2f2e1Sniklas 				conf_free_list(attrs);
137624d2f2e1Sniklas 			}
1377ec172ef8Sniklas 			/* 'Connections' should stay alive.  */
1378baf9095eShshoexer 			if (connection_exist(exchange->name)) {
1379ec172ef8Sniklas 				sa->flags |= SA_FLAG_STAYALIVE;
1380ec172ef8Sniklas 
1381baf9095eShshoexer 				/*
1382baf9095eShshoexer 				 * ISAKMP SA of this connection should also
1383baf9095eShshoexer 				 * stay alive.
1384baf9095eShshoexer 				 */
1385ec172ef8Sniklas 				if (exchange->phase == 2 && msg->isakmp_sa)
1386cc6cc03eSho 					msg->isakmp_sa->flags |=
1387cc6cc03eSho 					    SA_FLAG_STAYALIVE;
1388ec172ef8Sniklas 			}
13894c7a9999Sniklas 		}
139045055671Sangelos 		sa->seq = exchange->seq;
13912040585eSniklas 		sa->exch_type = exchange->type;
13922040585eSniklas 	}
13932040585eSniklas 
13942040585eSniklas 	/*
1395baf9095eShshoexer 	 * If this was an phase 1 SA negotiation, save the keystate in the
1396baf9095eShshoexer 	 * ISAKMP SA structure for future initialization of phase 2 exchanges'
1397baf9095eShshoexer 	 * keystates.  Also save the Phase 1 ID and authentication
1398baf9095eShshoexer 	 * information.
13992040585eSniklas 	 */
1400baf9095eShshoexer 	if (exchange->phase == 1 && msg->isakmp_sa) {
14012040585eSniklas 		msg->isakmp_sa->keystate = exchange->keystate;
14022040585eSniklas 		exchange->keystate = 0;
14037409b616Sniklas 
14047409b616Sniklas 		msg->isakmp_sa->recv_certtype = exchange->recv_certtype;
140500b1b4a9Sangelos 		msg->isakmp_sa->sent_certtype = exchange->sent_certtype;
140600b1b4a9Sangelos 		msg->isakmp_sa->recv_keytype = exchange->recv_keytype;
140732f522cdSniklas 		msg->isakmp_sa->recv_key = exchange->recv_key;
140800b1b4a9Sangelos 		msg->isakmp_sa->keynote_key = exchange->keynote_key;
14090eb823c5Sniklas 		/* Reset.  */
14100eb823c5Sniklas 		exchange->recv_key = 0;
14110eb823c5Sniklas 		exchange->keynote_key = 0;
141232f522cdSniklas 		msg->isakmp_sa->policy_id = exchange->policy_id;
14130e8582adSangelos 		exchange->policy_id = -1;
14147409b616Sniklas 		msg->isakmp_sa->initiator = exchange->initiator;
14157409b616Sniklas 
1416baf9095eShshoexer 		if (exchange->recv_certtype && exchange->recv_cert) {
141700b1b4a9Sangelos 			handler = cert_get(exchange->recv_certtype);
141800b1b4a9Sangelos 			if (handler)
1419baf9095eShshoexer 				msg->isakmp_sa->recv_cert =
1420baf9095eShshoexer 				    handler->cert_dup(exchange->recv_cert);
142154a25d2eSniklas 		}
1422baf9095eShshoexer 		if (exchange->sent_certtype) {
142300b1b4a9Sangelos 			handler = cert_get(exchange->sent_certtype);
142400b1b4a9Sangelos 			if (handler)
1425baf9095eShshoexer 				msg->isakmp_sa->sent_cert =
1426baf9095eShshoexer 				    handler->cert_dup(exchange->sent_cert);
14272040585eSniklas 		}
14282cc3a730Shshoexer 		if (exchange->doi)
1429baf9095eShshoexer 			id_doi = exchange->doi->decode_ids(
1430baf9095eShshoexer 			    "initiator id %s, responder id %s",
143180f73593Sniklas 			    exchange->id_i, exchange->id_i_len,
1432baf9095eShshoexer 			    exchange->id_r, exchange->id_r_len, 0);
14332cc3a730Shshoexer 		else
14342cc3a730Shshoexer 			id_doi = "<no doi>";
14352cc3a730Shshoexer 
1436aa584aacSho 		if (msg->isakmp_sa->transport)
1437cc6cc03eSho 			id_trp =
1438cc6cc03eSho 			    msg->isakmp_sa->transport->vtbl->decode_ids(msg->isakmp_sa->transport);
14392cc3a730Shshoexer 		else
14402cc3a730Shshoexer 			id_trp = "<no transport>";
14412cc3a730Shshoexer 
1442aa584aacSho 		if (exchange->flags & EXCHANGE_FLAG_NAT_T_ENABLE)
1443aa584aacSho 			msg->isakmp_sa->flags |= SA_FLAG_NAT_T_ENABLE;
1444aa584aacSho 		if (exchange->flags & EXCHANGE_FLAG_NAT_T_KEEPALIVE)
1445aa584aacSho 			msg->isakmp_sa->flags |= SA_FLAG_NAT_T_KEEPALIVE;
1446aa584aacSho 
1447baf9095eShshoexer 		LOG_DBG((LOG_EXCHANGE, 10,
1448cc6cc03eSho 		    "exchange_finalize: phase 1 done: %s, %s", id_doi,
1449cc6cc03eSho 		    id_trp));
14502cc3a730Shshoexer 
1451e76eb8e7Slum 		log_verbose("isakmpd: phase 1 done%s: %s, %s",
1452e76eb8e7Slum 			(exchange->initiator == 0) ? " (as responder)" : "",
1453e76eb8e7Slum 			id_doi, id_trp);
14547409b616Sniklas 	}
1455d6351a66Sho 	exchange->doi->finalize_exchange(msg);
1456d6351a66Sho 	if (exchange->finalize)
1457d6351a66Sho 		exchange->finalize(exchange, exchange->finalize_arg, 0);
1458d6351a66Sho 	exchange->finalize = 0;
1459d6351a66Sho 
1460bd4e5273Sniklas 	/*
1461bd4e5273Sniklas 	 * There is no reason to keep the SAs connected to us anymore, in fact
1462bd4e5273Sniklas 	 * it can hurt us if we have short lifetimes on the SAs and we try
1463bd4e5273Sniklas 	 * to call exchange_report, where the SA list will be walked and
1464bd4e5273Sniklas 	 * references to freed SAs can occur.
1465bd4e5273Sniklas 	 */
1466baf9095eShshoexer 	while (TAILQ_FIRST(&exchange->sa_list)) {
1467605cc57cSho 		sa = TAILQ_FIRST(&exchange->sa_list);
146880f73593Sniklas 
1469baf9095eShshoexer 		if (exchange->id_i && exchange->id_r) {
1470cc6cc03eSho 			ipsec_clone_id(&sa->id_i, &sa->id_i_len,
1471cc6cc03eSho 			    exchange->id_i, exchange->id_i_len);
1472cc6cc03eSho 			ipsec_clone_id(&sa->id_r, &sa->id_r_len,
1473cc6cc03eSho 			    exchange->id_r, exchange->id_r_len);
147472c6dfaeSniklas 		}
147580f73593Sniklas 		TAILQ_REMOVE(&exchange->sa_list, sa, next);
14761d312cf3Sniklas 		sa_release(sa);
147780f73593Sniklas 	}
1478a31e0ec4Smarkus 	/*
1479a31e0ec4Smarkus 	 * Start sending DPD messages after all SAs have been released.
1480a31e0ec4Smarkus 	 * Otherwise we have a race between exchange_free_aux() and
1481a31e0ec4Smarkus 	 * dpd_check_event() where both will call sa_free().
1482a31e0ec4Smarkus 	 */
1483a31e0ec4Smarkus 	if (exchange->phase == 1 && msg->isakmp_sa &&
1484a31e0ec4Smarkus 	    (exchange->flags & EXCHANGE_FLAG_DPD_CAP_PEER))
1485a31e0ec4Smarkus 		dpd_start(msg->isakmp_sa);
1486bd4e5273Sniklas 
148722819a49Sniklas 	/* If we have nothing to retransmit we can safely remove ourselves.  */
148822819a49Sniklas 	if (!exchange->last_sent)
14892040585eSniklas 		exchange_free(exchange);
14902040585eSniklas }
14912040585eSniklas 
14922040585eSniklas /* Stash a nonce into the exchange data.  */
14932040585eSniklas static int
exchange_nonce(struct exchange * exchange,int peer,size_t nonce_sz,u_int8_t * buf)14942040585eSniklas exchange_nonce(struct exchange *exchange, int peer, size_t nonce_sz,
14952040585eSniklas     u_int8_t *buf)
14962040585eSniklas {
14972040585eSniklas 	u_int8_t      **nonce;
14982040585eSniklas 	size_t         *nonce_len;
1499cc6cc03eSho 	int		initiator = exchange->initiator ^ peer;
15002040585eSniklas 	char            header[32];
15012040585eSniklas 
1502120ded69Sho 	if (nonce_sz < 8 || nonce_sz > 256) {
1503120ded69Sho 		/*
1504120ded69Sho 		 * RFC2409, ch 5: The length of nonce payload MUST be
1505120ded69Sho 		 * between 8 and 256 bytes inclusive.
1506120ded69Sho 		 * XXX I'm assuming the generic payload header is not included.
1507120ded69Sho 		 */
1508120ded69Sho 		LOG_DBG((LOG_EXCHANGE, 20,
1509120ded69Sho 		    "exchange_nonce: invalid nonce length %lu",
1510120ded69Sho 		    (unsigned long)nonce_sz));
1511120ded69Sho 		return -1;
1512120ded69Sho 	}
1513120ded69Sho 
15142040585eSniklas 	nonce = initiator ? &exchange->nonce_i : &exchange->nonce_r;
1515cc6cc03eSho 	nonce_len =
1516cc6cc03eSho 	    initiator ? &exchange->nonce_i_len : &exchange->nonce_r_len;
15172040585eSniklas 	*nonce_len = nonce_sz;
15182040585eSniklas 	*nonce = malloc(nonce_sz);
1519baf9095eShshoexer 	if (!*nonce) {
1520baf9095eShshoexer 		log_error("exchange_nonce: malloc (%lu) failed",
1521baf9095eShshoexer 		    (unsigned long)nonce_sz);
15222040585eSniklas 		return -1;
152324d2f2e1Sniklas 	}
15242040585eSniklas 	memcpy(*nonce, buf, nonce_sz);
1525f799be47Sho 	snprintf(header, sizeof header, "exchange_nonce: NONCE_%c",
1526f799be47Sho 	    initiator ? 'i' : 'r');
152751ca15aeSniklas 	LOG_DBG_BUF((LOG_EXCHANGE, 80, header, *nonce, nonce_sz));
15282040585eSniklas 	return 0;
15292040585eSniklas }
15302040585eSniklas 
15312040585eSniklas /* Generate our NONCE.  */
15322040585eSniklas int
exchange_gen_nonce(struct message * msg,size_t nonce_sz)15332040585eSniklas exchange_gen_nonce(struct message *msg, size_t nonce_sz)
15342040585eSniklas {
15352040585eSniklas 	struct exchange *exchange = msg->exchange;
15362040585eSniklas 	u_int8_t	*buf;
15372040585eSniklas 
15382040585eSniklas 	buf = malloc(ISAKMP_NONCE_SZ + nonce_sz);
1539baf9095eShshoexer 	if (!buf) {
15407eb3b581Sderaadt 		log_error("exchange_gen_nonce: malloc (%lu) failed",
15417eb3b581Sderaadt 		    ISAKMP_NONCE_SZ + (unsigned long)nonce_sz);
15422040585eSniklas 		return -1;
154324d2f2e1Sniklas 	}
1544baf9c2dbSderaadt 	arc4random_buf(buf + ISAKMP_NONCE_DATA_OFF, nonce_sz);
15452040585eSniklas 	if (message_add_payload(msg, ISAKMP_PAYLOAD_NONCE, buf,
1546baf9095eShshoexer 	    ISAKMP_NONCE_SZ + nonce_sz, 1)) {
15472040585eSniklas 		free(buf);
15482040585eSniklas 		return -1;
15492040585eSniklas 	}
1550cc6cc03eSho 	return exchange_nonce(exchange, 0, nonce_sz,
1551cc6cc03eSho 	    buf + ISAKMP_NONCE_DATA_OFF);
15522040585eSniklas }
15532040585eSniklas 
15542040585eSniklas /* Save the peer's NONCE.  */
15552040585eSniklas int
exchange_save_nonce(struct message * msg)15562040585eSniklas exchange_save_nonce(struct message *msg)
15572040585eSniklas {
15582040585eSniklas 	struct payload	*noncep;
15592040585eSniklas 	struct exchange *exchange = msg->exchange;
15602040585eSniklas 
156177fa3de5Sho 	noncep = payload_first(msg, ISAKMP_PAYLOAD_NONCE);
15622040585eSniklas 	noncep->flags |= PL_MARK;
1563baf9095eShshoexer 	return exchange_nonce(exchange, 1, GET_ISAKMP_GEN_LENGTH(noncep->p) -
1564baf9095eShshoexer 	    ISAKMP_NONCE_DATA_OFF, noncep->p + ISAKMP_NONCE_DATA_OFF);
15652040585eSniklas }
15662040585eSniklas 
15672040585eSniklas /* Save the peer's CERT REQuests.  */
15682040585eSniklas int
exchange_save_certreq(struct message * msg)15692040585eSniklas exchange_save_certreq(struct message *msg)
15702040585eSniklas {
1571ed76d6b8Shshoexer 	struct payload	*cp;
15722040585eSniklas 	struct exchange	*exchange = msg->exchange;
1573a7b8c2e4Sniklas 	struct certreq_aca *aca;
15742040585eSniklas 
1575ed76d6b8Shshoexer 	TAILQ_FOREACH(cp, &msg->payload[ISAKMP_PAYLOAD_CERT_REQ], link) {
15762040585eSniklas 		cp->flags |= PL_MARK;
1577baf9095eShshoexer 		aca = certreq_decode(GET_ISAKMP_CERTREQ_TYPE(cp->p), cp->p +
1578baf9095eShshoexer 		    ISAKMP_CERTREQ_AUTHORITY_OFF, GET_ISAKMP_GEN_LENGTH(cp->p)
1579baf9095eShshoexer 		    - ISAKMP_CERTREQ_AUTHORITY_OFF);
1580a7b8c2e4Sniklas 		if (aca)
1581a7b8c2e4Sniklas 			TAILQ_INSERT_TAIL(&exchange->aca_list, aca, link);
15822040585eSniklas 	}
15832040585eSniklas 
15842040585eSniklas 	return 0;
15852040585eSniklas }
15862040585eSniklas 
15873b43e3b6Sniklas /* Free the list of pending CERTREQs.  */
15882040585eSniklas void
exchange_free_aca_list(struct exchange * exchange)15892040585eSniklas exchange_free_aca_list(struct exchange *exchange)
15902040585eSniklas {
15912040585eSniklas 	struct certreq_aca *aca;
15922040585eSniklas 
15932040585eSniklas 	for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
1594baf9095eShshoexer 	    aca = TAILQ_FIRST(&exchange->aca_list)) {
159505442ddfStom 		free(aca->raw_ca);
1596baf9095eShshoexer 		if (aca->data) {
1597172c7fecSniklas 			if (aca->handler)
15982040585eSniklas 				aca->handler->free_aca(aca->data);
15992040585eSniklas 			free(aca->data);
16002040585eSniklas 		}
16012040585eSniklas 		TAILQ_REMOVE(&exchange->aca_list, aca, link);
16022040585eSniklas 		free(aca);
16032040585eSniklas 	}
16042040585eSniklas }
16052040585eSniklas 
160605442ddfStom /* Add any CERTREQs we should send.  */
160705442ddfStom int
exchange_add_certreqs(struct message * msg)160805442ddfStom exchange_add_certreqs(struct message *msg)
160905442ddfStom {
161005442ddfStom 	struct exchange *exchange = msg->exchange;
161105442ddfStom 	struct certreq_aca *aca;
161205442ddfStom 	u_int8_t *buf;
161305442ddfStom 
161405442ddfStom 	/*
161505442ddfStom 	 * Some peers (e.g. Cisco IOS) won't send their cert unless we
161605442ddfStom 	 * specifically ask beforehand with CERTREQ.  We reflect any
161705442ddfStom 	 * CERTREQs we receive from the initiator in order to do this.
161805442ddfStom 	 * This avoids leaking information about which CAs we trust,
161905442ddfStom 	 * and works in the most common case where both ends trust the
162005442ddfStom 	 * same CA.
162105442ddfStom 	 */
162205442ddfStom 	for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
162305442ddfStom 	    aca = TAILQ_NEXT(aca, link)) {
162405442ddfStom 
162505442ddfStom 		/* But only do this if we have at least one CA */
162605442ddfStom 		if (aca->handler != NULL && aca->handler->ca_count() == 0) {
162705442ddfStom 			LOG_DBG((LOG_EXCHANGE, 10,
162805442ddfStom 			    "exchange_add_certreqs: no CA, so not "
162905442ddfStom 			    "sending a CERTREQ"));
163005442ddfStom 			continue;
163105442ddfStom 		}
163205442ddfStom 
163305442ddfStom 		if (aca->raw_ca_len) {
163405442ddfStom 			buf = malloc(ISAKMP_CERTREQ_SZ + aca->raw_ca_len);
163505442ddfStom 			if (buf == NULL) {
163605442ddfStom 				log_error("exchange_add_certreqs: "
163705442ddfStom 				    "malloc (%lu) failed",
163805442ddfStom 				    ISAKMP_CERTREQ_SZ +
163905442ddfStom 				    (unsigned long)aca->raw_ca_len);
164005442ddfStom 				return -1;
164105442ddfStom 			}
164205442ddfStom 
164305442ddfStom 			buf[ISAKMP_CERTREQ_TYPE_OFF] = aca->id;
164405442ddfStom 			memcpy(buf + ISAKMP_CERTREQ_AUTHORITY_OFF,
164505442ddfStom 			    aca->raw_ca, aca->raw_ca_len);
164605442ddfStom 
164705442ddfStom 			if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT_REQ,
164805442ddfStom 			    buf, ISAKMP_CERTREQ_SZ + aca->raw_ca_len, 1)) {
164905442ddfStom 				free(buf);
165005442ddfStom 				return -1;
165105442ddfStom 			}
165205442ddfStom 		}
165305442ddfStom 	}
165405442ddfStom 
165505442ddfStom 	return 0;
165605442ddfStom }
165705442ddfStom 
165824d2f2e1Sniklas /* Obtain certificates from acceptable certification authority.  */
16592040585eSniklas int
exchange_add_certs(struct message * msg)16602040585eSniklas exchange_add_certs(struct message *msg)
16612040585eSniklas {
16622040585eSniklas 	struct exchange *exchange = msg->exchange;
16632040585eSniklas 	struct certreq_aca *aca;
1664e7e18aa3Scloder 	u_int8_t       *cert = 0, *new_cert = 0;
16652040585eSniklas 	u_int32_t       certlen;
1666fb1921ccSniklas 	u_int8_t       *id;
1667fb1921ccSniklas 	size_t          id_len;
1668fb1921ccSniklas 
1669fb1921ccSniklas 	id = exchange->initiator ? exchange->id_r : exchange->id_i;
1670fb1921ccSniklas 	id_len = exchange->initiator ? exchange->id_r_len : exchange->id_i_len;
16712040585eSniklas 
167282bf5ee8Sho 	/*
167382bf5ee8Sho 	 * Without IDs we cannot handle this yet. Keep the aca_list around for
167482bf5ee8Sho 	 * a later step/retry to see if we got the ID by then.
167582bf5ee8Sho 	 * Note: A 'return -1' breaks X509-auth interop in the responder case
1676cc6cc03eSho 	 *       with some IPsec clients that send CERTREQs early (such as
1677cc6cc03eSho 	 *       the SSH Sentinel).
167882bf5ee8Sho 	 */
167982bf5ee8Sho 	if (!id)
168082bf5ee8Sho 		return 0;
168182bf5ee8Sho 
16822040585eSniklas 	for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
1683baf9095eShshoexer 	    aca = TAILQ_NEXT(aca, link)) {
1684a7b8c2e4Sniklas 		/* XXX? If we can not satisfy a CERTREQ we drop the message. */
1685cc6cc03eSho 		if (!aca->handler->cert_obtain(id, id_len, aca->data, &cert,
1686cc6cc03eSho 		    &certlen)) {
1687baf9095eShshoexer 			log_print("exchange_add_certs: could not obtain cert "
1688baf9095eShshoexer 			    "for a type %d cert request", aca->id);
1689e7e18aa3Scloder 			free(cert);
16902040585eSniklas 			return -1;
16912040585eSniklas 		}
1692e7e18aa3Scloder 		new_cert = realloc(cert, ISAKMP_CERT_SZ + certlen);
1693baf9095eShshoexer 		if (!new_cert) {
1694cc6cc03eSho 			log_error("exchange_add_certs: realloc (%p, %d) "
1695cc6cc03eSho 			    "failed", cert, ISAKMP_CERT_SZ + certlen);
1696e7e18aa3Scloder 			free(cert);
16972040585eSniklas 			return -1;
169824d2f2e1Sniklas 		}
1699e7e18aa3Scloder 		cert = new_cert;
17002040585eSniklas 		memmove(cert + ISAKMP_CERT_DATA_OFF, cert, certlen);
17012040585eSniklas 		SET_ISAKMP_CERT_ENCODING(cert, aca->id);
17022040585eSniklas 		if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT, cert,
1703baf9095eShshoexer 		    ISAKMP_CERT_SZ + certlen, 1)) {
17042040585eSniklas 			free(cert);
17052040585eSniklas 			return -1;
17062040585eSniklas 		}
170711d4dffdStom 		/*
170811d4dffdStom 		 * We need to reset cert here, as it is now controlled by
170911d4dffdStom 		 * message_add_payload() (i.e. we must not free() it), and
171011d4dffdStom 		 * it is possible for the next iteration of the aca loop
171111d4dffdStom 		 * to fail early in cert_obtain before it writes to &cert.
171211d4dffdStom 		 */
171311d4dffdStom 		cert = NULL;
17142040585eSniklas 	}
17152040585eSniklas 
1716a7b8c2e4Sniklas 	/* We dont need the CERT REQs any more, they are answered.  */
17172040585eSniklas 	exchange_free_aca_list(exchange);
17182040585eSniklas 
17192040585eSniklas 	return 0;
17202040585eSniklas }
17212b81057dSniklas 
17222b81057dSniklas static void
exchange_establish_finalize(struct exchange * exchange,void * arg,int fail)1723172c7fecSniklas exchange_establish_finalize(struct exchange *exchange, void *arg, int fail)
17242b81057dSniklas {
17252b81057dSniklas 	char	*name = arg;
1726172c7fecSniklas 
1727baf9095eShshoexer 	LOG_DBG((LOG_EXCHANGE, 20, "exchange_establish_finalize: "
1728172c7fecSniklas 	    "finalizing exchange %p with arg %p (%s) & fail = %d",
172951ca15aeSniklas 	    exchange, arg, name ? name : "<unnamed>", fail));
17302b81057dSniklas 
173124d2f2e1Sniklas 	if (!fail)
1732a28d886cShshoexer 		exchange_establish(name, 0, 0, 0);
17339bfbb31eSniklas 	free(name);
17342b81057dSniklas }
17352b81057dSniklas 
1736a06203bdSniklas /*
1737a06203bdSniklas  * Establish an exchange named NAME, and record the FINALIZE function
1738a06203bdSniklas  * taking ARG as an argument to be run after the exchange is ready.
1739a06203bdSniklas  */
17402b81057dSniklas void
exchange_establish(char * name,void (* finalize)(struct exchange *,void *,int),void * arg,int stayalive)1741baf9095eShshoexer exchange_establish(char *name, void (*finalize)(struct exchange *, void *,
1742a28d886cShshoexer     int), void *arg, int stayalive)
17432b81057dSniklas {
17442b81057dSniklas 	struct transport	*transport;
17452b81057dSniklas 	struct sa		*isakmp_sa;
1746172c7fecSniklas 	struct exchange		*exchange;
1747cc6cc03eSho 	int	 phase;
1748cc6cc03eSho 	char	*trpt, *peer;
1749cc6cc03eSho 
1750f5228d8eSniklas 	phase = conf_get_num(name, "Phase", 0);
1751172c7fecSniklas 
175214f1d06aSmpf 	if (ui_daemon_passive) {
175314f1d06aSmpf 		LOG_DBG((LOG_EXCHANGE, 40, "exchange_establish:"
175414f1d06aSmpf 		    " returning in passive mode for exchange %s phase %d",
175514f1d06aSmpf 		    name, phase));
175610dd6cf1Smpi 		if (finalize)
175710dd6cf1Smpi 			finalize(0, arg, 1);
175814f1d06aSmpf 		return;
175914f1d06aSmpf 	}
176014f1d06aSmpf 
1761172c7fecSniklas 	/*
1762baf9095eShshoexer 	 * First of all, never try to establish anything if another exchange
1763baf9095eShshoexer 	 * of the same kind is running.
1764172c7fecSniklas 	 */
1765172c7fecSniklas 	exchange = exchange_lookup_by_name(name, phase);
1766baf9095eShshoexer 	if (exchange) {
176751ca15aeSniklas 		LOG_DBG((LOG_EXCHANGE, 40,
1768cc6cc03eSho 		    "exchange_establish: %s exchange already exists as %p",
1769cc6cc03eSho 		    name, exchange));
1770172c7fecSniklas 		exchange_add_finalization(exchange, finalize, arg);
1771172c7fecSniklas 		return;
1772172c7fecSniklas 	}
1773baf9095eShshoexer 	switch (phase) {
17742b81057dSniklas 	case 1:
17752b81057dSniklas 		trpt = conf_get_str(name, "Transport");
1776baf9095eShshoexer 		if (!trpt) {
177780f73593Sniklas 			/* Phase 1 transport defaults to "udp".  */
177880f73593Sniklas 			trpt = ISAKMP_DEFAULT_TRANSPORT;
17792b81057dSniklas 		}
17802b81057dSniklas 		transport = transport_create(trpt, name);
1781baf9095eShshoexer 		if (!transport) {
1782cc6cc03eSho 			log_print("exchange_establish: transport \"%s\" for "
1783cc6cc03eSho 			    "peer \"%s\" could not be created", trpt, name);
178410dd6cf1Smpi 			if (finalize)
178510dd6cf1Smpi 				finalize(0, arg, 1);
17862b81057dSniklas 			return;
17872b81057dSniklas 		}
178810dd6cf1Smpi 		if (exchange_establish_p1(transport, 0, 0, name, 0, finalize,
178910dd6cf1Smpi 		    arg, stayalive) < 0 && finalize)
179010dd6cf1Smpi 			finalize(0, arg, 1);
17912b81057dSniklas 		break;
17922b81057dSniklas 
17932b81057dSniklas 	case 2:
17942b81057dSniklas 		peer = conf_get_str(name, "ISAKMP-peer");
1795baf9095eShshoexer 		if (!peer) {
1796cc6cc03eSho 			log_print("exchange_establish: No ISAKMP-peer given "
1797cc6cc03eSho 			    "for \"%s\"", name);
179810dd6cf1Smpi 			if (finalize)
179910dd6cf1Smpi 				finalize(0, arg, 1);
18002b81057dSniklas 			return;
18012b81057dSniklas 		}
18022b81057dSniklas 		isakmp_sa = sa_lookup_by_name(peer, 1);
1803baf9095eShshoexer 		if (!isakmp_sa) {
180410dd6cf1Smpi 			/* freed by exchange_establish_finalize() */
18052b81057dSniklas 			name = strdup(name);
1806baf9095eShshoexer 			if (!name) {
1807cc6cc03eSho 				log_error("exchange_establish: "
1808cc6cc03eSho 				    "strdup (\"%s\") failed", name);
180910dd6cf1Smpi 				if (finalize)
181010dd6cf1Smpi 					finalize(0, arg, 1);
18112b81057dSniklas 				return;
18122b81057dSniklas 			}
1813baf9095eShshoexer 			if (conf_get_num(peer, "Phase", 0) != 1) {
1814afcc621fSho 				log_print("exchange_establish: "
1815baf9095eShshoexer 				    "[%s]:ISAKMP-peer's (%s) phase is not 1",
1816baf9095eShshoexer 				    name, peer);
181710dd6cf1Smpi 				if (finalize)
181810dd6cf1Smpi 					finalize(0, arg, 1);
1819b05ee9e0Smarkus 				free(name);
18207409b616Sniklas 				return;
18217409b616Sniklas 			}
18228ce6c35cSangelos 			/*
1823baf9095eShshoexer 			 * XXX We're losing information here (what the
1824baf9095eShshoexer 			 * original finalize routine was. As a result, if an
1825baf9095eShshoexer 			 * exchange does not manage to get through, there may
1826baf9095eShshoexer 			 * be application-specific information that won't get
18275678a57aShshoexer 			 * cleaned up, since no error signaling will be done.
1828baf9095eShshoexer 			 * This is the case with dynamic SAs and PFKEY.
18298ce6c35cSangelos 			 */
1830cc6cc03eSho 			exchange_establish(peer, exchange_establish_finalize,
1831a28d886cShshoexer 			    name, 0);
1832ea9e0bc0Sangelos 			exchange = exchange_lookup_by_name(peer, 1);
1833ea9e0bc0Sangelos 			/*
1834baf9095eShshoexer 			 * If the exchange was correctly initialized, add the
1835baf9095eShshoexer 			 * original finalization routine; otherwise, call it
1836baf9095eShshoexer 			 * directly.
1837ea9e0bc0Sangelos 			 */
1838ea9e0bc0Sangelos 			if (exchange)
1839cc6cc03eSho 				exchange_add_finalization(exchange, finalize,
1840cc6cc03eSho 				    arg);
1841b05ee9e0Smarkus 			else {
18423dbbcfa7Scloder 				/* Indicate failure */
18433dbbcfa7Scloder 				if (finalize)
18443dbbcfa7Scloder 					finalize(0, arg, 1);
1845b05ee9e0Smarkus 			}
1846ea9e0bc0Sangelos 			return;
184710dd6cf1Smpi 		} else {
184810dd6cf1Smpi 			if (exchange_establish_p2(isakmp_sa, 0, name, 0,
184910dd6cf1Smpi 			    finalize, arg) < 0 && finalize)
185010dd6cf1Smpi 				finalize(0, arg, 1);
185110dd6cf1Smpi 		}
18522b81057dSniklas 		break;
18532b81057dSniklas 
18542b81057dSniklas 	default:
18552b81057dSniklas 		log_print("exchange_establish: "
18562b81057dSniklas 		    "peer \"%s\" does not have a correct phase (%d)",
18572b81057dSniklas 		    name, phase);
18582b81057dSniklas 		break;
18592b81057dSniklas 	}
18602b81057dSniklas }
1861