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/handler.c
+++ new/iked/ikev1/handler.c
1 1 /* $Id: handler.c,v 1.16 2008/02/07 10:12:27 mk 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 #include "config.h"
33 33
34 34 #include <sys/types.h>
35 35 #include <sys/param.h>
36 36 #include <sys/socket.h>
37 37
38 38 #include <netinet/in.h>
39 39
40 40 #include <stdlib.h>
41 41 #include <stdio.h>
42 42 #include <string.h>
43 43 #include <time.h>
44 44 #include <errno.h>
45 45
46 46 #include "racoon.h"
47 47
48 48 #include "var.h"
49 49 /* #include "misc.h" */
50 50 /* #include "vmbuf.h" */
51 51 #include "plog.h"
52 52 #include "sockmisc.h"
53 53 #include "debug.h"
54 54
55 55 #ifdef ENABLE_HYBRID
56 56 #include <resolv.h>
57 57 #endif
58 58
59 59 /* #include "schedule.h" */
60 60 /* #include "grabmyaddr.h" */
61 61 #include "algorithm.h"
62 62 #include "crypto_impl.h"
63 63 /* #include "policy.h" */
64 64 #include "proposal.h"
65 65 #include "isakmp.h"
66 66 #include "isakmp_var.h"
67 67 #include "ipsec_doi.h"
68 68 #include "evt.h"
69 69 #ifdef ENABLE_HYBRID
70 70 #include "isakmp_xauth.h"
71 71 #include "isakmp_cfg.h"
72 72 #endif
73 73 #include "isakmp_inf.h"
74 74 #include "oakley.h"
75 75 #include "isakmp_impl.h"
76 76 #include "ikev1_impl.h"
77 77 #include "ike_conf.h"
78 78 #include "remoteconf.h"
79 79 /* #include "localconf.h" */
80 80 #include "handler.h"
81 81 #include "gcmalloc.h"
82 82 #include "ikev1_natt.h"
83 83
84 84 /* #include "sainfo.h" */
85 85
86 86 #ifdef HAVE_GSSAPI
87 87 #include "gssapi.h"
88 88 #endif
89 89
90 90 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
91 91 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
92 92 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
93 93 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
94 94
95 95 static void del_recvdpkt (struct recvdpkt *);
96 96 static void rem_recvdpkt (struct recvdpkt *);
97 97 static void sweep_recvdpkt (void *);
98 98
99 99 /*
100 100 * functions about management of the isakmp status table
101 101 */
102 102 /* %%% management phase 1 handler */
103 103 /*
104 104 * search for isakmpsa handler with isakmp index.
105 105 */
106 106
107 107 extern caddr_t val2str(const char *, size_t);
108 108
109 109 struct ph1handle *
110 110 getph1byindex(isakmp_index_t *index)
111 111 {
112 112 struct ph1handle *p;
113 113
114 114 LIST_FOREACH(p, &ph1tree, chain) {
115 115 if (p->status == PHASE1ST_EXPIRED)
116 116 continue;
117 117 if (memcmp(&p->index, index, sizeof(*index)) == 0)
118 118 return p;
119 119 }
120 120
121 121 return NULL;
122 122 }
123 123
124 124
125 125 /*
126 126 * search for isakmp handler by i_ck in index.
127 127 */
128 128 struct ph1handle *
129 129 getph1byindex0(isakmp_index_t *index)
130 130 {
131 131 struct ph1handle *p;
132 132
133 133 LIST_FOREACH(p, &ph1tree, chain) {
134 134 if (p->status == PHASE1ST_EXPIRED)
135 135 continue;
136 136 if (memcmp(&p->index, index, sizeof(isakmp_cookie_t)) == 0)
137 137 return p;
138 138 }
139 139
140 140 return NULL;
141 141 }
142 142
143 143 /*
144 144 * search for isakmpsa handler by source and remote address.
145 145 * don't use port number to search because this function search
146 146 * with phase 2's destinaion.
147 147 */
148 148 struct ph1handle *
149 149 getph1byaddr(struct sockaddr *local, struct sockaddr *remote)
150 150 {
151 151 struct ph1handle *p;
152 152
153 153 LIST_FOREACH(p, &ph1tree, chain) {
154 154 if (p->status == PHASE1ST_EXPIRED)
155 155 continue;
156 156 if (CMPSADDR(local, p->local) == 0
157 157 && CMPSADDR(remote, p->remote) == 0)
158 158 return p;
159 159 }
160 160
161 161 return NULL;
162 162 }
163 163
164 164 struct ph1handle *
165 165 getph1byaddrwop(struct sockaddr *local, struct sockaddr *remote)
166 166 {
167 167 struct ph1handle *p;
168 168
169 169 LIST_FOREACH(p, &ph1tree, chain) {
170 170 if (p->status == PHASE1ST_EXPIRED)
171 171 continue;
172 172 if (rcs_cmpsa_wop(local, p->local) == 0
173 173 && rcs_cmpsa_wop(remote, p->remote) == 0)
174 174 return p;
175 175 }
176 176
177 177 return NULL;
178 178 }
179 179
180 180 /*
181 181 * search for isakmpsa handler by remote address.
182 182 * don't use port number to search because this function search
183 183 * with phase 2's destinaion.
184 184 */
185 185 struct ph1handle *
186 186 getph1bydstaddrwop(struct sockaddr *remote)
187 187 {
188 188 struct ph1handle *p;
189 189
190 190 LIST_FOREACH(p, &ph1tree, chain) {
191 191 if (p->status == PHASE1ST_EXPIRED)
192 192 continue;
193 193 if (rcs_cmpsa_wop(remote, p->remote) == 0)
194 194 return p;
195 195 }
196 196
197 197 return NULL;
198 198 }
199 199
200 200 /*
201 201 * dump isakmp-sa
202 202 */
203 203 rc_vchar_t *
204 204 dumpph1(void)
205 205 {
206 206 struct ph1handle *iph1;
207 207 struct ph1dump *pd;
208 208 int cnt = 0;
209 209 rc_vchar_t *buf;
210 210
211 211 /* get length of buffer */
212 212 LIST_FOREACH(iph1, &ph1tree, chain)
213 213 cnt++;
214 214
215 215 buf = rc_vmalloc(cnt * sizeof(struct ph1dump));
216 216 if (buf == NULL) {
217 217 plog(PLOG_INTERR, PLOGLOC, NULL,
218 218 "failed to get buffer\n");
219 219 return NULL;
220 220 }
221 221 pd = (struct ph1dump *)buf->v;
222 222
223 223 LIST_FOREACH(iph1, &ph1tree, chain) {
224 224 memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
225 225 pd->status = iph1->status;
226 226 pd->side = iph1->side;
227 227 memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
228 228 memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
229 229 pd->version = iph1->version;
230 230 pd->etype = iph1->etype;
231 231 pd->created = iph1->created;
232 232 pd->ph2cnt = iph1->ph2cnt;
233 233 pd++;
234 234 }
235 235
236 236 return buf;
237 237 }
238 238
239 239 /*
240 240 * create new isakmp Phase 1 status record to handle isakmp in Phase1
241 241 */
242 242 struct ph1handle *
243 243 newph1(void)
244 244 {
245 245 struct ph1handle *iph1;
246 246
247 247 /* create new iph1 */
248 248 iph1 = racoon_calloc(1, sizeof(*iph1));
249 249 if (iph1 == NULL)
250 250 return NULL;
251 251
252 252 iph1->status = PHASE1ST_SPAWN;
253 253
254 254 iph1->dpd_support = 0;
255 255 iph1->dpd_lastack = 0;
256 256 iph1->dpd_seq = 0;
257 257 iph1->dpd_fails = 0;
258 258 iph1->dpd_r_u = NULL;
259 259
260 260 return iph1;
261 261 }
262 262
263 263 /*
264 264 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
265 265 */
266 266 void
267 267 delph1(struct ph1handle *iph1)
|
↓ open down ↓ |
267 lines elided |
↑ open up ↑ |
268 268 {
269 269 if (iph1 == NULL)
270 270 return;
271 271
272 272 /* SA down shell script hook */
273 273 ikev1_script_hook(iph1, SCRIPT_PHASE1_DOWN);
274 274
275 275 EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
276 276
277 277 #ifdef ENABLE_NATT
278 +#ifndef sun /* XXX KEBE SAYS kernel does this in OpenSolaris */
278 279 if (iph1->natt_flags & NAT_KA_QUEUED)
279 280 natt_keepalive_remove (iph1->local, iph1->remote);
281 +#endif
280 282
281 283 if (iph1->natt_options) {
282 284 racoon_free(iph1->natt_options);
283 285 iph1->natt_options = NULL;
284 286 }
285 287 #endif
286 288
287 289 if (iph1->dpd_r_u != NULL)
288 290 SCHED_KILL(iph1->dpd_r_u);
289 291
290 292 if (iph1->remote) {
291 293 racoon_free(iph1->remote);
292 294 iph1->remote = NULL;
293 295 }
294 296 if (iph1->local) {
295 297 racoon_free(iph1->local);
296 298 iph1->local = NULL;
297 299 }
298 300
299 301 if (iph1->approval) {
300 302 delisakmpsa(iph1->approval);
301 303 iph1->approval = NULL;
302 304 }
303 305
304 306 #ifdef ENABLE_HYBRID
305 307 if (iph1->mode_cfg)
306 308 isakmp_cfg_rmstate(iph1);
307 309 #endif
308 310
309 311 VPTRINIT(iph1->authstr);
310 312
311 313 sched_scrub_param(iph1);
312 314 iph1->sce = NULL;
313 315 iph1->scr = NULL;
314 316
315 317 VPTRINIT(iph1->sendbuf);
316 318
317 319 VPTRINIT(iph1->dhpriv);
318 320 VPTRINIT(iph1->dhpub);
319 321 VPTRINIT(iph1->dhpub_p);
320 322 VPTRINIT(iph1->dhgxy);
321 323 VPTRINIT(iph1->nonce);
322 324 VPTRINIT(iph1->nonce_p);
323 325 VPTRINIT(iph1->skeyid);
324 326 VPTRINIT(iph1->skeyid_d);
325 327 VPTRINIT(iph1->skeyid_a);
326 328 VPTRINIT(iph1->skeyid_e);
327 329 VPTRINIT(iph1->key);
328 330 VPTRINIT(iph1->hash);
329 331 VPTRINIT(iph1->sig);
330 332 VPTRINIT(iph1->sig_p);
331 333 oakley_delcert(iph1->cert);
332 334 iph1->cert = NULL;
333 335 oakley_delcert(iph1->cert_p);
334 336 iph1->cert_p = NULL;
335 337 oakley_delcert(iph1->crl_p);
336 338 iph1->crl_p = NULL;
337 339 oakley_delcert(iph1->cr_p);
338 340 iph1->cr_p = NULL;
339 341 VPTRINIT(iph1->id);
340 342 VPTRINIT(iph1->id_p);
341 343
342 344 if (iph1->approval)
343 345 delisakmpsa(iph1->approval);
344 346
345 347 if (iph1->ivm) {
346 348 oakley_delivm(iph1->ivm);
347 349 iph1->ivm = NULL;
348 350 }
349 351
350 352 VPTRINIT(iph1->sa);
351 353 VPTRINIT(iph1->sa_ret);
352 354
353 355 #ifdef HAVE_GSSAPI
354 356 VPTRINIT(iph1->gi_i);
355 357 VPTRINIT(iph1->gi_r);
356 358
357 359 gssapi_free_state(iph1);
358 360 #endif
359 361
360 362 racoon_free(iph1);
361 363 }
362 364
363 365 /*
364 366 * create new isakmp Phase 1 status record to handle isakmp in Phase1
365 367 */
366 368 int
367 369 insph1(struct ph1handle *iph1)
368 370 {
369 371 /* validity check */
370 372 if (iph1->remote == NULL) {
371 373 plog(PLOG_INTERR, PLOGLOC, NULL,
372 374 "invalid isakmp SA handler. no remote address.\n");
373 375 return -1;
374 376 }
375 377 LIST_INSERT_HEAD(&ph1tree, iph1, chain);
376 378
377 379 return 0;
378 380 }
379 381
380 382 void
381 383 remph1(struct ph1handle *iph1)
382 384 {
383 385 LIST_REMOVE(iph1, chain);
384 386 }
385 387
386 388 /*
387 389 * flush isakmp-sa
388 390 */
389 391 void
390 392 flushph1(void)
391 393 {
392 394 struct ph1handle *p, *next;
393 395
394 396 for (p = LIST_FIRST(&ph1tree); p; p = next) {
395 397 next = LIST_NEXT(p, chain);
396 398
397 399 /* send delete information */
398 400 if (p->status == PHASE1ST_ESTABLISHED)
399 401 isakmp_info_send_d1(p);
400 402
401 403 remph1(p);
402 404 delph1(p);
403 405 }
404 406 }
405 407
406 408 void
407 409 initph1tree(void)
408 410 {
409 411 LIST_INIT(&ph1tree);
410 412 }
411 413
412 414 /* %%% management phase 2 handler */
413 415 #if 0
414 416 /*
415 417 * search ph2handle with policy id.
416 418 */
417 419 struct ph2handle *
418 420 getph2byspid(uint32_t spid)
419 421 {
420 422 struct ph2handle *p;
421 423
422 424 LIST_FOREACH(p, &ph2tree, chain) {
423 425 /*
424 426 * there are ph2handle independent on policy
425 427 * such like informational exchange.
426 428 */
427 429 if (p->spid == spid)
428 430 return p;
429 431 }
430 432
431 433 return NULL;
432 434 }
433 435 #endif
434 436
435 437 /*
436 438 * search ph2handle with sequence number.
437 439 */
438 440 struct ph2handle *
439 441 getph2byseq(uint32_t seq)
440 442 {
441 443 struct ph2handle *p;
442 444
443 445 LIST_FOREACH(p, &ph2tree, chain) {
444 446 if (p->seq == seq)
445 447 return p;
446 448 }
447 449
448 450 return NULL;
449 451 }
450 452
451 453 /*
452 454 * search ph2handle with message id.
453 455 */
454 456 struct ph2handle *
455 457 getph2bymsgid(struct ph1handle *iph1, uint32_t msgid)
456 458 {
457 459 struct ph2handle *p;
458 460
459 461 LIST_FOREACH(p, &ph2tree, chain) {
460 462 if (p->msgid == msgid)
461 463 return p;
462 464 }
|
↓ open down ↓ |
173 lines elided |
↑ open up ↑ |
463 465
464 466 return NULL;
465 467 }
466 468
467 469 struct ph2handle *
468 470 getph2byselector(struct sockaddr *src, struct sockaddr *dst, struct rcf_selector *selector)
469 471 {
470 472 struct ph2handle *p;
471 473
472 474 LIST_FOREACH(p, &ph2tree, chain) {
475 +#ifdef sun
476 + if ((p->selector->sl_index == selector->sl_index ||
477 + rc_vmemcmp(p->selector->sl_index,
478 + selector->sl_index) == 0) &&
479 +#else
473 480 if (rc_vmemcmp(p->selector->sl_index, selector->sl_index)
474 481 == 0 &&
482 +#endif
475 483 CMPSADDR(src, p->src) == 0 &&
476 484 CMPSADDR(dst, p->dst) == 0)
477 485 return p;
478 486 }
479 487
480 488 return NULL;
481 489 }
482 490
483 491 struct ph2handle *
484 492 getph2bysaddr(struct sockaddr *src, struct sockaddr *dst)
485 493 {
486 494 struct ph2handle *p;
487 495
488 496 LIST_FOREACH(p, &ph2tree, chain) {
489 497 if (rcs_cmpsa(src, p->src) == 0 &&
490 498 rcs_cmpsa(dst, p->dst) == 0)
491 499 return p;
492 500 }
493 501
494 502 return NULL;
495 503 }
496 504
497 505 /*
498 506 * call by pk_recvexpire().
499 507 */
500 508 struct ph2handle *
501 509 getph2bysaidx(struct sockaddr *src, struct sockaddr *dst, unsigned int proto_id, uint32_t spi)
502 510 {
503 511 struct ph2handle *iph2;
504 512 struct saproto *pr;
505 513
506 514 LIST_FOREACH(iph2, &ph2tree, chain) {
507 515 if (iph2->proposal == NULL && iph2->approval == NULL)
508 516 continue;
509 517 if (iph2->approval != NULL) {
510 518 for (pr = iph2->approval->head; pr != NULL;
511 519 pr = pr->next) {
512 520 if (proto_id != pr->proto_id)
513 521 break;
514 522 if (spi == pr->spi || spi == pr->spi_p)
515 523 return iph2;
516 524 }
517 525 } else if (iph2->proposal != NULL) {
518 526 for (pr = iph2->proposal->head; pr != NULL;
519 527 pr = pr->next) {
520 528 if (proto_id != pr->proto_id)
521 529 break;
522 530 if (spi == pr->spi)
523 531 return iph2;
524 532 }
525 533 }
526 534 }
527 535
528 536 return NULL;
529 537 }
530 538
531 539 /*
532 540 * create new isakmp Phase 2 status record to handle isakmp in Phase2
533 541 */
534 542 struct ph2handle *
535 543 newph2(void)
536 544 {
537 545 struct ph2handle *iph2 = NULL;
538 546
539 547 /* create new iph2 */
540 548 iph2 = racoon_calloc(1, sizeof(*iph2));
541 549 if (iph2 == NULL)
542 550 return NULL;
543 551
544 552 iph2->status = PHASE1ST_SPAWN;
545 553
546 554 return iph2;
547 555 }
548 556
549 557 /*
550 558 * initialize ph2handle
551 559 * NOTE: don't initialize src/dst.
552 560 * SPI in the proposal is cleared.
553 561 */
554 562 void
555 563 initph2(struct ph2handle *iph2)
556 564 {
557 565 sched_scrub_param(iph2);
558 566 iph2->sce = NULL;
559 567 iph2->scr = NULL;
560 568
561 569 VPTRINIT(iph2->sendbuf);
562 570 VPTRINIT(iph2->msg1);
563 571
564 572 /* clear spi, keep variables in the proposal */
565 573 if (iph2->proposal) {
566 574 struct saproto *pr;
567 575 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
568 576 pr->spi = 0;
569 577 }
570 578
571 579 /* clear approval */
572 580 if (iph2->approval) {
573 581 flushsaprop(iph2->approval);
574 582 iph2->approval = NULL;
575 583 }
576 584
577 585 #ifdef notyet
578 586 /* clear the generated policy */
579 587 if (iph2->spidx_gen) {
580 588 delsp_bothdir((struct policyindex *)iph2->spidx_gen);
581 589 racoon_free(iph2->spidx_gen);
582 590 iph2->spidx_gen = NULL;
583 591 }
584 592 #endif
585 593
586 594 if (iph2->pfsgrp) {
587 595 oakley_dhgrp_free(iph2->pfsgrp);
588 596 iph2->pfsgrp = NULL;
589 597 }
590 598
591 599 VPTRINIT(iph2->dhpriv);
592 600 VPTRINIT(iph2->dhpub);
593 601 VPTRINIT(iph2->dhpub_p);
594 602 VPTRINIT(iph2->dhgxy);
595 603 VPTRINIT(iph2->id);
596 604 VPTRINIT(iph2->id_p);
597 605 VPTRINIT(iph2->nonce);
598 606 VPTRINIT(iph2->nonce_p);
599 607 VPTRINIT(iph2->sa);
600 608 VPTRINIT(iph2->sa_ret);
601 609
602 610 if (iph2->ivm) {
603 611 oakley_delivm(iph2->ivm);
604 612 iph2->ivm = NULL;
605 613 }
606 614 }
607 615
608 616 /*
609 617 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
610 618 */
611 619 void
612 620 delph2(struct ph2handle *iph2)
613 621 {
614 622 initph2(iph2);
615 623
616 624 if (iph2->src) {
617 625 racoon_free(iph2->src);
618 626 iph2->src = NULL;
619 627 }
620 628 if (iph2->dst) {
621 629 racoon_free(iph2->dst);
|
↓ open down ↓ |
137 lines elided |
↑ open up ↑ |
622 630 iph2->dst = NULL;
623 631 }
624 632 if (iph2->src_id) {
625 633 racoon_free(iph2->src_id);
626 634 iph2->src_id = NULL;
627 635 }
628 636 if (iph2->dst_id) {
629 637 racoon_free(iph2->dst_id);
630 638 iph2->dst_id = NULL;
631 639 }
640 +#ifdef ENABLE_NATT
641 + if (iph2->natoa_src) {
642 + racoon_free(iph2->natoa_src);
643 + iph2->natoa_src = NULL;
644 + }
645 + if (iph2->natoa_dst) {
646 + racoon_free(iph2->natoa_dst);
647 + iph2->natoa_dst = NULL;
648 + }
649 +#endif
632 650
633 651 if (iph2->proposal) {
634 652 flushsaprop(iph2->proposal);
635 653 iph2->proposal = NULL;
636 654 }
637 655
638 656 sadb_request_finish(&iph2->sadb_request);
639 657
640 658 racoon_free(iph2);
641 659 }
642 660
643 661 /*
644 662 * create new isakmp Phase 2 status record to handle isakmp in Phase2
645 663 */
646 664 int
647 665 insph2(struct ph2handle *iph2)
648 666 {
649 667 LIST_INSERT_HEAD(&ph2tree, iph2, chain);
650 668
651 669 return 0;
652 670 }
653 671
654 672 void
655 673 remph2(struct ph2handle *iph2)
656 674 {
657 675 LIST_REMOVE(iph2, chain);
658 676 }
659 677
660 678 void
661 679 destroy_ph2(struct ph2handle *iph2)
662 680 {
663 681 /* delete_spd(iph2); */
664 682 unbindph12(iph2);
665 683 remph2(iph2);
666 684 delph2(iph2);
667 685 }
668 686
669 687
670 688 void
671 689 initph2tree(void)
672 690 {
673 691 LIST_INIT(&ph2tree);
674 692 }
675 693
676 694 void
677 695 flushph2(void)
678 696 {
679 697 struct ph2handle *p, *next;
680 698
681 699 for (p = LIST_FIRST(&ph2tree); p; p = next) {
682 700 next = LIST_NEXT(p, chain);
683 701
684 702 /* send delete information */
685 703 if (p->status == PHASE2ST_ESTABLISHED)
686 704 isakmp_info_send_d2(p);
687 705
688 706 destroy_ph2(p);
689 707 }
690 708 }
691 709
692 710 /*
693 711 * Delete all Phase 2 handlers for this src/dst/proto. This
694 712 * is used during INITIAL-CONTACT processing (so no need to
695 713 * send a message to the peer).
696 714 */
697 715 void
698 716 deleteallph2(struct sockaddr *src, struct sockaddr *dst, unsigned int proto_id)
699 717 {
700 718 struct ph2handle *iph2, *next;
701 719 struct saproto *pr;
702 720
703 721 for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
704 722 next = LIST_NEXT(iph2, chain);
705 723 if (iph2->proposal == NULL && iph2->approval == NULL)
706 724 continue;
707 725 if (iph2->approval != NULL) {
708 726 for (pr = iph2->approval->head; pr != NULL;
709 727 pr = pr->next) {
710 728 if (proto_id == pr->proto_id)
711 729 goto zap_it;
712 730 }
713 731 } else if (iph2->proposal != NULL) {
714 732 for (pr = iph2->proposal->head; pr != NULL;
715 733 pr = pr->next) {
716 734 if (proto_id == pr->proto_id)
717 735 goto zap_it;
718 736 }
719 737 }
720 738 continue;
721 739 zap_it:
722 740 unbindph12(iph2);
723 741 remph2(iph2);
724 742 delph2(iph2);
725 743 }
726 744 }
727 745
728 746 /* %%% */
729 747 void
730 748 bindph12(struct ph1handle *iph1, struct ph2handle *iph2)
731 749 {
732 750 iph2->ph1 = iph1;
733 751 LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
734 752 }
735 753
736 754 void
737 755 unbindph12(struct ph2handle *iph2)
738 756 {
739 757 if (iph2->ph1 != NULL) {
740 758 iph2->ph1 = NULL;
741 759 LIST_REMOVE(iph2, ph1bind);
742 760 }
743 761 }
744 762
745 763 /* %%% management contacted list */
746 764 /*
747 765 * search contacted list.
748 766 */
749 767 struct contacted *
750 768 getcontacted(struct sockaddr *remote)
751 769 {
752 770 struct contacted *p;
753 771
754 772 LIST_FOREACH(p, &ctdtree, chain) {
755 773 if (rcs_cmpsa(remote, p->remote) == 0)
756 774 return p;
757 775 }
758 776
759 777 return NULL;
760 778 }
761 779
762 780 /*
763 781 * create new isakmp Phase 2 status record to handle isakmp in Phase2
764 782 */
765 783 int
766 784 inscontacted(struct sockaddr *remote)
767 785 {
768 786 struct contacted *new;
769 787
770 788 /* create new iph2 */
771 789 new = racoon_calloc(1, sizeof(*new));
772 790 if (new == NULL)
773 791 return -1;
774 792
775 793 new->remote = rcs_sadup(remote);
776 794 if (!new->remote) {
777 795 racoon_free(new);
778 796 return -1;
779 797 }
780 798
781 799 LIST_INSERT_HEAD(&ctdtree, new, chain);
782 800
783 801 return 0;
784 802 }
785 803
786 804 void
787 805 initctdtree(void)
788 806 {
789 807 LIST_INIT(&ctdtree);
790 808 }
791 809
792 810 /*
793 811 * check the response has been sent to the peer. when not, simply reply
794 812 * the buffered packet to the peer.
795 813 * OUT:
796 814 * 0: the packet is received at the first time.
797 815 * 1: the packet was processed before.
798 816 * 2: the packet was processed before, but the address mismatches.
799 817 * -1: error happened.
800 818 */
801 819 int
802 820 check_recvdpkt(struct sockaddr *remote, struct sockaddr *local, rc_vchar_t *rbuf)
803 821 {
804 822 rc_vchar_t *hash;
805 823 struct recvdpkt *r;
806 824 time_t t;
807 825 int len, s;
808 826
809 827 /* set current time */
810 828 t = time(NULL);
811 829
812 830 hash = eay_md5_one(rbuf);
813 831 if (!hash) {
814 832 plog(PLOG_INTERR, PLOGLOC, NULL,
815 833 "failed to allocate buffer.\n");
816 834 return -1;
817 835 }
818 836
819 837 LIST_FOREACH(r, &rcptree, chain) {
820 838 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
821 839 break;
822 840 }
823 841 rc_vfree(hash);
824 842
825 843 /* this is the first time to receive the packet */
826 844 if (r == NULL)
827 845 return 0;
828 846
829 847 /*
830 848 * the packet was processed before, but the remote address mismatches.
831 849 */
832 850 if (rcs_cmpsa(remote, r->remote) != 0)
833 851 return 2;
834 852
835 853 /*
836 854 * it should not check the local address because the packet
837 855 * may arrive at other interface.
838 856 */
839 857
840 858 /* check the previous time to send */
841 859 if (t - r->time_send < 1) {
842 860 plog(PLOG_PROTOWARN, PLOGLOC, NULL,
843 861 "the packet retransmitted in a short time from %s\n",
844 862 rcs_sa2str(remote));
845 863 /*XXX should it be error ? */
846 864 }
847 865
848 866 /* select the socket to be sent */
849 867 s = getsockmyaddr(r->local);
850 868 if (s == -1)
851 869 return -1;
852 870
853 871 /* resend the packet if needed */
854 872 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
855 873 r->local, r->remote, 1 /* lcconf->count_persend */);
856 874 if (len == -1) {
857 875 plog(PLOG_INTERR, PLOGLOC, NULL, "sendfromto failed\n");
858 876 return -1;
859 877 }
860 878
861 879 /* check the retry counter */
862 880 r->retry_counter--;
863 881 if (r->retry_counter <= 0) {
864 882 rem_recvdpkt(r);
865 883 del_recvdpkt(r);
866 884 plog(PLOG_DEBUG, PLOGLOC, NULL,
867 885 "deleted the retransmission packet to %s.\n",
868 886 rcs_sa2str(remote));
869 887 } else
870 888 r->time_send = t;
871 889
872 890 return 1;
873 891 }
874 892
875 893 /*
876 894 * adding a hash of received packet into the received list.
877 895 */
878 896 int
879 897 add_recvdpkt(struct sockaddr *remote, struct sockaddr *local,
880 898 rc_vchar_t *sbuf, rc_vchar_t *rbuf, struct rcf_remote *conf)
881 899 {
882 900 struct recvdpkt *new = NULL;
883 901 int lifetime;
884 902
885 903 lifetime = ikev1_max_retry_to_send(conf) * ikev1_interval_to_send(conf);
886 904 if (lifetime == 0) {
887 905 /* no need to add it */
888 906 return 0;
889 907 }
890 908
891 909 new = racoon_calloc(1, sizeof(*new));
892 910 if (!new) {
893 911 plog(PLOG_INTERR, PLOGLOC, NULL,
894 912 "failed to allocate buffer.\n");
895 913 return -1;
896 914 }
897 915
898 916 new->hash = eay_md5_one(rbuf);
899 917 if (!new->hash) {
900 918 plog(PLOG_INTERR, PLOGLOC, NULL,
901 919 "failed to allocate buffer.\n");
902 920 del_recvdpkt(new);
903 921 return -1;
904 922 }
905 923 new->remote = rcs_sadup(remote);
906 924 if (new->remote == NULL) {
907 925 plog(PLOG_INTERR, PLOGLOC, NULL,
908 926 "failed to allocate buffer.\n");
909 927 del_recvdpkt(new);
910 928 return -1;
911 929 }
912 930 new->local = rcs_sadup(local);
913 931 if (new->local == NULL) {
914 932 plog(PLOG_INTERR, PLOGLOC, NULL,
915 933 "failed to allocate buffer.\n");
916 934 del_recvdpkt(new);
917 935 return -1;
918 936 }
919 937 new->sendbuf = rc_vdup(sbuf);
920 938 if (new->sendbuf == NULL) {
921 939 plog(PLOG_INTERR, PLOGLOC, NULL,
922 940 "failed to allocate buffer.\n");
923 941 del_recvdpkt(new);
924 942 return -1;
925 943 }
926 944
927 945 new->lifetime = lifetime;
928 946 new->time_send = 0;
929 947 new->created = time(NULL);
930 948
931 949 LIST_INSERT_HEAD(&rcptree, new, chain);
932 950
933 951 return 0;
934 952 }
935 953
936 954 void
937 955 del_recvdpkt(struct recvdpkt *r)
938 956 {
939 957 if (r->remote)
940 958 racoon_free(r->remote);
941 959 if (r->local)
942 960 racoon_free(r->local);
943 961 if (r->hash)
944 962 rc_vfree(r->hash);
945 963 if (r->sendbuf)
946 964 rc_vfree(r->sendbuf);
947 965 racoon_free(r);
948 966 }
949 967
950 968 void
951 969 rem_recvdpkt(struct recvdpkt *r)
952 970 {
953 971 LIST_REMOVE(r, chain);
954 972 }
955 973
956 974 int ikev1_recvdpkt_sweep_interval = 5; /* ??? */
957 975
958 976 void
959 977 sweep_recvdpkt(void *dummy)
960 978 {
961 979 struct recvdpkt *r, *next;
962 980 time_t t;
963 981
964 982 /* set current time */
965 983 t = time(NULL);
966 984
967 985 for (r = LIST_FIRST(&rcptree); r; r = next) {
968 986 next = LIST_NEXT(r, chain);
969 987
970 988 if (t > r->created + r->lifetime) {
971 989 rem_recvdpkt(r);
972 990 del_recvdpkt(r);
973 991 }
974 992 }
975 993
976 994 sched_new(ikev1_recvdpkt_sweep_interval, sweep_recvdpkt, NULL);
977 995 }
978 996
979 997 void
980 998 init_recvdpkt(void)
981 999 {
982 1000 LIST_INIT(&rcptree);
983 1001
984 1002 sched_new(ikev1_recvdpkt_sweep_interval, sweep_recvdpkt, NULL);
985 1003 }
986 1004
987 1005 #ifdef ENABLE_HYBRID
988 1006 /*
989 1007 * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
990 1008 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
991 1009 */
992 1010 int
993 1011 exclude_cfg_addr(const struct sockaddr *addr)
994 1012 {
995 1013 struct ph1handle *p;
996 1014 struct sockaddr_in *sin;
997 1015
998 1016 LIST_FOREACH(p, &ph1tree, chain) {
999 1017 if ((p->mode_cfg != NULL) &&
1000 1018 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
1001 1019 (addr->sa_family == AF_INET)) {
1002 1020 sin = (struct sockaddr_in *)addr;
1003 1021 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
1004 1022 return 0;
1005 1023 }
1006 1024 }
1007 1025
1008 1026 return 1;
1009 1027 }
1010 1028 #endif
1011 1029
1012 1030
1013 1031
1014 1032 #if 0
1015 1033 /*
1016 1034 * Reload conf code
1017 1035 */
1018 1036 static int revalidate_ph2(struct ph2handle *iph2){
1019 1037 struct sainfoalg *alg;
1020 1038 int found, check_level;
1021 1039 struct sainfo *sainfo;
1022 1040 struct saprop *approval;
1023 1041
1024 1042 /*
1025 1043 * Get the new sainfo using values of the old one
1026 1044 */
1027 1045 iph2->sainfo = getsainfo(iph2->sainfo->idsrc,
1028 1046 iph2->sainfo->iddst, iph2->sainfo->id_i);
1029 1047 approval = iph2->approval;
1030 1048 sainfo = iph2->sainfo;
1031 1049
1032 1050 if (sainfo == NULL) {
1033 1051 /*
1034 1052 * Sainfo has been removed
1035 1053 */
1036 1054 plog(PLOG_DEBUG, PLOGLOC, NULL,
1037 1055 "Reload: No sainfo for ph2\n");
1038 1056 return 0;
1039 1057 }
1040 1058
1041 1059 if (approval == NULL) {
1042 1060 /*
1043 1061 * XXX why do we have a NULL approval sometimes ???
1044 1062 */
1045 1063 plog(PLOG_DEBUG, PLOGLOC, NULL,
1046 1064 "No approval found !\n");
1047 1065 return 0;
1048 1066 }
1049 1067
1050 1068 /*
1051 1069 * Don't care about proposals, should we do something ?
1052 1070 * We have to keep iph2->proposal valid at least for initiator,
1053 1071 * for pk_sendgetspi()
1054 1072 */
1055 1073
1056 1074 plog(PLOG_DEBUG, PLOGLOC, NULL, "active single bundle:\n");
1057 1075 printsaprop0(PLOG_DEBUG, approval);
1058 1076
1059 1077 /*
1060 1078 * Validate approval against sainfo
1061 1079 * Note: we must have an updated ph1->rmconf before doing that,
1062 1080 * we'll set check_level to EXACT if we don't have a ph1
1063 1081 * XXX try tu find the new remote section to get the new check level ?
1064 1082 * XXX lifebyte
1065 1083 */
1066 1084 if (iph2->ph1 != NULL && iph2->ph1->rmconf != NULL) {
1067 1085 check_level = ikev1_proposal_check(iph2->ph1->rmconf);
1068 1086 } else {
1069 1087 plog(PLOG_DEBUG, PLOGLOC, NULL,
1070 1088 "No phase1 rmconf found !\n");
1071 1089 check_level = RCT_PCT_EXACT;
1072 1090 }
1073 1091
1074 1092 switch (check_level) {
1075 1093 case RCT_PCT_OBEY:
1076 1094 plog(PLOG_DEBUG, PLOGLOC, NULL,
1077 1095 "Reload: OBEY for ph2, ok\n");
1078 1096 return 1;
1079 1097 break;
1080 1098
1081 1099 case RCT_PCT_STRICT:
1082 1100 /* FALLTHROUGH */
1083 1101 case RCT_PCT_CLAIM:
1084 1102 if (sainfo->lifetime < approval->lifetime) {
1085 1103 plog(PLOG_DEBUG, PLOGLOC, NULL,
1086 1104 "Reload: lifetime mismatch\n");
1087 1105 return 0;
1088 1106 }
1089 1107
1090 1108 if (sainfo->lifebyte < approval->lifebyte) {
1091 1109 plog(PLOG_DEBUG, PLOGLOC, NULL,
1092 1110 "Reload: lifebyte mismatch\n");
1093 1111 return 0;
1094 1112 }
1095 1113
1096 1114 if (sainfo->pfs_group &&
1097 1115 sainfo->pfs_group != approval->pfs_group) {
1098 1116 plog(PLOG_DEBUG, PLOGLOC, NULL,
1099 1117 "Reload: PFS group mismatch\n");
1100 1118 return 0;
1101 1119 }
1102 1120 break;
1103 1121
1104 1122 case RCT_PCT_EXACT:
1105 1123 if (sainfo->lifetime != approval->lifetime ||
1106 1124 sainfo->lifebyte != approval->lifebyte ||
1107 1125 sainfo->pfs_group != iph2->approval->pfs_group) {
1108 1126 plog(PLOG_DEBUG, PLOGLOC, NULL,
1109 1127 "Reload: lifetime | pfs mismatch\n");
1110 1128 return 0;
1111 1129 }
1112 1130 break;
1113 1131
1114 1132 default:
1115 1133 plog(PLOG_DEBUG, PLOGLOC, NULL,
1116 1134 "Reload: Shouldn't be here !\n");
1117 1135 return 0;
1118 1136 break;
1119 1137 }
1120 1138
1121 1139 for (alg = sainfo->algs[algclass_ipsec_auth]; alg; alg = alg->next) {
1122 1140 if (alg->alg == approval->head->head->authtype)
1123 1141 break;
1124 1142 }
1125 1143 if (alg == NULL) {
1126 1144 plog(PLOG_DEBUG, PLOGLOC, NULL,
1127 1145 "Reload: alg == NULL (auth)\n");
1128 1146 return 0;
1129 1147 }
1130 1148
1131 1149 found = 0;
1132 1150 for (alg = sainfo->algs[algclass_ipsec_enc];
1133 1151 (found == 0 && alg != NULL); alg = alg->next) {
1134 1152 plog(PLOG_DEBUG, PLOGLOC, NULL,
1135 1153 "Reload: next ph2 enc alg...\n");
1136 1154
1137 1155 if (alg->alg != approval->head->head->trns_id){
1138 1156 plog(PLOG_DEBUG, PLOGLOC, NULL,
1139 1157 "Reload: encmode mismatch (%d / %d)\n",
1140 1158 alg->alg, approval->head->head->trns_id);
1141 1159 continue;
1142 1160 }
1143 1161
1144 1162 switch (check_level){
1145 1163 /* RCT_PCT_STRICT cannot happen here */
1146 1164 case RCT_PCT_EXACT:
1147 1165 if (alg->encklen != approval->head->head->encklen) {
1148 1166 plog(PLOG_DEBUG, PLOGLOC, NULL,
1149 1167 "Reload: enclen mismatch\n");
1150 1168 continue;
1151 1169 }
1152 1170 break;
1153 1171
1154 1172 case RCT_PCT_CLAIM:
1155 1173 /* FALLTHROUGH */
1156 1174 case RCT_PCT_STRICT:
1157 1175 if (alg->encklen > approval->head->head->encklen) {
1158 1176 plog(PLOG_DEBUG, PLOGLOC, NULL,
1159 1177 "Reload: enclen mismatch\n");
1160 1178 continue;
1161 1179 }
1162 1180 break;
1163 1181
1164 1182 default:
1165 1183 plog(PLOG_INTERR, PLOGLOC, NULL,
1166 1184 "unexpected check_level\n");
1167 1185 continue;
1168 1186 break;
1169 1187 }
1170 1188 found = 1;
1171 1189 }
1172 1190
1173 1191 if (!found){
1174 1192 plog(PLOG_DEBUG, PLOGLOC, NULL,
1175 1193 "Reload: No valid enc\n");
1176 1194 return 0;
1177 1195 }
1178 1196
1179 1197 /*
1180 1198 * XXX comp
1181 1199 */
1182 1200 plog(PLOG_DEBUG, PLOGLOC, NULL,
1183 1201 "Reload: ph2 check ok\n");
1184 1202
1185 1203 return 1;
1186 1204 }
1187 1205 #endif
1188 1206
1189 1207
1190 1208 #ifdef notyet
1191 1209 static void
1192 1210 remove_ph2(struct ph2handle *iph2)
1193 1211 {
1194 1212 uint32_t spis[2];
1195 1213
1196 1214 if(iph2 == NULL)
1197 1215 return;
1198 1216
1199 1217 plog(PLOG_DEBUG, PLOGLOC, NULL,
1200 1218 "Deleting a Ph2...\n");
1201 1219
1202 1220 if (iph2->status == PHASE2ST_ESTABLISHED)
1203 1221 isakmp_info_send_d2(iph2);
1204 1222
1205 1223 if(iph2->approval != NULL && iph2->approval->head != NULL){
1206 1224 spis[0]=iph2->approval->head->spi;
1207 1225 spis[1]=iph2->approval->head->spi_p;
1208 1226
1209 1227 /* purge_ipsec_spi() will do all the work:
1210 1228 * - delete SPIs in kernel
1211 1229 * - delete generated SPD
1212 1230 * - unbind / rem / del ph2
1213 1231 */
1214 1232 purge_ipsec_spi(iph2->ph1, iph2->dst, iph2->approval->head->proto_id,
1215 1233 spis, 2);
1216 1234 }else{
1217 1235 unbindph12(iph2);
1218 1236 remph2(iph2);
1219 1237 delph2(iph2);
1220 1238 }
1221 1239 }
1222 1240
1223 1241 static void
1224 1242 remove_ph1(struct ph1handle *iph1)
1225 1243 {
1226 1244 struct ph2handle *iph2, *iph2_next;
1227 1245
1228 1246 if(iph1 == NULL)
1229 1247 return;
1230 1248
1231 1249 plog(PLOG_DEBUG, PLOGLOC, NULL,
1232 1250 "Removing PH1...\n");
1233 1251
1234 1252 if (iph1->status == PHASE1ST_ESTABLISHED){
1235 1253 for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) {
1236 1254 iph2_next = LIST_NEXT(iph2, chain);
1237 1255 remove_ph2(iph2);
1238 1256 }
1239 1257 isakmp_info_send_d1(iph1);
1240 1258 }
1241 1259 iph1->status = PHASE1ST_EXPIRED;
1242 1260 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1243 1261 }
1244 1262
1245 1263
1246 1264 static int
1247 1265 revalidate_ph1tree_rmconf(void)
1248 1266 {
1249 1267 struct ph1handle *p, *next;
1250 1268 struct rcf_remote *newrmconf;
1251 1269
1252 1270 for (p = LIST_FIRST(&ph1tree); p; p = next) {
1253 1271 next = LIST_NEXT(p, chain);
1254 1272
1255 1273 if (p->status == PHASE1ST_EXPIRED)
1256 1274 continue;
1257 1275
1258 1276 newrmconf=getrmconf(p->remote);
1259 1277 if(newrmconf == NULL){
1260 1278 p->rmconf = NULL;
1261 1279 remove_ph1(p);
1262 1280 }else{
1263 1281 /* Do not free old rmconf, it is just a pointer to an entry in rmtree
1264 1282 */
1265 1283 p->rmconf=newrmconf;
1266 1284 if(p->approval != NULL){
1267 1285 struct isakmpsa *tmpsa;
1268 1286
1269 1287 tmpsa=dupisakmpsa(p->approval);
1270 1288 if(tmpsa != NULL){
1271 1289 delisakmpsa(p->approval);
1272 1290 p->approval=tmpsa;
1273 1291 p->approval->rmconf=newrmconf;
1274 1292 }
1275 1293 }
1276 1294 }
1277 1295 }
1278 1296
1279 1297 return 1;
1280 1298 }
1281 1299
1282 1300
1283 1301 /* rmconf is already updated here
1284 1302 */
1285 1303 static int
1286 1304 revalidate_ph1(struct ph1handle *iph1)
1287 1305 {
1288 1306 rc_type exchange_mode;
1289 1307 struct isakmpsa *p, *approval;
1290 1308 struct etypes *e;
1291 1309
1292 1310 if(iph1 == NULL ||
1293 1311 iph1->approval == NULL ||
1294 1312 iph1->rmconf == NULL)
1295 1313 return 0;
1296 1314
1297 1315 approval=iph1->approval;
1298 1316 for (p=iph1->rmconf->proposal; p != NULL; p=p->next){
1299 1317 plog(PLOG_DEBUG, PLOGLOC, NULL,
1300 1318 "Reload: Trying next proposal...\n");
1301 1319
1302 1320 if(approval->authmethod != p->authmethod){
1303 1321 plog(PLOG_DEBUG, PLOGLOC, NULL,
1304 1322 "Reload: Authmethod mismatch\n");
1305 1323 continue;
1306 1324 }
1307 1325
1308 1326 if(approval->enctype != p->enctype){
1309 1327 plog(PLOG_DEBUG, PLOGLOC, NULL,
1310 1328 "Reload: enctype mismatch\n");
1311 1329 continue;
1312 1330 }
1313 1331
1314 1332 switch (iph1->rmconf->pcheck_level) {
1315 1333 case RCT_PCT_OBEY:
1316 1334 plog(PLOG_DEBUG, PLOGLOC, NULL,
1317 1335 "Reload: OBEY pcheck level, ok...\n");
1318 1336 return 1;
1319 1337 break;
1320 1338
1321 1339 case RCT_PCT_CLAIM:
1322 1340 /* FALLTHROUGH */
1323 1341 case RCT_PCT_STRICT:
1324 1342 if (approval->encklen < p->encklen) {
1325 1343 plog(PLOG_DEBUG, PLOGLOC, NULL,
1326 1344 "Reload: encklen mismatch\n");
1327 1345 continue;
1328 1346 }
1329 1347
1330 1348 if (approval->lifetime > p->lifetime) {
1331 1349 plog(PLOG_DEBUG, PLOGLOC, NULL,
1332 1350 "Reload: lifetime mismatch\n");
1333 1351 continue;
1334 1352 }
1335 1353
1336 1354 if (approval->lifebyte > p->lifebyte) {
1337 1355 plog(PLOG_DEBUG, PLOGLOC, NULL,
1338 1356 "Reload: lifebyte mismatch\n");
1339 1357 continue;
1340 1358 }
1341 1359 break;
1342 1360
1343 1361 case RCT_PCT_EXACT:
1344 1362 if (approval->encklen != p->encklen) {
1345 1363 plog(PLOG_DEBUG, PLOGLOC, NULL,
1346 1364 "Reload: encklen mismatch\n");
1347 1365 continue;
1348 1366 }
1349 1367
1350 1368 if (approval->lifetime != p->lifetime) {
1351 1369 plog(PLOG_DEBUG, PLOGLOC, NULL,
1352 1370 "Reload: lifetime mismatch\n");
1353 1371 continue;
1354 1372 }
1355 1373
1356 1374 if (approval->lifebyte != p->lifebyte) {
1357 1375 plog(PLOG_DEBUG, PLOGLOC, NULL,
1358 1376 "Reload: lifebyte mismatch\n");
1359 1377 continue;
1360 1378 }
1361 1379 break;
1362 1380
1363 1381 default:
1364 1382 plog(PLOG_INTERR, PLOGLOC, NULL,
1365 1383 "unexpected check_level\n");
1366 1384 continue;
1367 1385 break;
1368 1386 }
1369 1387
1370 1388 if (approval->hashtype != p->hashtype) {
1371 1389 plog(PLOG_DEBUG, PLOGLOC, NULL,
1372 1390 "Reload: hashtype mismatch\n");
1373 1391 continue;
1374 1392 }
1375 1393
1376 1394 if (iph1->etype != ISAKMP_ETYPE_AGG &&
1377 1395 approval->dh_group != p->dh_group) {
1378 1396 plog(PLOG_DEBUG, PLOGLOC, NULL,
1379 1397 "Reload: dhgroup mismatch\n");
1380 1398 continue;
1381 1399 }
1382 1400
1383 1401 plog(PLOG_DEBUG, PLOGLOC, NULL, "Reload: Conf ok\n");
1384 1402 return 1;
1385 1403 }
1386 1404
1387 1405 plog(PLOG_DEBUG, PLOGLOC, NULL, "Reload: No valid conf found\n");
1388 1406 return 0;
1389 1407 }
1390 1408
1391 1409
1392 1410 static int
1393 1411 revalidate_ph1tree(void)
1394 1412 {
1395 1413 struct ph1handle *p, *next;
1396 1414
1397 1415 for (p = LIST_FIRST(&ph1tree); p; p = next) {
1398 1416 next = LIST_NEXT(p, chain);
1399 1417
1400 1418 if (p->status == PHASE1ST_EXPIRED)
1401 1419 continue;
1402 1420
1403 1421 if(!revalidate_ph1(p))
1404 1422 remove_ph1(p);
1405 1423 }
1406 1424
1407 1425 return 1;
1408 1426 }
1409 1427
1410 1428 static int
1411 1429 revalidate_ph2tree(void)
1412 1430 {
1413 1431 struct ph2handle *p, *next;
1414 1432
1415 1433 for (p = LIST_FIRST(&ph2tree); p; p = next) {
1416 1434 next = LIST_NEXT(p, chain);
1417 1435
1418 1436 if (p->status == PHASE2ST_EXPIRED)
1419 1437 continue;
1420 1438
1421 1439 if(!revalidate_ph2(p)){
1422 1440 plog(PLOG_DEBUG, PLOGLOC, NULL,
1423 1441 "PH2 not validated, removing it\n");
1424 1442 remove_ph2(p);
1425 1443 }
1426 1444 }
1427 1445
1428 1446 return 1;
1429 1447 }
1430 1448
1431 1449 int
1432 1450 revalidate_ph12(void)
1433 1451 {
1434 1452
1435 1453 revalidate_ph1tree_rmconf();
1436 1454
1437 1455 revalidate_ph2tree();
1438 1456 revalidate_ph1tree();
1439 1457
1440 1458 return 1;
1441 1459 }
1442 1460 #endif
1443 1461
1444 1462 #ifdef ENABLE_HYBRID
1445 1463 struct ph1handle *
1446 1464 getph1bylogin(char *login)
1447 1465 {
1448 1466 struct ph1handle *p;
1449 1467
1450 1468 LIST_FOREACH(p, &ph1tree, chain) {
1451 1469 if (p->mode_cfg == NULL)
1452 1470 continue;
1453 1471 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0)
1454 1472 return p;
1455 1473 }
1456 1474
1457 1475 return NULL;
1458 1476 }
1459 1477
1460 1478 int
1461 1479 purgeph1bylogin(char *login)
1462 1480 {
1463 1481 struct ph1handle *p;
1464 1482 int found = 0;
1465 1483
1466 1484 LIST_FOREACH(p, &ph1tree, chain) {
1467 1485 if (p->mode_cfg == NULL)
1468 1486 continue;
1469 1487 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) {
1470 1488 if (p->status == PHASE1ST_ESTABLISHED)
1471 1489 isakmp_info_send_d1(p);
1472 1490 purge_remote(p);
1473 1491 found++;
1474 1492 }
1475 1493 }
1476 1494
1477 1495 return found;
1478 1496 }
1479 1497 #endif
1480 1498
|
↓ open down ↓ |
839 lines elided |
↑ open up ↑ |
1481 1499
1482 1500 static int
1483 1501 delete_ipsec_sa(struct sadb_request *r,
1484 1502 struct sockaddr *src, struct sockaddr *dst, int proto,
1485 1503 uint32_t spi/* network order */)
1486 1504 {
1487 1505 struct rcpfk_msg param;
1488 1506 int satype;
1489 1507 int retval;
1490 1508
1509 + (void) memset(¶m, 0, sizeof (param));
1510 +
1491 1511 switch (proto) {
1492 1512 case IPSECDOI_PROTO_IPSEC_AH:
1493 1513 satype = RCT_SATYPE_AH;
1494 1514 break;
1495 1515 case IPSECDOI_PROTO_IPSEC_ESP:
1496 1516 satype = RCT_SATYPE_ESP;
1497 1517 break;
1498 1518 case IPSECDOI_PROTO_IPCOMP:
1499 1519 satype = RCT_SATYPE_IPCOMP;
1500 1520 break;
1501 1521 default:
1502 1522 plog(PLOG_INTERR, PLOGLOC, 0,
1503 1523 "unsupported IPSECDOI protocol ID (%d)\n",
1504 1524 proto);
1505 1525 retval = -1;
1506 1526 goto done;
1507 1527 break;
1508 1528 }
1509 1529
1510 1530 param.sa_src = src;
1511 1531 param.sa_dst = dst;
1512 1532 param.satype = satype;
1513 1533 param.spi = spi;
1514 1534 retval = r->method->delete_sa(¶m);
1515 1535
1516 1536 done:
1517 1537 return retval;
1518 1538 }
1519 1539
1520 1540
1521 1541 void
1522 1542 purge_remote(struct ph1handle *iph1)
1523 1543 {
1524 1544 struct ph2handle *iph2;
1525 1545 struct ph2handle *next_ph2;
1526 1546 struct saprop *pp;
1527 1547 struct saproto *pr;
1528 1548
1529 1549 plog(PLOG_INFO, PLOGLOC, 0,
1530 1550 "purging ISAKMP-SA spi=%s.\n",
1531 1551 isakmp_pindex(&(iph1->index), iph1->msgid));
1532 1552
1533 1553 /* Mark as expired. */
1534 1554 iph1->status = PHASE1ST_EXPIRED;
1535 1555
1536 1556 for (iph2 = LIST_FIRST(&ph2tree); iph2; iph2 = next_ph2) {
1537 1557 next_ph2 = LIST_NEXT(iph2, chain);
1538 1558
1539 1559 if (iph2->ph1 != iph1)
1540 1560 continue;
1541 1561
1542 1562 pp = iph2->approval;
1543 1563 if (pp != NULL) {
1544 1564 for (pr = pp->head; pr != NULL; pr = pr->next) {
1545 1565 TRACE((PLOGLOC, "proto %d spi 0x%08" PRIx32 "\n",
1546 1566 pr->proto_id,
1547 1567 ntohl(pr->spi)));
1548 1568 (void) delete_ipsec_sa(&iph2->sadb_request,
1549 1569 iph2->src,
1550 1570 iph2->dst,
1551 1571 pr->proto_id, pr->spi_p);
1552 1572 (void) delete_ipsec_sa(&iph2->sadb_request,
1553 1573 iph2->dst,
1554 1574 iph2->src,
1555 1575 pr->proto_id, pr->spi);
1556 1576 }
1557 1577 }
1558 1578
1559 1579 destroy_ph2(iph2);
1560 1580 }
1561 1581 }
1562 1582
1563 1583
1564 1584 void
1565 1585 purge_ipsec_spi(struct ph1handle *ph1,
1566 1586 struct sockaddr *dst0,
1567 1587 int proto_id,
1568 1588 uint32_t *spi_ptr/*network byteorder*/,
1569 1589 int n)
1570 1590 {
1571 1591 struct ph2handle *iph2;
1572 1592 uint32_t spi;
1573 1593 int all_done;
1574 1594 struct saprop *pp;
1575 1595 struct saproto *pr;
1576 1596 int i;
1577 1597
1578 1598 for (i = 0; i < n; ++i) {
1579 1599 spi = htonl(get_uint32(&spi_ptr[i]));
1580 1600 iph2 = getph2bysaidx(ph1->local, ph1->remote, proto_id, spi);
1581 1601 if (iph2 != NULL) {
1582 1602 pp = iph2->approval;
1583 1603 all_done = TRUE;
1584 1604 for (pr = pp->head; pr != NULL; pr = pr->next) {
1585 1605 TRACE((PLOGLOC, "proto %d spi 0x%08" PRIx32 "\n",
1586 1606 pr->proto_id,
1587 1607 ntohl(pr->spi_p)));
1588 1608 if (pr->proto_id == proto_id && pr->spi_p == spi) {
1589 1609 (void) delete_ipsec_sa(&iph2->sadb_request,
1590 1610 iph2->src,
1591 1611 iph2->dst,
1592 1612 proto_id, spi);
1593 1613 pr->spi_p = 0;
1594 1614 } else if (pr->spi_p != 0) {
1595 1615 all_done = FALSE;
1596 1616 }
1597 1617 }
1598 1618
1599 1619 if (all_done)
1600 1620 destroy_ph2(iph2);
1601 1621 }
1602 1622 }
1603 1623 }
1604 1624
|
↓ open down ↓ |
104 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX