Thu Jan 24 06:47:51 2013 UTC ()
Fix handling of deletion notification.


(tteras)
diff -r1.48 -r1.49 src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c

cvs diff -r1.48 -r1.49 src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c (switch to unified diff)

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