Print this page
Current snapshot of OpenSolaris port.
Checkpoint
Checkpoint
Merge from parent.
Merge with WIDE update.
Pull from WIDE.
Pull from WIDE.
Checkpoint
Re-update.
blah
WIDE update
Update from WIDE.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/iked/ikev1/isakmp_quick.c
+++ new/iked/ikev1/isakmp_quick.c
1 1 /* $KAME: isakmp_quick.c,v 1.95 2003/10/21 07:18:03 itojun Exp $ */
2 2
3 3 /*
4 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 5 * All rights reserved.
6 6 *
7 7 * Redistribution and use in source and binary forms, with or without
8 8 * modification, are permitted provided that the following conditions
9 9 * are met:
10 10 * 1. Redistributions of source code must retain the above copyright
11 11 * notice, this list of conditions and the following disclaimer.
12 12 * 2. Redistributions in binary form must reproduce the above copyright
13 13 * notice, this list of conditions and the following disclaimer in the
14 14 * documentation and/or other materials provided with the distribution.
15 15 * 3. Neither the name of the project nor the names of its contributors
16 16 * may be used to endorse or promote products derived from this software
17 17 * without specific prior written permission.
18 18 *
19 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 29 * SUCH DAMAGE.
30 30 */
31 31
32 32 #ifdef HAVE_CONFIG_H
33 33 # include <config.h>
34 34 #endif
35 35
36 36 #include <sys/types.h>
37 37 #include <sys/param.h>
38 38 #include <sys/socket.h>
39 39
40 40 #if 0
41 41 #include <netkey/key_var.h>
42 42 #endif
43 43 #include <netinet/in.h>
44 44
45 45 #include <stdlib.h>
46 46 #include <stdio.h>
47 47 #include <string.h>
48 48 #include <errno.h>
49 49 #if TIME_WITH_SYS_TIME
50 50 # include <sys/time.h>
51 51 # include <time.h>
52 52 #else
53 53 # if HAVE_SYS_TIME_H
54 54 # include <sys/time.h>
55 55 # else
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
56 56 # include <time.h>
57 57 # endif
58 58 #endif
59 59
60 60 #ifdef HAVE_NETINET6_IPSEC_H
61 61 # include <netinet6/ipsec.h>
62 62 #else
63 63 # ifdef HAVE_NETIPSEC_IPSEC_H
64 64 # include <netipsec/ipsec.h>
65 65 # else
66 -# include <linux/ipsec.h>
66 +# ifndef sun /* XXX KEBE SAYS OpenSolaris */
67 +# include <linux/ipsec.h>
68 +# endif
67 69 # endif
68 70 #endif
69 71
72 +#ifdef sun /* XXX KEBE SAYS OpenSolaris */
73 +#define IPSEC_ULPROTO_ANY 0
74 +#endif
75 +
70 76 #include "racoon.h"
71 77
72 78 #include "var.h"
73 79 /* #include "vmbuf.h" */
74 80 /* #include "schedule.h" */
75 81 /* #include "misc.h" */
76 82 #include "plog.h"
77 83 #include "debug.h"
78 84
79 85 /* #include "localconf.h" */
80 86 #include "remoteconf.h"
81 87 #include "isakmp.h"
82 88 #include "isakmp_var.h"
83 89 #include "isakmp_impl.h"
84 90 #include "ikev1_impl.h"
85 91 #include "isakmp_inf.h"
86 92 #include "isakmp_quick.h"
87 93 #include "oakley.h"
88 94 #include "handler.h"
89 95 #include "ipsec_doi.h"
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
90 96 #include "crypto_impl.h"
91 97 #include "pfkey.h"
92 98 /* #include "policy.h" */
93 99 #include "algorithm.h"
94 100 #include "sockmisc.h"
95 101 #include "proposal.h"
96 102 /* #include "sainfo.h" */
97 103 /* #include "admin.h" */
98 104 #include "strnames.h"
99 105
106 +#ifdef sun
107 +#include "ikev1_natt.h"
108 +#define IPSECDOI_PREFIX_HOST 32 /* Hack for port of NAT-OA from ipsec-tools. */
109 +#endif
110 +
100 111 #include "ike_conf.h"
101 112
102 113 /* quick mode */
103 114 static rc_vchar_t *quick_ir1mx (struct ph2handle *, rc_vchar_t *, rc_vchar_t *);
104 115 static int get_sainfo_r (struct ph2handle *);
105 116 static int get_proposal_r (struct ph2handle *);
106 117 #ifdef INET6
107 118 static uint32_t setscopeid (struct sockaddr *, struct sockaddr *)
108 119 GCC_ATTRIBUTE((unused));
109 120 #endif
110 121
111 122 /* called from scheduler */
112 123 void
113 124 pfkey_timeover_stub(p)
114 125 void *p;
115 126 {
116 127 void pfkey_timeover();
117 128
118 129 pfkey_timeover((struct ph2handle *)p);
119 130 }
120 131
121 132 void
122 133 pfkey_timeover(struct ph2handle *iph2)
123 134 {
124 135 plog(PLOG_PROTOERR, PLOGLOC, 0,
125 136 "%s give up to get IPsec-SA due to time up to wait.\n",
126 137 rcs_sa2str_wop(iph2->dst));
127 138 SCHED_KILL(iph2->sce);
128 139
129 140 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
130 141 if (iph2->side == INITIATOR)
131 142 pk_sendeacquire(iph2);
132 143
133 144 unbindph12(iph2);
134 145 remph2(iph2);
135 146 delph2(iph2);
136 147
137 148 return;
138 149 }
139 150
140 151 /* %%%
141 152 * Quick Mode
142 153 */
143 154 /*
144 155 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
145 156 */
146 157 int
147 158 quick_i1prep(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */)
148 159 {
149 160 int error = ISAKMP_INTERNAL_ERROR;
150 161
151 162 /* validity check */
152 163 if (iph2->status != PHASE2ST_STATUS2) {
153 164 plog(PLOG_INTERR, PLOGLOC, NULL,
154 165 "status mismatched %d.\n", iph2->status);
155 166 goto end;
156 167 }
157 168
158 169 iph2->msgid = isakmp_newmsgid2(iph2->ph1);
159 170 iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
160 171 if (iph2->ivm == NULL)
161 172 return 0;
162 173
163 174 iph2->status = PHASE2ST_GETSPISENT;
164 175
165 176 #if 0
166 177 /* don't anything if local test mode. */
167 178 if (f_local) {
168 179 error = 0;
169 180 goto end;
170 181 }
171 182 #endif
172 183
173 184 /* send getspi message */
174 185 if (pk_sendgetspi(iph2) < 0)
175 186 goto end;
176 187
177 188 plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey getspi sent.\n");
178 189
179 190 iph2->sce = sched_new(ikev1_ipsec_sa_nego_time_limit(iph2->ph1->rmconf),
|
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
180 191 pfkey_timeover_stub, iph2);
181 192
182 193 error = 0;
183 194
184 195 end:
185 196 return error;
186 197 }
187 198
188 199 /*
189 200 * send to responder
190 - * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
201 + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
191 202 */
192 203 int
193 204 quick_i1send(struct ph2handle *iph2, rc_vchar_t *msg /* must be null pointer */)
194 205 {
195 206 rc_vchar_t *body = NULL;
196 207 rc_vchar_t *hash = NULL;
197 208 struct isakmp_gen *gen;
198 209 char *p;
199 210 int tlen;
200 211 int error = ISAKMP_INTERNAL_ERROR;
201 212 int pfsgroup, idci, idcr;
202 213 int np;
203 214 struct ipsecdoi_id_b *id, *id_p;
215 +#ifdef sun
216 + int natoa = ISAKMP_NPTYPE_NONE;
217 + rc_vchar_t *nat_oai = NULL;
218 + rc_vchar_t *nat_oar = NULL;
219 +#endif
204 220
205 221 /* validity check */
206 222 if (msg != NULL) {
207 223 plog(PLOG_INTERR, PLOGLOC, NULL,
208 224 "msg has to be NULL in this function.\n");
209 225 goto end;
210 226 }
211 227 if (iph2->status != PHASE2ST_GETSPIDONE) {
212 228 plog(PLOG_INTERR, PLOGLOC, NULL,
213 229 "status mismatched %d.\n", iph2->status);
214 230 goto end;
215 231 }
216 232
217 233 /* create SA payload for my proposal */
218 234 if (ipsecdoi_setph2proposal(iph2) < 0)
219 235 goto end;
220 236
221 237 /* generate NONCE value */
222 238 iph2->nonce = eay_set_random(ikev1_nonce_size(iph2->ph1->rmconf));
223 239 if (iph2->nonce == NULL)
224 240 goto end;
225 241
226 242 /*
227 243 * DH value calculation is kicked out into cfparse.y.
228 244 * because pfs group can not be negotiated, it's only to be checked
229 245 * acceptable.
230 246 */
231 247 /* generate KE value if need */
232 248 pfsgroup = iph2->proposal->pfs_group;
233 249 if (pfsgroup) {
234 250 /* DH group settting if PFS is required. */
235 251 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
236 252 plog(PLOG_INTERR, PLOGLOC, NULL,
237 253 "failed to set DH value.\n");
238 254 goto end;
239 255 }
240 256 if (oakley_dh_generate(iph2->pfsgrp,
241 257 &iph2->dhpub, &iph2->dhpriv) < 0) {
242 258 goto end;
243 259 }
244 260 }
245 261
246 262 /* generate ID value */
247 263 if (ipsecdoi_setid2(iph2) < 0) {
248 264 plog(PLOG_INTERR, PLOGLOC, NULL,
249 265 "failed to get ID.\n");
250 266 goto end;
251 267 }
252 268 plog(PLOG_DEBUG, PLOGLOC, NULL, "IDci:\n");
253 269 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id->v, iph2->id->l);
254 270 plog(PLOG_DEBUG, PLOGLOC, NULL, "IDcr:");
255 271 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id_p->v, iph2->id_p->l);
256 272
257 273 /*
258 274 * we do not attach IDci nor IDcr, under the following condition:
259 275 * - all proposals are transport mode
260 276 * - no MIP6 or proxy
261 277 * - id payload suggests to encrypt all the traffic (no specific
262 278 * protocol type)
263 279 */
264 280 id = (struct ipsecdoi_id_b *)iph2->id->v;
265 281 id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
266 282 if (id->proto_id == 0
267 283 && id_p->proto_id == 0
|
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
268 284 && id->port == 0
269 285 && id_p->port == 0
270 286 && iph2->selector->pl != 0
271 287 && (iph2->selector->pl->my_sa_ipaddr != 0
272 288 || iph2->selector->pl->peers_sa_ipaddr != 0)
273 289 && ipsecdoi_transportmode(iph2->proposal)) {
274 290 idci = idcr = 0;
275 291 } else
276 292 idci = idcr = 1;
277 293
294 +#ifdef sun
295 + /*
296 + * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
297 + * we should send NAT-OA
298 + *
299 + * XXX KEBE ASKS if we should send it for tunnel mode anyway, like
300 + * we do with in.iked?
301 + */
302 + if (ipsecdoi_transportmode(iph2->proposal)
303 + && (iph2->ph1->natt_flags & NAT_DETECTED)) {
304 + natoa = iph2->ph1->natt_options->payload_nat_oa;
305 +
306 + nat_oai = ipsecdoi_sockaddr2id(iph2->src,
307 + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
308 + nat_oar = ipsecdoi_sockaddr2id(iph2->dst,
309 + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
310 +
311 + if (nat_oai == NULL || nat_oar == NULL) {
312 + plog(PLOG_INTERR, PLOGLOC, NULL,
313 + "failed to generate NAT-OA payload.\n");
314 + goto end;
315 + }
316 +
317 + plog(PLOG_INFO, PLOGLOC, NULL, "Using NAT-OA.\n");
318 + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAi:\n");
319 + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oai->v, nat_oai->l);
320 + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAr:\n");
321 + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oar->v, nat_oar->l);
322 + } else {
323 + plog(PLOG_INFO, PLOGLOC, NULL, "Not using NAT-OA.\n");
324 + plog(PLOG_INFO, PLOGLOC, NULL, "transportmode == %d, "
325 + "natt_flags == 0x%x\n",
326 + ipsecdoi_transportmode(iph2->proposal),
327 + iph2->ph1->natt_flags & NAT_DETECTED);
328 + natoa = ISAKMP_NPTYPE_NONE;
329 + }
330 +#endif
331 +
278 332 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
279 333 tlen = + sizeof(*gen) + iph2->sa->l
280 334 + sizeof(*gen) + iph2->nonce->l;
281 335 if (pfsgroup)
282 336 tlen += (sizeof(*gen) + iph2->dhpub->l);
283 337 if (idci)
284 338 tlen += sizeof(*gen) + iph2->id->l;
285 339 if (idcr)
286 340 tlen += sizeof(*gen) + iph2->id_p->l;
341 +#ifdef sun
342 + if (natoa != ISAKMP_NPTYPE_NONE)
343 + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
344 +#endif
287 345
288 346 body = rc_vmalloc(tlen);
289 347 if (body == NULL) {
290 348 plog(PLOG_INTERR, PLOGLOC, NULL,
291 349 "failed to get buffer to send.\n");
292 350 goto end;
293 351 }
294 352
295 353 p = body->v;
296 354
297 355 /* add SA payload */
298 356 p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE);
299 357
300 358 /* add NONCE payload */
301 359 if (pfsgroup)
302 360 np = ISAKMP_NPTYPE_KE;
303 361 else if (idci || idcr)
304 362 np = ISAKMP_NPTYPE_ID;
305 363 else
306 - np = ISAKMP_NPTYPE_NONE;
364 + np = natoa;
307 365 p = set_isakmp_payload(p, iph2->nonce, np);
308 366
309 367 /* add KE payload if need. */
310 - np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
368 + np = (idci || idcr) ? ISAKMP_NPTYPE_ID : natoa;
311 369 if (pfsgroup)
312 370 p = set_isakmp_payload(p, iph2->dhpub, np);
313 371
314 372 /* IDci */
315 - np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
373 + np = (idcr) ? ISAKMP_NPTYPE_ID : natoa;
316 374 if (idci)
317 375 p = set_isakmp_payload(p, iph2->id, np);
318 376
319 377 /* IDcr */
320 378 if (idcr)
321 - p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE);
379 + p = set_isakmp_payload(p, iph2->id_p, natoa);
322 380
381 +#ifdef sun
382 + /* NAT-OA */
383 + if (natoa != ISAKMP_NPTYPE_NONE) {
384 + p = set_isakmp_payload(p, nat_oai, natoa);
385 + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
386 + }
387 +#endif
388 +
323 389 /* generate HASH(1) */
324 390 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
325 391 if (hash == NULL)
326 392 goto end;
327 393
328 394 /* send isakmp payload */
329 395 iph2->sendbuf = quick_ir1mx(iph2, body, hash);
330 396 if (iph2->sendbuf == NULL)
331 397 goto end;
332 398
333 399 /* send the packet, add to the schedule to resend */
334 400 iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
335 401 if (isakmp_ph2resend(iph2) == -1)
336 402 goto end;
337 403
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
338 404 /* change status of isakmp status entry */
339 405 iph2->status = PHASE2ST_MSG1SENT;
340 406
341 407 error = 0;
342 408
343 409 end:
344 410 if (body != NULL)
345 411 rc_vfree(body);
346 412 if (hash != NULL)
347 413 rc_vfree(hash);
414 + if (nat_oai != NULL)
415 + rc_vfree(nat_oai);
416 + if (nat_oar != NULL)
417 + rc_vfree(nat_oar);
348 418
349 419 return error;
350 420 }
351 421
352 422 /*
353 423 * receive from responder
354 - * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
424 + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
355 425 */
356 426 int
357 427 quick_i2recv(struct ph2handle *iph2, rc_vchar_t *msg0)
358 428 {
359 429 rc_vchar_t *msg = NULL;
360 430 rc_vchar_t *hbuf = NULL; /* for hash computing. */
361 431 rc_vchar_t *pbuf = NULL; /* for payload parsing */
432 + rc_vchar_t *idci = NULL;
433 + rc_vchar_t *idcr = NULL;
362 434 struct isakmp_parse_t *pa;
363 435 struct isakmp *isakmp = (struct isakmp *)msg0->v;
364 436 struct isakmp_pl_hash *hash = NULL;
365 - int f_id;
366 437 char *p;
367 438 int tlen;
368 439 int error = ISAKMP_INTERNAL_ERROR;
369 440
370 441 /* validity check */
371 442 if (iph2->status != PHASE2ST_MSG1SENT) {
372 443 plog(PLOG_INTERR, PLOGLOC, NULL,
373 444 "status mismatched %d.\n", iph2->status);
374 445 goto end;
375 446 }
376 447
377 448 /* decrypt packet */
378 449 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
379 450 isakmp_log(0, 0, iph2->ph1->remote, 0,
380 451 PLOG_PROTOERR, PLOGLOC,
381 452 "Packet wasn't encrypted.\n");
382 453 goto end;
383 454 }
384 455 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
385 456 if (msg == NULL)
386 457 goto end;
387 458
388 459 /* create buffer for validating HASH(2) */
389 460 /*
390 461 * ordering rule:
391 462 * 1. the first one must be HASH
392 463 * 2. the second one must be SA (added in isakmp-oakley-05!)
393 464 * 3. two IDs must be considered as IDci, then IDcr
394 465 */
395 466 pbuf = isakmp_parse(msg);
396 467 if (pbuf == NULL)
397 468 goto end;
398 469 pa = (struct isakmp_parse_t *)pbuf->v;
399 470
400 471 /* HASH payload is fixed postion */
401 472 if (pa->type != ISAKMP_NPTYPE_HASH) {
402 473 isakmp_log(0, 0, iph2->ph1->remote, 0,
403 474 PLOG_PROTOERR, PLOGLOC,
404 475 "received invalid next payload type %d, "
405 476 "expecting %d.\n",
406 477 pa->type, ISAKMP_NPTYPE_HASH);
407 478 goto end;
408 479 }
409 480 hash = (struct isakmp_pl_hash *)pa->ptr;
410 481 pa++;
411 482
412 483 /*
413 484 * this restriction was introduced in isakmp-oakley-05.
414 485 * we do not check this for backward compatibility.
415 486 * TODO: command line/config file option to enable/disable this code
416 487 */
417 488 /* HASH payload is fixed postion */
418 489 if (pa->type != ISAKMP_NPTYPE_SA) {
419 490 isakmp_log(0, 0, iph2->ph1->remote, 0,
420 491 PLOG_PROTOWARN, PLOGLOC,
421 492 "received invalid next payload type %d, "
422 493 "expecting %d.\n",
423 494 pa->type, ISAKMP_NPTYPE_HASH);
424 495 }
425 496
426 497 /* allocate buffer for computing HASH(2) */
427 498 tlen = iph2->nonce->l
428 499 + get_uint32(&isakmp->len) - sizeof(*isakmp);
429 500 hbuf = rc_vmalloc(tlen);
430 501 if (hbuf == NULL) {
431 502 plog(PLOG_INTERR, PLOGLOC, NULL,
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
432 503 "failed to get hash buffer.\n");
433 504 goto end;
434 505 }
435 506 p = hbuf->v + iph2->nonce->l; /* retain the space for Ni_b */
436 507
437 508 /*
438 509 * parse the payloads.
439 510 * copy non-HASH payloads into hbuf, so that we can validate HASH.
440 511 */
441 512 iph2->sa_ret = NULL;
442 - f_id = 0; /* flag to use checking ID */
443 513 tlen = 0; /* count payload length except of HASH payload. */
444 514 for (; pa->type; pa++) {
445 515
446 516 /* copy to buffer for HASH */
447 517 /* Don't modify the payload */
448 518 memcpy(p, pa->ptr, pa->len);
449 519
450 520 switch (pa->type) {
451 521 case ISAKMP_NPTYPE_SA:
452 522 if (iph2->sa_ret != NULL) {
453 523 plog(PLOG_PROTOERR, PLOGLOC, NULL,
454 524 "Ignored, multiple SA "
455 525 "isn't supported.\n");
456 526 break;
457 527 }
458 528 if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0)
459 529 goto end;
460 530 break;
461 531
462 532 case ISAKMP_NPTYPE_NONCE:
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
463 533 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
464 534 goto end;
465 535 break;
466 536
467 537 case ISAKMP_NPTYPE_KE:
468 538 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
469 539 goto end;
470 540 break;
471 541
472 542 case ISAKMP_NPTYPE_ID:
473 - {
474 - rc_vchar_t *vp;
475 -
476 - /* check ID value */
477 - if (f_id == 0) {
478 - /* for IDci */
479 - f_id = 1;
480 - vp = iph2->id;
543 + if (idci == NULL) {
544 + if (isakmp_p2ph(&idci, pa->ptr) < 0)
545 + goto end;
546 + } else if (idcr == NULL) {
547 + if (isakmp_p2ph(&idcr, pa->ptr) < 0)
548 + goto end;
481 549 } else {
482 - /* for IDcr */
483 - vp = iph2->id_p;
484 550 }
485 -
486 - if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) {
487 -
488 - plog(PLOG_PROTOERR, PLOGLOC, NULL,
489 - "mismatched ID was returned.\n");
490 - error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
491 - goto end;
492 - }
493 - }
494 551 break;
495 552
496 553 case ISAKMP_NPTYPE_N:
497 554 isakmp_check_notify(pa->ptr, iph2->ph1);
498 555 break;
499 556
500 557 #ifdef ENABLE_NATT
501 558 case ISAKMP_NPTYPE_NATOA_DRAFT:
502 559 case ISAKMP_NPTYPE_NATOA_RFC:
560 +#ifdef sun
561 + /* DON'T ignore original source/destination. */
562 + {
563 + struct sockaddr_storage addr;
564 + struct sockaddr *daddr;
565 + uint8_t prefix;
566 + uint16_t ul_proto;
567 + rc_vchar_t *vp = NULL;
568 +
569 + if (isakmp_p2ph(&vp, pa->ptr) < 0)
570 + goto end;
571 +
572 + error = ipsecdoi_id2sockaddr(vp,
573 + (struct sockaddr *) &addr,
574 + &prefix, &ul_proto);
575 +
576 + rc_vfree(vp);
577 +
578 + if (error)
579 + goto end;
580 +
581 + daddr = rcs_sadup((struct sockaddr *) &addr);
582 + if (daddr == NULL)
583 + goto end;
584 +
585 + if (iph2->natoa_src == NULL)
586 + iph2->natoa_src = daddr;
587 + else if (iph2->natoa_dst == NULL)
588 + iph2->natoa_dst = daddr;
589 + else {
590 + racoon_free(daddr);
591 + goto end;
592 + }
593 + }
594 +#else
503 595 /* Ignore original source/destination messages */
596 +#endif
504 597 break;
505 598 #endif
506 599
507 600 default:
508 601 /* don't send information, see ident_r1recv() */
509 602 isakmp_log(0, 0, iph2->ph1->remote, 0,
510 603 PLOG_PROTOERR, PLOGLOC,
511 604 "ignore the packet, "
512 605 "received unexpecting payload type %d.\n",
513 606 pa->type);
514 607 goto end;
515 608 }
516 609
517 610 p += pa->len;
518 611
519 612 /* compute true length of payload. */
520 613 tlen += pa->len;
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
521 614 }
522 615
523 616 /* payload existency check */
524 617 if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
525 618 isakmp_log(0, 0, iph2->ph1->remote, 0,
526 619 PLOG_PROTOERR, PLOGLOC,
527 620 "few isakmp message received.\n");
528 621 goto end;
529 622 }
530 623
624 + /* identity check */
625 + if (idci != NULL) {
626 + struct sockaddr_storage proposed_addr, got_addr;
627 + uint8_t proposed_prefix, got_prefix;
628 + uint16_t proposed_ulproto, got_ulproto;
629 +
630 + error = ipsecdoi_id2sockaddr(iph2->id,
631 + (struct sockaddr *) &proposed_addr,
632 + &proposed_prefix, &proposed_ulproto);
633 + if (error)
634 + goto end;
635 +
636 + error = ipsecdoi_id2sockaddr(idci,
637 + (struct sockaddr *) &got_addr,
638 + &got_prefix, &got_ulproto);
639 + if (error)
640 + goto end;
641 +
642 + if (proposed_prefix != got_prefix
643 + || proposed_ulproto != got_ulproto) {
644 + plog(PLOG_DEBUG, PLOGLOC, NULL,
645 + "IDci prefix/ulproto does not match proposal.\n");
646 + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
647 + goto end;
648 + }
649 +
650 + if (rcs_cmpsa((struct sockaddr *) &proposed_addr,
651 + (struct sockaddr *) &got_addr) == 0) {
652 + plog(PLOG_DEBUG, PLOGLOC, NULL,
653 + "IDci matches proposal.\n");
654 +#ifdef ENABLE_NATT
655 + } else if (iph2->natoa_src != NULL
656 + && rcs_cmpsa_wop(iph2->natoa_src,
657 + (struct sockaddr *) &got_addr) == 0
658 + && extract_port((struct sockaddr *) &proposed_addr) ==
659 + extract_port((struct sockaddr *) &got_addr)) {
660 + plog(PLOG_DEBUG, PLOGLOC, NULL,
661 + "IDci matches NAT-OAi.\n");
662 +#endif
663 + } else {
664 + plog(PLOG_INTERR, PLOGLOC, NULL,
665 + "mismatched IDci was returned.\n");
666 + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
667 + goto end;
668 + }
669 + }
670 + if (idcr != NULL) {
671 + struct sockaddr_storage proposed_addr, got_addr;
672 + uint8_t proposed_prefix, got_prefix;
673 + uint16_t proposed_ulproto, got_ulproto;
674 +
675 + error = ipsecdoi_id2sockaddr(iph2->id_p,
676 + (struct sockaddr *) &proposed_addr,
677 + &proposed_prefix, &proposed_ulproto);
678 + if (error)
679 + goto end;
680 +
681 + error = ipsecdoi_id2sockaddr(idcr,
682 + (struct sockaddr *) &got_addr,
683 + &got_prefix, &got_ulproto);
684 + if (error)
685 + goto end;
686 +
687 + if (proposed_prefix != got_prefix
688 + || proposed_ulproto != got_ulproto) {
689 + plog(PLOG_DEBUG, PLOGLOC, NULL,
690 + "IDcr prefix/ulproto does not match proposal.\n");
691 + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
692 + goto end;
693 + }
694 +
695 + if (rcs_cmpsa((struct sockaddr *) &proposed_addr,
696 + (struct sockaddr *) &got_addr) == 0) {
697 + plog(PLOG_DEBUG, PLOGLOC, NULL,
698 + "IDcr matches proposal.\n");
699 +#ifdef ENABLE_NATT
700 + } else if (iph2->natoa_dst != NULL
701 + && rcs_cmpsa_wop(iph2->natoa_dst,
702 + (struct sockaddr *) &got_addr) == 0
703 + && extract_port((struct sockaddr *) &proposed_addr) ==
704 + extract_port((struct sockaddr *) &got_addr)) {
705 + plog(PLOG_DEBUG, PLOGLOC, NULL,
706 + "IDcr matches NAT-OAr.\n");
707 +#endif
708 + } else {
709 + plog(PLOG_INTERR, PLOGLOC, NULL,
710 + "mismatched IDcr was returned.\n");
711 + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
712 + goto end;
713 + }
714 + }
715 +
531 716 /* Fixed buffer for calculating HASH */
532 717 memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
533 718 plog(PLOG_DEBUG, PLOGLOC, NULL,
534 719 "HASH allocated:hbuf->l=%d actual:tlen=%d\n",
535 720 hbuf->l, tlen + iph2->nonce->l);
536 721 /* adjust buffer length for HASH */
537 722 hbuf->l = iph2->nonce->l + tlen;
538 723
539 724 /* validate HASH(2) */
540 725 {
541 726 char *r_hash;
542 727 rc_vchar_t *my_hash = NULL;
543 728 int result;
544 729
545 730 r_hash = (char *)hash + sizeof(*hash);
546 731
547 732 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(2) received:");
548 733 plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
549 734
550 735 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
551 736 if (my_hash == NULL)
552 737 goto end;
553 738
554 739 result = memcmp(my_hash->v, r_hash, my_hash->l);
555 740 rc_vfree(my_hash);
556 741
557 742 if (result) {
558 743 isakmp_log(0, 0, iph2->ph1->remote, 0,
559 744 PLOG_PROTOERR, PLOGLOC,
560 745 "HASH(2) mismatch.\n");
561 746 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
562 747 goto end;
563 748 }
564 749 }
565 750
566 751 /* validity check SA payload sent from responder */
567 752 if (ipsecdoi_checkph2proposal(iph2) < 0) {
568 753 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
569 754 goto end;
570 755 }
571 756
572 757 /* change status of isakmp status entry */
573 758 iph2->status = PHASE2ST_STATUS6;
|
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
574 759
575 760 error = 0;
576 761
577 762 end:
578 763 if (hbuf)
579 764 rc_vfree(hbuf);
580 765 if (pbuf)
581 766 rc_vfree(pbuf);
582 767 if (msg)
583 768 rc_vfree(msg);
769 + if (idci)
770 + rc_vfree(idci);
771 + if (idcr)
772 + rc_vfree(idcr);
584 773
585 774 if (error) {
586 775 VPTRINIT(iph2->sa_ret);
587 776 VPTRINIT(iph2->nonce_p);
588 777 VPTRINIT(iph2->dhpub_p);
589 778 VPTRINIT(iph2->id);
590 779 VPTRINIT(iph2->id_p);
780 +#ifdef ENABLE_NATT
781 + if (iph2->natoa_src) {
782 + racoon_free(iph2->natoa_src);
783 + iph2->natoa_src = NULL;
784 + }
785 + if (iph2->natoa_dst) {
786 + racoon_free(iph2->natoa_dst);
787 + iph2->natoa_dst = NULL;
788 + }
789 +#endif
591 790 }
592 791
593 792 return error;
594 793 }
595 794
795 +static int
796 +fill_in_ipsec_sas(struct ph2handle *iph2)
797 +{
798 + /*
799 + * NOTE: The OpenSolaris kernel can queue up packets on a larval SA
800 + * such that when the SA is filled-in via SADB_UPDATE, these packets
801 + * can be immediately processed. If the reply packet is generated
802 + * in-kernel (e.g. ICMP_ECHO processing), an additonal ACQUIRE can
803 + * be sent if there is not a corresponding outbound SA waiting in
804 + * the wings. We therefore perform SADB_ADD first so that if an
805 + * outbound SA is needed immediately during SADB_UPDATE processing,
806 + * it is ready.
807 + */
808 +
809 + plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendadd\n");
810 + if (pk_sendadd(iph2) < 0) {
811 + plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
812 + return (-1);
813 + }
814 + plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
815 +
816 + plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
817 + if (pk_sendupdate(iph2) < 0) {
818 + plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
819 + return (-1);
820 + }
821 + plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
822 +
823 + return (0);
824 +}
825 +
596 826 /*
597 827 * send to responder
598 828 * HDR*, HASH(3)
599 829 */
600 830 int
601 831 quick_i2send(struct ph2handle *iph2, rc_vchar_t *msg0)
602 832 {
603 833 rc_vchar_t *msg = NULL;
604 834 rc_vchar_t *buf = NULL;
605 835 rc_vchar_t *hash = NULL;
606 836 char *p = NULL;
607 837 int tlen;
608 838 int error = ISAKMP_INTERNAL_ERROR;
609 839
610 840 /* validity check */
611 841 if (iph2->status != PHASE2ST_STATUS6) {
612 842 plog(PLOG_INTERR, PLOGLOC, NULL,
613 843 "status mismatched %d.\n", iph2->status);
614 844 goto end;
615 845 }
616 846
617 847 /* generate HASH(3) */
618 848 {
619 849 rc_vchar_t *tmp = NULL;
620 850
621 851 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(3) generate\n");
622 852
623 853 tmp = rc_vmalloc(iph2->nonce->l + iph2->nonce_p->l);
624 854 if (tmp == NULL) {
625 855 plog(PLOG_INTERR, PLOGLOC, NULL,
626 856 "failed to get hash buffer.\n");
627 857 goto end;
628 858 }
629 859 memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l);
630 860 memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l);
631 861
632 862 hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
633 863 rc_vfree(tmp);
634 864
635 865 if (hash == NULL)
636 866 goto end;
637 867 }
638 868
639 869 /* create buffer for isakmp payload */
640 870 tlen = sizeof(struct isakmp)
641 871 + sizeof(struct isakmp_gen) + hash->l;
642 872 buf = rc_vmalloc(tlen);
643 873 if (buf == NULL) {
644 874 plog(PLOG_INTERR, PLOGLOC, NULL,
645 875 "failed to get buffer to send.\n");
646 876 goto end;
647 877 }
648 878
649 879 /* create isakmp header */
650 880 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
651 881 if (p == NULL)
652 882 goto end;
653 883
654 884 /* add HASH(3) payload */
655 885 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
656 886
657 887 #ifdef HAVE_PRINT_ISAKMP_C
658 888 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
659 889 #endif
660 890
661 891 /* encoding */
662 892 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
663 893 if (iph2->sendbuf == NULL)
664 894 goto end;
665 895
666 896 /* if there is commit bit, need resending */
667 897 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
668 898 /* send the packet, add to the schedule to resend */
669 899 iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
670 900 if (isakmp_ph2resend(iph2) == -1)
671 901 goto end;
672 902 } else {
673 903 /* send the packet */
674 904 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
675 905 goto end;
676 906 }
677 907
678 908 /* the sending message is added to the received-list. */
679 909 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
680 910 iph2->sendbuf, msg0, iph2->ph1->rmconf) == -1) {
681 911 plog(PLOG_INTERR , PLOGLOC, NULL,
682 912 "failed to add a response packet to the tree.\n");
683 913 goto end;
684 914 }
685 915
686 916 /* compute both of KEYMATs */
687 917 if (oakley_compute_keymat(iph2, INITIATOR) < 0)
688 918 goto end;
689 919
690 920 iph2->status = PHASE2ST_ADDSA;
691 921
692 922 #if 0
693 923 /* don't anything if local test mode. */
694 924 if (f_local) {
695 925 error = 0;
696 926 goto end;
|
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
697 927 }
698 928 #endif
699 929
700 930 /* if there is commit bit don't set up SA now. */
701 931 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
702 932 iph2->status = PHASE2ST_COMMIT;
703 933 error = 0;
704 934 goto end;
705 935 }
706 936
707 - /* Do UPDATE for initiator */
708 - plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
709 - if (pk_sendupdate(iph2) < 0) {
710 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
711 - goto end;
712 - }
713 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
937 + plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas");
938 + error = fill_in_ipsec_sas(iph2);
714 939
715 - /* Do ADD for responder */
716 - if (pk_sendadd(iph2) < 0) {
717 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
718 - goto end;
719 - }
720 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
721 -
722 - error = 0;
723 -
724 940 end:
725 941 if (buf != NULL)
726 942 rc_vfree(buf);
727 943 if (msg != NULL)
728 944 rc_vfree(msg);
729 945 if (hash != NULL)
730 946 rc_vfree(hash);
731 947
732 948 return error;
733 949 }
734 950
735 951 /*
736 952 * receive from responder
737 953 * HDR#*, HASH(4), notify
738 954 */
739 955 int
740 956 quick_i3recv(struct ph2handle *iph2, rc_vchar_t *msg0)
741 957 {
742 958 rc_vchar_t *msg = NULL;
743 959 rc_vchar_t *pbuf = NULL; /* for payload parsing */
744 960 struct isakmp_parse_t *pa;
745 961 struct isakmp_pl_hash *hash = NULL;
746 962 rc_vchar_t *notify = NULL;
747 963 int error = ISAKMP_INTERNAL_ERROR;
748 964
749 965 /* validity check */
750 966 if (iph2->status != PHASE2ST_COMMIT) {
751 967 plog(PLOG_INTERR, PLOGLOC, NULL,
752 968 "status mismatched %d.\n", iph2->status);
753 969 goto end;
754 970 }
755 971
756 972 /* decrypt packet */
757 973 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
758 974 isakmp_log(0, 0, iph2->ph1->remote, 0,
759 975 PLOG_PROTOERR, PLOGLOC,
760 976 "Packet wasn't encrypted.\n");
761 977 goto end;
762 978 }
763 979 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
764 980 if (msg == NULL)
765 981 goto end;
766 982
767 983 /* validate the type of next payload */
768 984 pbuf = isakmp_parse(msg);
769 985 if (pbuf == NULL)
770 986 goto end;
771 987
772 988 for (pa = (struct isakmp_parse_t *)pbuf->v;
773 989 pa->type != ISAKMP_NPTYPE_NONE;
774 990 pa++) {
775 991
776 992 switch (pa->type) {
777 993 case ISAKMP_NPTYPE_HASH:
778 994 hash = (struct isakmp_pl_hash *)pa->ptr;
779 995 break;
780 996 case ISAKMP_NPTYPE_N:
781 997 if (notify != NULL) {
782 998 plog(PLOG_INTWARN, PLOGLOC, NULL,
783 999 "Ignoring multiple notifications\n");
784 1000 break;
785 1001 }
786 1002 isakmp_check_notify(pa->ptr, iph2->ph1);
787 1003 notify = rc_vmalloc(pa->len);
788 1004 if (notify == NULL) {
789 1005 plog(PLOG_INTERR, PLOGLOC, NULL,
790 1006 "failed to get notify buffer.\n");
791 1007 goto end;
792 1008 }
793 1009 memcpy(notify->v, pa->ptr, notify->l);
794 1010 break;
795 1011 default:
796 1012 /* don't send information, see ident_r1recv() */
797 1013 isakmp_log(0, 0, iph2->ph1->remote, 0,
798 1014 PLOG_PROTOERR, PLOGLOC,
799 1015 "ignore the packet, "
800 1016 "received unexpecting payload type %d.\n",
801 1017 pa->type);
802 1018 goto end;
803 1019 }
804 1020 }
805 1021
806 1022 /* payload existency check */
807 1023 if (hash == NULL) {
808 1024 isakmp_log(0, 0, iph2->ph1->remote, 0,
809 1025 PLOG_PROTOERR, PLOGLOC,
810 1026 "few isakmp message received.\n");
811 1027 goto end;
812 1028 }
813 1029
814 1030 /* validate HASH(4) */
815 1031 {
816 1032 char *r_hash;
817 1033 rc_vchar_t *my_hash = NULL;
818 1034 rc_vchar_t *tmp = NULL;
819 1035 int result;
820 1036
821 1037 r_hash = (char *)hash + sizeof(*hash);
822 1038
823 1039 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(4) validate:");
824 1040 plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
825 1041
826 1042 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
827 1043 rc_vfree(tmp);
828 1044 if (my_hash == NULL)
829 1045 goto end;
830 1046
831 1047 result = memcmp(my_hash->v, r_hash, my_hash->l);
832 1048 rc_vfree(my_hash);
833 1049
834 1050 if (result) {
835 1051 isakmp_log(0, 0, iph2->ph1->remote, 0,
836 1052 PLOG_PROTOERR, PLOGLOC,
837 1053 "HASH(4) mismatch.\n");
838 1054 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
839 1055 goto end;
840 1056 }
841 1057 }
842 1058
843 1059 iph2->status = PHASE2ST_ADDSA;
|
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
844 1060 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */
845 1061
846 1062 #if 0
847 1063 /* don't anything if local test mode. */
848 1064 if (f_local) {
849 1065 error = 0;
850 1066 goto end;
851 1067 }
852 1068 #endif
853 1069
854 - /* Do UPDATE for initiator */
855 - plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
856 - if (pk_sendupdate(iph2) < 0) {
857 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
858 - goto end;
859 - }
860 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
1070 + plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas");
1071 + error = fill_in_ipsec_sas(iph2);
861 1072
862 - /* Do ADD for responder */
863 - if (pk_sendadd(iph2) < 0) {
864 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
865 - goto end;
866 - }
867 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
868 -
869 - error = 0;
870 -
871 1073 end:
872 1074 if (msg != NULL)
873 1075 rc_vfree(msg);
874 1076 if (pbuf != NULL)
875 1077 rc_vfree(pbuf);
876 1078 if (notify != NULL)
877 1079 rc_vfree(notify);
878 1080
879 1081 return error;
880 1082 }
881 1083
882 1084 /*
883 1085 * receive from initiator
884 - * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
1086 + * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
885 1087 */
886 1088 int
887 1089 quick_r1recv(struct ph2handle *iph2, rc_vchar_t *msg0)
888 1090 {
889 1091 rc_vchar_t *msg = NULL;
890 1092 rc_vchar_t *hbuf = NULL; /* for hash computing. */
891 1093 rc_vchar_t *pbuf = NULL; /* for payload parsing */
892 1094 struct isakmp_parse_t *pa;
893 1095 struct isakmp *isakmp = (struct isakmp *)msg0->v;
894 1096 struct isakmp_pl_hash *hash = NULL;
895 1097 char *p;
896 1098 int tlen;
897 1099 int f_id_order; /* for ID payload detection */
898 1100 int error = ISAKMP_INTERNAL_ERROR;
899 1101
900 1102 /* validity check */
901 1103 if (iph2->status != PHASE2ST_START) {
902 1104 plog(PLOG_INTERR, PLOGLOC, NULL,
903 1105 "status mismatched %d.\n", iph2->status);
904 1106 goto end;
905 1107 }
906 1108
907 1109 /* decrypting */
908 1110 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
909 1111 isakmp_log(0, 0, iph2->ph1->remote, 0,
910 1112 PLOG_PROTOERR, PLOGLOC,
911 1113 "Packet wasn't encrypted.\n");
912 1114 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
913 1115 goto end;
914 1116 }
915 1117 /* decrypt packet */
916 1118 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
917 1119 if (msg == NULL)
918 1120 goto end;
919 1121
920 1122 /* create buffer for using to validate HASH(1) */
921 1123 /*
922 1124 * ordering rule:
923 1125 * 1. the first one must be HASH
924 1126 * 2. the second one must be SA (added in isakmp-oakley-05!)
925 1127 * 3. two IDs must be considered as IDci, then IDcr
926 1128 */
927 1129 pbuf = isakmp_parse(msg);
928 1130 if (pbuf == NULL)
929 1131 goto end;
930 1132 pa = (struct isakmp_parse_t *)pbuf->v;
931 1133
932 1134 /* HASH payload is fixed postion */
933 1135 if (pa->type != ISAKMP_NPTYPE_HASH) {
934 1136 isakmp_log(0, 0, iph2->ph1->remote, 0,
935 1137 PLOG_PROTOERR, PLOGLOC,
936 1138 "received invalid next payload type %d, "
937 1139 "expecting %d.\n",
938 1140 pa->type, ISAKMP_NPTYPE_HASH);
939 1141 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
940 1142 goto end;
941 1143 }
942 1144 hash = (struct isakmp_pl_hash *)pa->ptr;
943 1145 pa++;
944 1146
945 1147 /*
946 1148 * this restriction was introduced in isakmp-oakley-05.
947 1149 * we do not check this for backward compatibility.
948 1150 * TODO: command line/config file option to enable/disable this code
949 1151 */
950 1152 /* HASH payload is fixed postion */
951 1153 if (pa->type != ISAKMP_NPTYPE_SA) {
952 1154 isakmp_log(0, 0, iph2->ph1->remote, 0,
953 1155 PLOG_PROTOERR, PLOGLOC,
954 1156 "received invalid next payload type %d, "
955 1157 "expecting %d.\n",
956 1158 pa->type, ISAKMP_NPTYPE_HASH);
957 1159 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
958 1160 }
959 1161
960 1162 /* allocate buffer for computing HASH(1) */
961 1163 tlen = get_uint32(&isakmp->len) - sizeof(*isakmp);
962 1164 hbuf = rc_vmalloc(tlen);
963 1165 if (hbuf == NULL) {
964 1166 plog(PLOG_INTERR, PLOGLOC, NULL,
965 1167 "failed to get hash buffer.\n");
966 1168 goto end;
967 1169 }
968 1170 p = hbuf->v;
969 1171
970 1172 /*
971 1173 * parse the payloads.
972 1174 * copy non-HASH payloads into hbuf, so that we can validate HASH.
973 1175 */
974 1176 iph2->sa = NULL; /* we don't support multi SAs. */
975 1177 iph2->nonce_p = NULL;
976 1178 iph2->dhpub_p = NULL;
977 1179 iph2->id_p = NULL;
978 1180 iph2->id = NULL;
979 1181 tlen = 0; /* count payload length except of HASH payload. */
980 1182
981 1183 /*
982 1184 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
983 1185 * illegal case, but logged. First ID payload is to be IDi2.
984 1186 * And next ID payload is to be IDr2.
985 1187 */
986 1188 f_id_order = 0;
987 1189
988 1190 for (; pa->type; pa++) {
989 1191
990 1192 /* copy to buffer for HASH */
991 1193 /* Don't modify the payload */
992 1194 memcpy(p, pa->ptr, pa->len);
993 1195
994 1196 if (pa->type != ISAKMP_NPTYPE_ID)
995 1197 f_id_order = 0;
996 1198
997 1199 switch (pa->type) {
998 1200 case ISAKMP_NPTYPE_SA:
999 1201 if (iph2->sa != NULL) {
1000 1202 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1001 1203 "Multi SAs isn't supported.\n");
1002 1204 goto end;
1003 1205 }
1004 1206 if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0)
1005 1207 goto end;
1006 1208 break;
1007 1209
1008 1210 case ISAKMP_NPTYPE_NONCE:
1009 1211 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
1010 1212 goto end;
1011 1213 break;
1012 1214
1013 1215 case ISAKMP_NPTYPE_KE:
1014 1216 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
1015 1217 goto end;
1016 1218 break;
1017 1219
1018 1220 case ISAKMP_NPTYPE_ID:
1019 1221 if (iph2->id_p == NULL) {
1020 1222 /* for IDci */
1021 1223 f_id_order++;
1022 1224
1023 1225 if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0)
1024 1226 goto end;
1025 1227
1026 1228 } else if (iph2->id == NULL) {
1027 1229 /* for IDcr */
1028 1230 if (f_id_order == 0) {
1029 1231 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1030 1232 "IDr2 payload is not "
1031 1233 "immediatelly followed "
1032 1234 "by IDi2. We allowed.\n");
1033 1235 /* XXX we allowed in this case. */
1034 1236 }
1035 1237
1036 1238 if (isakmp_p2ph(&iph2->id, pa->ptr) < 0)
1037 1239 goto end;
1038 1240 } else {
1039 1241 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1040 1242 "received too many ID payloads.\n");
1041 1243 plogdump(PLOG_PROTOERR, PLOGLOC, 0, iph2->id->v, iph2->id->l);
1042 1244 error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1043 1245 goto end;
|
↓ open down ↓ |
149 lines elided |
↑ open up ↑ |
1044 1246 }
1045 1247 break;
1046 1248
1047 1249 case ISAKMP_NPTYPE_N:
1048 1250 isakmp_check_notify(pa->ptr, iph2->ph1);
1049 1251 break;
1050 1252
1051 1253 #ifdef ENABLE_NATT
1052 1254 case ISAKMP_NPTYPE_NATOA_DRAFT:
1053 1255 case ISAKMP_NPTYPE_NATOA_RFC:
1256 +#ifdef sun
1257 + {
1258 + struct sockaddr_storage addr;
1259 + struct sockaddr *daddr;
1260 + uint8_t prefix;
1261 + uint16_t ul_proto;
1262 + rc_vchar_t *vp = NULL;
1263 +
1264 + if (isakmp_p2ph(&vp, pa->ptr) < 0)
1265 + goto end;
1266 +
1267 + error = ipsecdoi_id2sockaddr(vp,
1268 + (struct sockaddr *) &addr,
1269 + &prefix, &ul_proto);
1270 +
1271 + rc_vfree(vp);
1272 +
1273 + if (error)
1274 + goto end;
1275 +
1276 + daddr = rcs_sadup((struct sockaddr *) &addr);
1277 + if (daddr == NULL)
1278 + goto end;
1279 +
1280 + if (iph2->natoa_dst == NULL)
1281 + iph2->natoa_dst = daddr;
1282 + else if (iph2->natoa_src == NULL)
1283 + iph2->natoa_src = daddr;
1284 + else {
1285 + racoon_free(daddr);
1286 + goto end;
1287 + }
1288 + }
1289 +#else
1054 1290 /* Ignore original source/destination messages */
1291 +#endif
1055 1292 break;
1056 1293 #endif
1057 1294
1058 1295 default:
1059 1296 isakmp_log(0, 0, iph2->ph1->remote, 0,
1060 1297 PLOG_PROTOERR, PLOGLOC,
1061 1298 "ignore the packet, "
1062 1299 "received unexpecting payload type %d.\n",
1063 1300 pa->type);
1064 1301 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1065 1302 goto end;
1066 1303 }
1067 1304
1068 1305 p += pa->len;
1069 1306
1070 1307 /* compute true length of payload. */
1071 1308 tlen += pa->len;
1072 1309 }
1073 1310
1074 1311 /* payload existency check */
1075 1312 if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
1076 1313 isakmp_log(0, 0, iph2->ph1->remote, 0,
1077 1314 PLOG_PROTOERR, PLOGLOC,
1078 1315 "few isakmp message received.\n");
1079 1316 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1080 1317 goto end;
1081 1318 }
1082 1319
1083 1320 if (iph2->id_p) {
1084 1321 plog(PLOG_DEBUG, PLOGLOC, NULL, "received IDci2:");
1085 1322 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id_p->v, iph2->id_p->l);
1086 1323 }
1087 1324 if (iph2->id) {
1088 1325 plog(PLOG_DEBUG, PLOGLOC, NULL, "received IDcr2:");
1089 1326 plogdump(PLOG_DEBUG, PLOGLOC, 0, iph2->id->v, iph2->id->l);
1090 1327 }
1091 1328
1092 1329 /* adjust buffer length for HASH */
1093 1330 hbuf->l = tlen;
1094 1331
1095 1332 /* validate HASH(1) */
1096 1333 {
1097 1334 char *r_hash;
1098 1335 rc_vchar_t *my_hash = NULL;
1099 1336 int result;
1100 1337
1101 1338 r_hash = (caddr_t)hash + sizeof(*hash);
1102 1339
1103 1340 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(1) validate:");
1104 1341 plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
1105 1342
1106 1343 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
1107 1344 if (my_hash == NULL)
1108 1345 goto end;
1109 1346
1110 1347 result = memcmp(my_hash->v, r_hash, my_hash->l);
1111 1348 rc_vfree(my_hash);
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
1112 1349
1113 1350 if (result) {
1114 1351 isakmp_log(0, 0, iph2->ph1->remote, 0,
1115 1352 PLOG_DEBUG, PLOGLOC,
1116 1353 "HASH(1) mismatch.\n");
1117 1354 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1118 1355 goto end;
1119 1356 }
1120 1357 }
1121 1358
1359 +#ifndef sun
1122 1360 /* get sainfo */
1123 1361 error = get_sainfo_r(iph2);
1124 1362 if (error) {
1125 1363 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1126 1364 "failed to get sainfo.\n");
1127 1365 goto end;
1128 1366 }
1129 1367
1130 1368 /* check the existence of ID payload and create responder's proposal */
1131 1369 error = get_proposal_r(iph2);
1132 1370 switch (error) {
1133 1371 #ifdef notyet
1134 1372 case -2:
1135 1373 /* generate a policy template from peer's proposal */
1136 1374 if (set_proposal_from_proposal(iph2)) {
1137 1375 plog(PLOG_INTERR, PLOGLOC, NULL,
1138 1376 "failed to generate a proposal template "
1139 1377 "from client's proposal.\n");
1140 1378 return ISAKMP_INTERNAL_ERROR;
1141 1379 }
1142 1380 /*FALLTHROUGH*/
1143 1381 #endif
1144 1382 case 0:
1145 1383 /* select single proposal or reject it. */
1146 1384 if (ipsecdoi_selectph2proposal(iph2) < 0) {
1147 1385 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1148 1386 goto end;
1149 1387 }
1150 1388 break;
1151 1389 default:
1152 1390 plog(PLOG_INTERR, PLOGLOC, NULL,
1153 1391 "failed to get proposal for responder.\n");
1154 1392 goto end;
1155 1393 }
1156 1394
1157 1395 /* check KE and attribute of PFS */
1158 1396 if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
1159 1397 plog(PLOG_PROTOERR, PLOGLOC, NULL,
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
1160 1398 "no PFS is specified, but peer sends KE.\n");
1161 1399 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1162 1400 goto end;
1163 1401 }
1164 1402 if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
1165 1403 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1166 1404 "PFS is specified, but peer doesn't sends KE.\n");
1167 1405 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1168 1406 goto end;
1169 1407 }
1408 + /* change status of isakmp status entry */
1409 + iph2->status = PHASE2ST_STATUS2;
1170 1410
1411 +#endif /* sun/OpenSolaris */
1412 +
1171 1413 /*
1172 1414 * save the packet from the initiator in order to resend the
1173 1415 * responder's first packet against this packet.
1174 1416 */
1175 1417 iph2->msg1 = rc_vdup(msg0);
1176 1418
1177 - /* change status of isakmp status entry */
1178 - iph2->status = PHASE2ST_STATUS2;
1179 -
1180 1419 error = 0;
1181 1420
1182 1421 end:
1183 1422 if (hbuf)
1184 1423 rc_vfree(hbuf);
1185 1424 if (msg)
1186 1425 rc_vfree(msg);
1187 1426 if (pbuf)
1188 1427 rc_vfree(pbuf);
1189 1428
1190 1429 if (error) {
1191 1430 VPTRINIT(iph2->sa);
1192 1431 VPTRINIT(iph2->nonce_p);
1193 1432 VPTRINIT(iph2->dhpub_p);
1194 1433 VPTRINIT(iph2->id);
1195 1434 VPTRINIT(iph2->id_p);
1435 +#ifdef ENABLE_NATT
1436 + if (iph2->natoa_src) {
1437 + racoon_free(iph2->natoa_src);
1438 + iph2->natoa_src = NULL;
1439 + }
1440 + if (iph2->natoa_dst) {
1441 + racoon_free(iph2->natoa_dst);
1442 + iph2->natoa_dst = NULL;
1443 + }
1444 +#endif
1196 1445 }
1197 1446
1198 1447 return error;
1199 1448 }
1200 1449
1201 1450 /*
1202 1451 * call pfkey_getspi.
1203 1452 */
1204 1453 int
1205 1454 quick_r1prep(struct ph2handle *iph2, rc_vchar_t *msg)
1206 1455 {
1207 1456 int error = ISAKMP_INTERNAL_ERROR;
1208 1457
1209 1458 /* validity check */
1210 1459 if (iph2->status != PHASE2ST_STATUS2) {
1211 1460 plog(PLOG_INTERR, PLOGLOC, NULL,
1212 1461 "status mismatched %d.\n", iph2->status);
1213 1462 goto end;
1214 1463 }
1215 1464
1216 1465 iph2->status = PHASE2ST_GETSPISENT;
1217 1466
1218 1467 /* send getspi message */
1219 1468 if (pk_sendgetspi(iph2) < 0)
1220 1469 goto end;
1221 1470
1222 1471 plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey getspi sent.\n");
1223 1472
1224 1473 iph2->sce = sched_new(ikev1_ipsec_sa_nego_time_limit(iph2->ph1->rmconf),
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
1225 1474 pfkey_timeover_stub, iph2);
1226 1475
1227 1476 error = 0;
1228 1477
1229 1478 end:
1230 1479 return error;
1231 1480 }
1232 1481
1233 1482 /*
1234 1483 * send to initiator
1235 - * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1484 + * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1236 1485 */
1237 1486 int
1238 1487 quick_r2send(struct ph2handle *iph2, rc_vchar_t *msg)
1239 1488 {
1240 1489 rc_vchar_t *body = NULL;
1241 1490 rc_vchar_t *hash = NULL;
1242 1491 struct isakmp_gen *gen;
1243 1492 char *p;
1244 1493 int tlen;
1245 1494 int error = ISAKMP_INTERNAL_ERROR;
1495 + int natoa = ISAKMP_NPTYPE_NONE;
1246 1496 int pfsgroup;
1247 1497 uint8_t *np_p = NULL;
1498 +#ifdef ENABLE_NATT
1499 + rc_vchar_t *nat_oai = NULL;
1500 + rc_vchar_t *nat_oar = NULL;
1501 +#endif
1248 1502
1249 1503 /* validity check */
1250 1504 if (msg != NULL) {
1251 1505 plog(PLOG_INTERR, PLOGLOC, NULL,
1252 1506 "msg has to be NULL in this function.\n");
1253 1507 goto end;
1254 1508 }
1255 1509 if (iph2->status != PHASE2ST_GETSPIDONE) {
1256 1510 plog(PLOG_INTERR, PLOGLOC, NULL,
1257 1511 "status mismatched %d.\n", iph2->status);
1258 1512 goto end;
1259 1513 }
1260 1514
1261 1515 /* update responders SPI */
1262 1516 if (ipsecdoi_updatespi(iph2) < 0) {
1263 1517 plog(PLOG_INTERR, PLOGLOC, NULL, "failed to update spi.\n");
1264 1518 goto end;
1265 1519 }
1266 1520
1267 1521 /* generate NONCE value */
1268 1522 iph2->nonce = eay_set_random(ikev1_nonce_size(iph2->ph1->rmconf));
1269 1523 if (iph2->nonce == NULL)
1270 1524 goto end;
1271 1525
1272 1526 /* generate KE value if need */
1273 1527 pfsgroup = iph2->approval->pfs_group;
1274 1528 if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1275 1529 /* DH group settting if PFS is required. */
1276 1530 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
1277 1531 plog(PLOG_INTERR, PLOGLOC, NULL,
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
1278 1532 "failed to set DH value.\n");
1279 1533 goto end;
1280 1534 }
1281 1535 /* generate DH public value */
1282 1536 if (oakley_dh_generate(iph2->pfsgrp,
1283 1537 &iph2->dhpub, &iph2->dhpriv) < 0) {
1284 1538 goto end;
1285 1539 }
1286 1540 }
1287 1541
1542 +#ifdef ENABLE_NATT
1543 + /*
1544 + * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1545 + * we should send NAT-OA
1546 + */
1547 + if (ipsecdoi_transportmode(iph2->proposal)
1548 + && (iph2->ph1->natt_flags & NAT_DETECTED)) {
1549 + natoa = iph2->ph1->natt_options->payload_nat_oa;
1550 +
1551 + nat_oai = ipsecdoi_sockaddr2id(iph2->dst,
1552 + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
1553 + nat_oar = ipsecdoi_sockaddr2id(iph2->src,
1554 + IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
1555 +
1556 + if (nat_oai == NULL || nat_oar == NULL) {
1557 + plog(PLOG_INTERR, PLOGLOC, NULL,
1558 + "failed to generate NAT-OA payload.\n");
1559 + goto end;
1560 + }
1561 +
1562 + plog(PLOG_DEBUG, PLOGLOC, NULL, "NAT-OAi:\n");
1563 + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oai->v, nat_oai->l);
1564 + plog(PLOG_DEBUG, PLOGLOC, 0, NULL, "NAT-OAr:\n");
1565 + plogdump(PLOG_DEBUG, PLOGLOC, 0, nat_oar->v, nat_oar->l);
1566 + }
1567 +#endif
1568 +
1288 1569 /* create SA;NONCE payload, and KE and ID if need */
1289 1570 tlen = sizeof(*gen) + iph2->sa_ret->l
1290 1571 + sizeof(*gen) + iph2->nonce->l;
1291 1572 if (iph2->dhpub_p != NULL && pfsgroup != 0)
1292 1573 tlen += (sizeof(*gen) + iph2->dhpub->l);
1293 1574 if (iph2->id_p != NULL)
1294 1575 tlen += (sizeof(*gen) + iph2->id_p->l
1295 1576 + sizeof(*gen) + iph2->id->l);
1296 1577
1578 +#ifdef ENABLE_NATT
1579 + if (natoa != ISAKMP_NPTYPE_NONE)
1580 + tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
1581 +#endif
1582 +
1297 1583 body = rc_vmalloc(tlen);
1298 1584 if (body == NULL) {
1299 1585 plog(PLOG_INTERR, PLOGLOC, NULL,
1300 1586 "failed to get buffer to send.\n");
1301 1587 goto end;
1302 1588 }
1303 1589 p = body->v;
1304 1590
1305 1591 /* make SA payload */
1306 1592 p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE);
1307 1593
1308 1594 /* add NONCE payload */
1309 1595 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
1310 1596 p = set_isakmp_payload(p, iph2->nonce,
1311 1597 (iph2->dhpub_p != NULL && pfsgroup != 0)
1312 1598 ? ISAKMP_NPTYPE_KE
1313 1599 : (iph2->id_p != NULL
1314 1600 ? ISAKMP_NPTYPE_ID
1315 - : ISAKMP_NPTYPE_NONE));
1601 + : natoa));
1316 1602
1317 1603 /* add KE payload if need. */
1318 1604 if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1319 1605 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
1320 1606 p = set_isakmp_payload(p, iph2->dhpub,
1321 1607 (iph2->id_p == NULL)
1322 - ? ISAKMP_NPTYPE_NONE
1608 + ? natoa
1323 1609 : ISAKMP_NPTYPE_ID);
1324 1610 }
1325 1611
1326 1612 /* add ID payloads received. */
1327 1613 if (iph2->id_p != NULL) {
1328 1614 /* IDci */
1329 1615 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
1330 1616 /* IDcr */
1331 1617 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
1332 - p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE);
1618 + p = set_isakmp_payload(p, iph2->id, natoa);
1333 1619 }
1620 +#ifdef ENABLE_NATT
1621 + /* NAT-OA */
1622 + if (natoa != ISAKMP_NPTYPE_NONE) {
1623 + p = set_isakmp_payload(p, nat_oai, natoa);
1624 + p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
1625 + }
1626 +#endif
1334 1627
1335 1628 /* add a RESPONDER-LIFETIME notify payload if needed */
1336 1629 {
1337 1630 rc_vchar_t *data = NULL;
1338 1631 struct saprop *pp = iph2->approval;
1339 1632 struct saproto *pr;
1340 1633
1341 1634 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) {
1342 1635 uint32_t v = htonl((uint32_t)pp->lifetime);
1343 1636 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1344 1637 IPSECDOI_ATTR_SA_LD_TYPE_SEC);
1345 1638 if (!data)
1346 1639 goto end;
1347 1640 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1348 1641 (caddr_t)&v, sizeof(v));
1349 1642 if (!data)
1350 1643 goto end;
1351 1644 }
1352 1645 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
1353 1646 uint32_t v = htonl((uint32_t)pp->lifebyte);
1354 1647 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1355 1648 IPSECDOI_ATTR_SA_LD_TYPE_KB);
1356 1649 if (!data)
1357 1650 goto end;
1358 1651 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1359 1652 (caddr_t)&v, sizeof(v));
1360 1653 if (!data)
1361 1654 goto end;
1362 1655 }
1363 1656
1364 1657 /*
1365 1658 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1366 1659 * in the case of SA bundle ?
1367 1660 */
1368 1661 if (data) {
1369 1662 for (pr = pp->head; pr; pr = pr->next) {
1370 1663 body = isakmp_add_pl_n(body, &np_p,
1371 1664 ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
1372 1665 if (!body) {
1373 1666 rc_vfree(data);
1374 1667 return error; /* XXX */
1375 1668 }
1376 1669 }
1377 1670 rc_vfree(data);
1378 1671 }
1379 1672 }
1380 1673
1381 1674 /* generate HASH(2) */
1382 1675 {
1383 1676 rc_vchar_t *tmp;
1384 1677
1385 1678 tmp = rc_vmalloc(iph2->nonce_p->l + body->l);
1386 1679 if (tmp == NULL) {
1387 1680 plog(PLOG_INTERR, PLOGLOC, NULL,
1388 1681 "failed to get hash buffer.\n");
1389 1682 goto end;
1390 1683 }
1391 1684 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1392 1685 memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l);
1393 1686
1394 1687 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
1395 1688 rc_vfree(tmp);
1396 1689
1397 1690 if (hash == NULL)
1398 1691 goto end;
1399 1692 }
1400 1693
1401 1694 /* send isakmp payload */
1402 1695 iph2->sendbuf = quick_ir1mx(iph2, body, hash);
1403 1696 if (iph2->sendbuf == NULL)
1404 1697 goto end;
1405 1698
1406 1699 /* send the packet, add to the schedule to resend */
1407 1700 iph2->retry_counter = ikev1_max_retry_to_send(iph2->ph1->rmconf);
1408 1701 if (isakmp_ph2resend(iph2) == -1)
1409 1702 goto end;
1410 1703
1411 1704 /* the sending message is added to the received-list. */
1412 1705 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1, iph2->ph1->rmconf) == -1) {
1413 1706 plog(PLOG_INTERR , PLOGLOC, NULL,
1414 1707 "failed to add a response packet to the tree.\n");
1415 1708 goto end;
1416 1709 }
1417 1710
|
↓ open down ↓ |
74 lines elided |
↑ open up ↑ |
1418 1711 /* change status of isakmp status entry */
1419 1712 iph2->status = PHASE2ST_MSG1SENT;
1420 1713
1421 1714 error = 0;
1422 1715
1423 1716 end:
1424 1717 if (body != NULL)
1425 1718 rc_vfree(body);
1426 1719 if (hash != NULL)
1427 1720 rc_vfree(hash);
1721 +#ifdef ENABLE_NATT
1722 + if (nat_oai != NULL)
1723 + rc_vfree(nat_oai);
1724 + if (nat_oar != NULL)
1725 + rc_vfree(nat_oar);
1726 +#endif
1428 1727
1429 1728 return error;
1430 1729 }
1431 1730
1432 1731 /*
1433 1732 * receive from initiator
1434 1733 * HDR*, HASH(3)
1435 1734 */
1436 1735 int
1437 1736 quick_r3recv(struct ph2handle *iph2, rc_vchar_t *msg0)
1438 1737 {
1439 1738 rc_vchar_t *msg = NULL;
1440 1739 rc_vchar_t *pbuf = NULL; /* for payload parsing */
1441 1740 struct isakmp_parse_t *pa;
1442 1741 struct isakmp_pl_hash *hash = NULL;
1443 1742 int error = ISAKMP_INTERNAL_ERROR;
1444 1743
1445 1744 /* validity check */
1446 1745 if (iph2->status != PHASE2ST_MSG1SENT) {
1447 1746 plog(PLOG_INTERR, PLOGLOC, NULL,
1448 1747 "status mismatched %d.\n", iph2->status);
1449 1748 goto end;
1450 1749 }
1451 1750
1452 1751 /* decrypt packet */
1453 1752 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1454 1753 isakmp_log(0, 0, iph2->ph1->remote, 0,
1455 1754 PLOG_PROTOERR, PLOGLOC,
1456 1755 "Packet wasn't encrypted.\n");
1457 1756 goto end;
1458 1757 }
1459 1758 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
1460 1759 if (msg == NULL)
1461 1760 goto end;
1462 1761
1463 1762 /* validate the type of next payload */
1464 1763 pbuf = isakmp_parse(msg);
1465 1764 if (pbuf == NULL)
1466 1765 goto end;
1467 1766
1468 1767 for (pa = (struct isakmp_parse_t *)pbuf->v;
1469 1768 pa->type != ISAKMP_NPTYPE_NONE;
1470 1769 pa++) {
1471 1770
1472 1771 switch (pa->type) {
1473 1772 case ISAKMP_NPTYPE_HASH:
1474 1773 hash = (struct isakmp_pl_hash *)pa->ptr;
1475 1774 break;
1476 1775 case ISAKMP_NPTYPE_N:
1477 1776 isakmp_check_notify(pa->ptr, iph2->ph1);
1478 1777 break;
1479 1778 default:
1480 1779 /* don't send information, see ident_r1recv() */
1481 1780 isakmp_log(0, 0, iph2->ph1->remote, 0,
1482 1781 PLOG_PROTOERR, PLOGLOC,
1483 1782 "ignore the packet, "
1484 1783 "received unexpecting payload type %d.\n",
1485 1784 pa->type);
1486 1785 goto end;
1487 1786 }
1488 1787 }
1489 1788
1490 1789 /* payload existency check */
1491 1790 if (hash == NULL) {
1492 1791 isakmp_log(0, 0, iph2->ph1->remote, 0,
1493 1792 PLOG_PROTOERR, PLOGLOC,
1494 1793 "few isakmp message received.\n");
1495 1794 goto end;
1496 1795 }
1497 1796
1498 1797 /* validate HASH(3) */
1499 1798 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1500 1799 {
1501 1800 char *r_hash;
1502 1801 rc_vchar_t *my_hash = NULL;
1503 1802 rc_vchar_t *tmp = NULL;
1504 1803 int result;
1505 1804
1506 1805 r_hash = (char *)hash + sizeof(*hash);
1507 1806
1508 1807 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(3) validate:");
1509 1808 plogdump(PLOG_DEBUG, PLOGLOC, 0, r_hash, get_uint16(&hash->h.len) - sizeof(*hash));
1510 1809
1511 1810 tmp = rc_vmalloc(iph2->nonce_p->l + iph2->nonce->l);
1512 1811 if (tmp == NULL) {
1513 1812 plog(PLOG_INTERR, PLOGLOC, NULL,
1514 1813 "failed to get hash buffer.\n");
1515 1814 goto end;
1516 1815 }
1517 1816 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1518 1817 memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l);
1519 1818
1520 1819 my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
1521 1820 rc_vfree(tmp);
1522 1821 if (my_hash == NULL)
1523 1822 goto end;
1524 1823
1525 1824 result = memcmp(my_hash->v, r_hash, my_hash->l);
1526 1825 rc_vfree(my_hash);
1527 1826
1528 1827 if (result) {
1529 1828 isakmp_log(0, 0, iph2->ph1->remote, 0,
1530 1829 PLOG_PROTOERR, PLOGLOC,
1531 1830 "HASH(3) mismatch.\n");
1532 1831 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1533 1832 goto end;
1534 1833 }
1535 1834 }
1536 1835
1537 1836 /* if there is commit bit, don't set up SA now. */
1538 1837 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
1539 1838 iph2->status = PHASE2ST_COMMIT;
1540 1839 } else
1541 1840 iph2->status = PHASE2ST_STATUS6;
1542 1841
1543 1842 error = 0;
1544 1843
1545 1844 end:
1546 1845 if (pbuf != NULL)
1547 1846 rc_vfree(pbuf);
1548 1847 if (msg != NULL)
1549 1848 rc_vfree(msg);
1550 1849
1551 1850 return error;
1552 1851 }
1553 1852
1554 1853 /*
1555 1854 * send to initiator
1556 1855 * HDR#*, HASH(4), notify
1557 1856 */
1558 1857 int
1559 1858 quick_r3send(struct ph2handle *iph2, rc_vchar_t *msg0)
1560 1859 {
1561 1860 rc_vchar_t *buf = NULL;
1562 1861 rc_vchar_t *myhash = NULL;
1563 1862 struct isakmp_pl_n *n;
1564 1863 rc_vchar_t *notify = NULL;
1565 1864 char *p;
1566 1865 int tlen;
1567 1866 int error = ISAKMP_INTERNAL_ERROR;
1568 1867
1569 1868 /* validity check */
1570 1869 if (iph2->status != PHASE2ST_COMMIT) {
1571 1870 plog(PLOG_INTERR, PLOGLOC, NULL,
1572 1871 "status mismatched %d.\n", iph2->status);
1573 1872 goto end;
1574 1873 }
1575 1874
1576 1875 /* generate HASH(4) */
1577 1876 /* XXX What can I do in the case of multiple different SA */
1578 1877 plog(PLOG_DEBUG, PLOGLOC, NULL, "HASH(4) generate\n");
1579 1878
1580 1879 /* XXX What should I do if there are multiple SAs ? */
1581 1880 tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
1582 1881 notify = rc_vmalloc(tlen);
1583 1882 if (notify == NULL) {
1584 1883 plog(PLOG_INTERR, PLOGLOC, NULL,
1585 1884 "failed to get notify buffer.\n");
1586 1885 goto end;
1587 1886 }
1588 1887 n = (struct isakmp_pl_n *)notify->v;
1589 1888 n->h.np = ISAKMP_NPTYPE_NONE;
1590 1889 put_uint16(&n->h.len, tlen);
1591 1890 put_uint32(&n->doi, IPSEC_DOI);
1592 1891 n->proto_id = iph2->approval->head->proto_id;
1593 1892 n->spi_size = sizeof(iph2->approval->head->spisize);
1594 1893 put_uint16(&n->type, ISAKMP_NTYPE_CONNECTED);
1595 1894 memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
1596 1895
1597 1896 myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1598 1897 if (myhash == NULL)
1599 1898 goto end;
1600 1899
1601 1900 /* create buffer for isakmp payload */
1602 1901 tlen = sizeof(struct isakmp)
1603 1902 + sizeof(struct isakmp_gen) + myhash->l
1604 1903 + notify->l;
1605 1904 buf = rc_vmalloc(tlen);
1606 1905 if (buf == NULL) {
1607 1906 plog(PLOG_INTERR, PLOGLOC, NULL,
1608 1907 "failed to get buffer to send.\n");
1609 1908 goto end;
1610 1909 }
1611 1910
1612 1911 /* create isakmp header */
1613 1912 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1614 1913 if (p == NULL)
1615 1914 goto end;
1616 1915
1617 1916 /* add HASH(4) payload */
1618 1917 p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
1619 1918
1620 1919 /* add notify payload */
1621 1920 memcpy(p, notify->v, notify->l);
1622 1921
1623 1922 #ifdef HAVE_PRINT_ISAKMP_C
1624 1923 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1625 1924 #endif
1626 1925
1627 1926 /* encoding */
1628 1927 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1629 1928 if (iph2->sendbuf == NULL)
1630 1929 goto end;
1631 1930
1632 1931 /* send the packet */
1633 1932 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
1634 1933 goto end;
1635 1934
1636 1935 /* the sending message is added to the received-list. */
1637 1936 if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0, iph2->ph1->rmconf) == -1) {
1638 1937 plog(PLOG_INTERR , PLOGLOC, NULL,
1639 1938 "failed to add a response packet to the tree.\n");
1640 1939 goto end;
1641 1940 }
1642 1941
1643 1942 iph2->status = PHASE2ST_COMMIT;
1644 1943
1645 1944 error = 0;
1646 1945
1647 1946 end:
1648 1947 if (buf != NULL)
1649 1948 rc_vfree(buf);
1650 1949 if (myhash != NULL)
1651 1950 rc_vfree(myhash);
1652 1951 if (notify != NULL)
1653 1952 rc_vfree(notify);
1654 1953
1655 1954 return error;
1656 1955 }
1657 1956
1658 1957
1659 1958 /*
1660 1959 * set SA to kernel.
1661 1960 */
1662 1961 int
1663 1962 quick_r3prep(struct ph2handle *iph2, rc_vchar_t *msg0)
1664 1963 {
1665 1964 rc_vchar_t *msg = NULL;
1666 1965 int lifetime;
1667 1966 int error = ISAKMP_INTERNAL_ERROR;
1668 1967
1669 1968 /* validity check */
1670 1969 if (iph2->status != PHASE2ST_STATUS6) {
1671 1970 plog(PLOG_INTERR, PLOGLOC, NULL,
1672 1971 "status mismatched %d.\n", iph2->status);
1673 1972 goto end;
1674 1973 }
1675 1974
1676 1975 /* compute both of KEYMATs */
1677 1976 if (oakley_compute_keymat(iph2, RESPONDER) < 0)
1678 1977 goto end;
1679 1978
1680 1979 iph2->status = PHASE2ST_ADDSA;
1681 1980 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */
1682 1981
1683 1982 /* generate policy */
1684 1983 if (rcs_is_addr_rw(iph2->selector->pl->peers_sa_ipaddr)) {
1685 1984 IPSEC_CONF(lifetime, iph2->selector->pl->ips,
1686 1985 ipsec_sa_lifetime_time, 0);
|
↓ open down ↓ |
249 lines elided |
↑ open up ↑ |
1687 1986 if (ike_spmif_post_policy_add(iph2->selector,
1688 1987 ike_ipsec_mode(iph2->selector->pl),
1689 1988 lifetime, iph2->src, iph2->dst,
1690 1989 iph2->ph1->rmconf) < 0) {
1691 1990 plog(PLOG_INTERR, PLOGLOC, NULL,
1692 1991 "generate policy failed.\n");
1693 1992 goto end;
1694 1993 }
1695 1994 }
1696 1995
1697 - /* Do UPDATE as responder */
1698 - plog(PLOG_DEBUG, PLOGLOC, NULL, "call pk_sendupdate\n");
1699 - if (pk_sendupdate(iph2) < 0) {
1700 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey update failed.\n");
1701 - goto end;
1702 - }
1703 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey update sent.\n");
1996 + plog(PLOG_DEBUG, PLOGLOC, NULL, "call fill_in_ipsec_sas");
1997 + error = fill_in_ipsec_sas(iph2);
1704 1998
1705 - /* Do ADD for responder */
1706 - if (pk_sendadd(iph2) < 0) {
1707 - plog(PLOG_INTERR, PLOGLOC, NULL, "pfkey add failed.\n");
1708 - goto end;
1709 - }
1710 - plog(PLOG_DEBUG, PLOGLOC, NULL, "pfkey add sent.\n");
1711 -
1712 - error = 0;
1713 -
1714 1999 end:
1715 2000 if (msg != NULL)
1716 2001 rc_vfree(msg);
1717 2002
1718 2003 return error;
1719 2004 }
1720 2005
1721 2006
1722 2007 /*
1723 2008 * create HASH, body (SA, NONCE) payload with isakmp header.
1724 2009 */
1725 2010 static rc_vchar_t *
1726 2011 quick_ir1mx(struct ph2handle *iph2, rc_vchar_t *body, rc_vchar_t *hash)
1727 2012 {
1728 2013 struct isakmp *isakmp;
1729 2014 rc_vchar_t *buf = NULL, *new = NULL;
1730 2015 char *p;
1731 2016 int tlen;
1732 2017 struct isakmp_gen *gen;
1733 2018 int error = ISAKMP_INTERNAL_ERROR;
1734 2019
1735 2020 /* create buffer for isakmp payload */
1736 2021 tlen = sizeof(*isakmp)
1737 2022 + sizeof(*gen) + hash->l
1738 2023 + body->l;
1739 2024 buf = rc_vmalloc(tlen);
1740 2025 if (buf == NULL) {
1741 2026 plog(PLOG_INTERR, PLOGLOC, NULL,
1742 2027 "failed to get buffer to send.\n");
1743 2028 goto end;
1744 2029 }
1745 2030
1746 2031 /* re-set encryption flag, for serurity. */
1747 2032 iph2->flags |= ISAKMP_FLAG_E;
1748 2033
1749 2034 /* set isakmp header */
1750 2035 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1751 2036 if (p == NULL)
1752 2037 goto end;
1753 2038
1754 2039 /* add HASH payload */
1755 2040 /* XXX is next type always SA ? */
1756 2041 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA);
1757 2042
1758 2043 /* add body payload */
1759 2044 memcpy(p, body->v, body->l);
1760 2045
1761 2046 #ifdef HAVE_PRINT_ISAKMP_C
1762 2047 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1763 2048 #endif
1764 2049
1765 2050 /* encoding */
1766 2051 new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1767 2052 if (new == NULL)
1768 2053 goto end;
1769 2054
1770 2055 rc_vfree(buf);
1771 2056
1772 2057 buf = new;
1773 2058
1774 2059 error = 0;
1775 2060
1776 2061 end:
1777 2062 if (error && buf != NULL) {
1778 2063 rc_vfree(buf);
1779 2064 buf = NULL;
1780 2065 }
1781 2066
1782 2067 return buf;
1783 2068 }
1784 2069
1785 2070 /*
1786 2071 * get remote's sainfo.
1787 2072 * NOTE: this function is for responder.
1788 2073 */
1789 2074 static int
1790 2075 get_sainfo_r(struct ph2handle *iph2)
1791 2076 {
1792 2077 rc_vchar_t *idsrc = NULL, *iddst = NULL;
1793 2078 int prefixlen;
1794 2079 int error = ISAKMP_INTERNAL_ERROR;
1795 2080
1796 2081 if (iph2->id == NULL) {
1797 2082 struct sockaddr *sa;
1798 2083
1799 2084 switch (iph2->src->sa_family) {
1800 2085 case AF_INET:
1801 2086 prefixlen = sizeof(struct in_addr) << 3;
1802 2087 break;
1803 2088 case AF_INET6:
1804 2089 prefixlen = sizeof(struct in6_addr) << 3;
1805 2090 break;
1806 2091 default:
1807 2092 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1808 2093 "invalid family: %d\n", iph2->src->sa_family);
1809 2094 goto end;
1810 2095 }
1811 2096 sa = rcs_sadup(iph2->src);
1812 2097 set_port(sa, 0);
1813 2098 idsrc = ipsecdoi_sockaddr2id(sa, prefixlen,
1814 2099 IPSEC_ULPROTO_ANY);
1815 2100 rc_free(sa);
1816 2101 } else {
1817 2102 idsrc = rc_vdup(iph2->id);
1818 2103 }
1819 2104 if (idsrc == NULL) {
1820 2105 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1821 2106 "failed to set ID for source.\n");
1822 2107 goto end;
1823 2108 }
1824 2109
1825 2110 if (iph2->id_p == NULL) {
1826 2111 struct sockaddr *sa;
1827 2112
1828 2113 switch (iph2->dst->sa_family) {
1829 2114 case AF_INET:
1830 2115 prefixlen = sizeof(struct in_addr) << 3;
1831 2116 break;
1832 2117 case AF_INET6:
1833 2118 prefixlen = sizeof(struct in6_addr) << 3;
1834 2119 break;
1835 2120 default:
1836 2121 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1837 2122 "invalid family: %d\n", iph2->dst->sa_family);
1838 2123 goto end;
1839 2124 }
1840 2125 sa = rcs_sadup(iph2->dst);
1841 2126 set_port(sa, 0);
1842 2127 iddst = ipsecdoi_sockaddr2id(sa, prefixlen,
1843 2128 IPSEC_ULPROTO_ANY);
1844 2129 rc_free(sa);
1845 2130 } else {
1846 2131 iddst = rc_vdup(iph2->id_p);
1847 2132 }
1848 2133 if (iddst == NULL) {
1849 2134 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1850 2135 "failed to set ID for destination.\n");
1851 2136 goto end;
1852 2137 }
1853 2138
1854 2139 iph2->selector = ike_conf_find_ikev1sel_by_id(idsrc, iddst);
1855 2140 if (! iph2->selector) {
1856 2141 plog(PLOG_INTERR, PLOGLOC, 0,
1857 2142 "can't find matching selector\n");
1858 2143 goto end;
1859 2144 }
1860 2145
1861 2146 #if 0
1862 2147 iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p);
1863 2148 if (iph2->sainfo == NULL) {
1864 2149 plog(PLOG_INTERR, PLOGLOC, NULL,
1865 2150 "failed to get sainfo.\n");
1866 2151 goto end;
1867 2152 }
1868 2153
1869 2154 plog(PLOG_DEBUG, PLOGLOC, NULL,
1870 2155 "get sa info: %s\n", sainfo2str(iph2->sainfo));
1871 2156 #endif
1872 2157
1873 2158 error = 0;
1874 2159 end:
1875 2160 if (idsrc)
1876 2161 rc_vfree(idsrc);
1877 2162 if (iddst)
1878 2163 rc_vfree(iddst);
1879 2164
1880 2165 return error;
1881 2166 }
1882 2167
1883 2168
1884 2169 /*
1885 2170 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
1886 2171 * are IP address and same address family.
1887 2172 * Then get remote's policy from SPD copied from kernel.
1888 2173 * If the type of ID payload is address or subnet type, then the index is
1889 2174 * made from the payload. If there is no ID payload, or the type of ID
1890 2175 * payload is NOT address type, then the index is made from the address
1891 2176 * pair of phase 1.
1892 2177 * NOTE: This function is only for responder.
1893 2178 */
1894 2179 static int
1895 2180 get_proposal_r(struct ph2handle *iph2)
1896 2181 {
1897 2182 struct rcf_selector *selector;
1898 2183 struct rcf_policy *p;
1899 2184
1900 2185 /* check the existence of ID payload */
1901 2186 if ((iph2->id_p != NULL && iph2->id == NULL)
1902 2187 || (iph2->id_p == NULL && iph2->id != NULL)) {
1903 2188 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1904 2189 "Both IDs wasn't found in payload.\n");
1905 2190 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1906 2191 }
1907 2192
1908 2193 if (iph2->src_id || iph2->dst_id) {
1909 2194 plog(PLOG_INTERR, PLOGLOC, 0,
1910 2195 "ph2handle has ID[src, dst] already\n");
1911 2196 return ISAKMP_INTERNAL_ERROR;
1912 2197 }
1913 2198
1914 2199 selector = iph2->selector;
1915 2200 p = selector->pl;
1916 2201 if (!p) {
1917 2202 plog(PLOG_INTERR, PLOGLOC, 0,
1918 2203 "selector (index %s) does not have policy\n",
1919 2204 rc_vmem2str(selector->sl_index));
1920 2205 return ISAKMP_INTERNAL_ERROR;
1921 2206 }
1922 2207
1923 2208 if (set_proposal_from_policy(iph2, iph2->ph1->rmconf, p)) {
1924 2209 plog(PLOG_INTERR, PLOGLOC, 0,
1925 2210 "failed to create saprop.\n");
1926 2211 return ISAKMP_INTERNAL_ERROR;
1927 2212 }
1928 2213
1929 2214 return 0;
1930 2215 #if 0
1931 2216 struct policyindex spidx;
1932 2217 struct secpolicy *sp_in, *sp_out;
1933 2218 int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */
1934 2219 int error = ISAKMP_INTERNAL_ERROR;
1935 2220
1936 2221 /* check the existence of ID payload */
1937 2222 if ((iph2->id_p != NULL && iph2->id == NULL)
1938 2223 || (iph2->id_p == NULL && iph2->id != NULL)) {
1939 2224 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1940 2225 "Both IDs wasn't found in payload.\n");
1941 2226 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1942 2227 }
1943 2228
1944 2229 /* make sure if id[src,dst] is null. */
1945 2230 if (iph2->src_id || iph2->dst_id) {
1946 2231 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1947 2232 "Why do ID[src,dst] exist already.\n");
1948 2233 return ISAKMP_INTERNAL_ERROR;
1949 2234 }
1950 2235
1951 2236 memset(&spidx, 0, sizeof(spidx));
1952 2237
1953 2238 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
1954 2239
1955 2240 /* make a spidx; a key to search SPD */
1956 2241 spidx.dir = IPSEC_DIR_INBOUND;
1957 2242 spidx.ul_proto = 0;
1958 2243
1959 2244 /*
1960 2245 * make destination address in spidx from either ID payload
1961 2246 * or phase 1 address into a address in spidx.
1962 2247 */
1963 2248 if (iph2->id != NULL
1964 2249 && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1965 2250 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
1966 2251 || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
1967 2252 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
1968 2253 /* get a destination address of a policy */
1969 2254 error = ipsecdoi_id2sockaddr(iph2->id,
1970 2255 (struct sockaddr *)&spidx.dst,
1971 2256 &spidx.prefd, &spidx.ul_proto);
1972 2257 if (error)
1973 2258 return error;
1974 2259
1975 2260 #ifdef INET6
1976 2261 /*
1977 2262 * get scopeid from the SA address.
1978 2263 * note that the phase 1 source address is used as
1979 2264 * a destination address to search for a inbound policy entry
1980 2265 * because rcoon is responder.
1981 2266 */
1982 2267 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
1983 2268 error = setscopeid((struct sockaddr *)&spidx.dst,
1984 2269 iph2->src);
1985 2270 if (error)
1986 2271 return error;
1987 2272 }
1988 2273 #endif
1989 2274
1990 2275 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1991 2276 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
1992 2277 idi2type = _XIDT(iph2->id);
1993 2278
1994 2279 } else {
1995 2280
1996 2281 plog(PLOG_DEBUG, PLOGLOC, NULL,
1997 2282 "get a destination address of SP index "
1998 2283 "from phase1 address "
1999 2284 "due to no ID payloads found "
2000 2285 "OR because ID type is not address.\n");
2001 2286
2002 2287 /*
2003 2288 * copy the SOURCE address of IKE into the DESTINATION address
2004 2289 * of the key to search the SPD because the direction of policy
2005 2290 * is inbound.
2006 2291 */
2007 2292 memcpy(&spidx.dst, iph2->src, iph2->src->sa_len);
2008 2293 switch (spidx.dst.ss_family) {
2009 2294 case AF_INET:
2010 2295 spidx.prefd = sizeof(struct in_addr) << 3;
2011 2296 break;
2012 2297 #ifdef INET6
2013 2298 case AF_INET6:
2014 2299 spidx.prefd = sizeof(struct in6_addr) << 3;
2015 2300 break;
2016 2301 #endif
2017 2302 default:
2018 2303 spidx.prefd = 0;
2019 2304 break;
2020 2305 }
2021 2306 }
2022 2307
2023 2308 /* make source address in spidx */
2024 2309 if (iph2->id_p != NULL
2025 2310 && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
2026 2311 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
2027 2312 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2028 2313 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2029 2314 /* get a source address of inbound SA */
2030 2315 error = ipsecdoi_id2sockaddr(iph2->id_p,
2031 2316 (struct sockaddr *)&spidx.src,
2032 2317 &spidx.prefs, &spidx.ul_proto);
2033 2318 if (error)
2034 2319 return error;
2035 2320
2036 2321 #ifdef INET6
2037 2322 /*
2038 2323 * get scopeid from the SA address.
2039 2324 * for more detail, see above of this function.
2040 2325 */
2041 2326 if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
2042 2327 error = setscopeid((struct sockaddr *)&spidx.src,
2043 2328 iph2->dst);
2044 2329 if (error)
2045 2330 return error;
2046 2331 }
2047 2332 #endif
2048 2333
2049 2334 /* make id[src,dst] if both ID types are IP address and same */
2050 2335 if (_XIDT(iph2->id_p) == idi2type
2051 2336 && spidx.dst.ss_family == spidx.src.ss_family) {
2052 2337 iph2->src_id = rcs_sadup((struct sockaddr *)&spidx.dst);
2053 2338 iph2->dst_id = rcs_sadup((struct sockaddr *)&spidx.src);
2054 2339 }
2055 2340
2056 2341 } else {
2057 2342 plog(PLOG_DEBUG, PLOGLOC, NULL,
2058 2343 "get a source address of SP index "
2059 2344 "from phase1 address "
2060 2345 "due to no ID payloads found "
2061 2346 "OR because ID type is not address.\n");
2062 2347
2063 2348 /* see above comment. */
2064 2349 memcpy(&spidx.src, iph2->dst, iph2->dst->sa_len);
2065 2350 switch (spidx.src.ss_family) {
2066 2351 case AF_INET:
2067 2352 spidx.prefs = sizeof(struct in_addr) << 3;
2068 2353 break;
2069 2354 #ifdef INET6
2070 2355 case AF_INET6:
2071 2356 spidx.prefs = sizeof(struct in6_addr) << 3;
2072 2357 break;
2073 2358 #endif
2074 2359 default:
2075 2360 spidx.prefs = 0;
2076 2361 break;
2077 2362 }
2078 2363 }
2079 2364
2080 2365 #undef _XIDT
2081 2366
2082 2367 plog(PLOG_DEBUG, PLOGLOC, NULL,
2083 2368 "get a src address from ID payload "
2084 2369 "%s prefixlen=%u ul_proto=%u\n",
2085 2370 rcs_sa2str((struct sockaddr *)&spidx.src),
2086 2371 spidx.prefs, spidx.ul_proto);
2087 2372 plog(PLOG_DEBUG, PLOGLOC, NULL,
2088 2373 "get dst address from ID payload "
2089 2374 "%s prefixlen=%u ul_proto=%u\n",
2090 2375 rcs_sa2str((struct sockaddr *)&spidx.dst),
2091 2376 spidx.prefd, spidx.ul_proto);
2092 2377
2093 2378 /*
2094 2379 * convert the ul_proto if it is 0
2095 2380 * because 0 in ID payload means a wild card.
2096 2381 */
2097 2382 if (spidx.ul_proto == 0)
2098 2383 spidx.ul_proto = IPSEC_ULPROTO_ANY;
2099 2384
2100 2385 /* get inbound policy */
2101 2386 sp_in = getsp_r(&spidx);
2102 2387 if (sp_in == NULL) {
2103 2388 if (iph2->ph1->rmconf->gen_policy) {
2104 2389 plog(PLOG_INFO, PLOGLOC, NULL,
2105 2390 "no policy found, "
2106 2391 "try to generate the policy : %s\n",
2107 2392 spidx2str(&spidx));
2108 2393 iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2109 2394 if (!iph2->spidx_gen) {
2110 2395 plog(PLOG_INTERR, PLOGLOC, NULL,
2111 2396 "buffer allocation failed.\n");
2112 2397 return ISAKMP_INTERNAL_ERROR;
2113 2398 }
2114 2399 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2115 2400 return -2; /* special value */
2116 2401 }
2117 2402 plog(PLOG_INTERR, PLOGLOC, NULL,
2118 2403 "no policy found: %s\n", spidx2str(&spidx));
|
↓ open down ↓ |
395 lines elided |
↑ open up ↑ |
2119 2404 return ISAKMP_INTERNAL_ERROR;
2120 2405 }
2121 2406 /* Refresh existing generated policies
2122 2407 */
2123 2408 if (iph2->ph1->rmconf->gen_policy) {
2124 2409 plog(LLV_INFO, LOCATION, NULL,
2125 2410 "Update the generated policy : %s\n",
2126 2411 spidx2str(&spidx));
2127 2412 iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2128 2413 if (!iph2->spidx_gen) {
2129 - plog(LLV_ERROR, LOCATION, NULL,
2414 + plog(PLOG_INTERR, PLOGLOC, NULL,
2130 2415 "buffer allocation failed.\n");
2131 2416 return ISAKMP_INTERNAL_ERROR;
2132 2417 }
2133 2418 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2134 2419 }
2135 2420
2136 2421 /* get outbound policy */
2137 2422 {
2138 2423 struct sockaddr_storage addr;
2139 2424 uint8_t pref;
2140 2425
2141 2426 spidx.dir = IPSEC_DIR_OUTBOUND;
2142 2427 addr = spidx.src;
2143 2428 spidx.src = spidx.dst;
2144 2429 spidx.dst = addr;
2145 2430 pref = spidx.prefs;
2146 2431 spidx.prefs = spidx.prefd;
2147 2432 spidx.prefd = pref;
2148 2433
2149 2434 sp_out = getsp_r(&spidx);
2150 2435 if (!sp_out) {
2151 2436 plog(PLOG_INTWARN, PLOGLOC, NULL,
2152 2437 "no outbound policy found: %s\n",
2153 2438 spidx2str(&spidx));
2154 2439 }
2155 2440 }
2156 2441
2157 2442 plog(PLOG_DEBUG, PLOGLOC, NULL,
2158 2443 "suitable SP found:%s\n", spidx2str(&spidx));
2159 2444
2160 2445 /*
2161 2446 * In the responder side, the inbound policy should be using IPsec.
2162 2447 * outbound policy is not checked currently.
2163 2448 */
2164 2449 if (sp_in->policy != IPSEC_POLICY_IPSEC) {
2165 2450 plog(PLOG_INTERR, PLOGLOC, NULL,
2166 2451 "policy found, but no IPsec required: %s\n",
2167 2452 spidx2str(&spidx));
2168 2453 return ISAKMP_INTERNAL_ERROR;
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
2169 2454 }
2170 2455
2171 2456 /* set new proposal derived from a policy into the iph2->proposal. */
2172 2457 if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
2173 2458 plog(PLOG_INTERR, PLOGLOC, NULL,
2174 2459 "failed to create saprop.\n");
2175 2460 return ISAKMP_INTERNAL_ERROR;
2176 2461 }
2177 2462
2178 2463 return 0;
2179 -#endif
2464 +#endif /* 0 */
2180 2465 }
2181 2466
2182 2467 #ifdef INET6
2183 2468 static uint32_t
2184 2469 setscopeid(struct sockaddr *sp_addr0, struct sockaddr *sa_addr0)
2185 2470 {
2186 2471 struct sockaddr_in6 *sp_addr, *sa_addr;
2187 2472
2188 2473 sp_addr = (struct sockaddr_in6 *)sp_addr0;
2189 2474 sa_addr = (struct sockaddr_in6 *)sa_addr0;
2190 2475
2191 2476 if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
2192 2477 && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
2193 2478 && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
2194 2479 return 0;
2195 2480
2196 2481 /* this check should not be here ? */
2197 2482 if (sa_addr->sin6_family != AF_INET6) {
2198 2483 plog(PLOG_INTERR, PLOGLOC, NULL,
2199 2484 "can't get scope ID: family mismatch\n");
2200 2485 return -1;
2201 2486 }
2202 2487
2203 2488 if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
2204 2489 plog(PLOG_INTERR, PLOGLOC, NULL,
2205 2490 "scope ID is not supported except of lladdr.\n");
2206 2491 return -1;
2207 2492 }
2208 2493
2209 2494 sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
2210 2495
2211 2496 return 0;
2212 2497 }
2213 2498 #endif
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX