Annotation of embedaddon/ipsec-tools/src/racoon/pfkey.c, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $ */
2:
3: /* $Id: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $ */
4:
5: /*
6: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. Neither the name of the project nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include "config.h"
35:
36: #include <stdlib.h>
37: #include <string.h>
38: #include <stdio.h>
39: #include <netdb.h>
40: #include <errno.h>
41: #ifdef HAVE_UNISTD_H
42: #include <unistd.h>
43: #endif
44: #include <netdb.h>
45: #include <netinet/in.h>
46: #include <arpa/inet.h>
47:
48: #ifdef ENABLE_NATT
49: # ifdef __linux__
50: # include <linux/udp.h>
51: # endif
52: # if defined(__NetBSD__) || defined(__FreeBSD__) || \
53: (defined(__APPLE__) && defined(__MACH__))
54: # include <netinet/udp.h>
55: # endif
56: #endif
57:
58: #include <sys/types.h>
59: #include <sys/param.h>
60: #include <sys/socket.h>
61: #include <sys/queue.h>
62: #include <sys/sysctl.h>
63:
64: #include <net/route.h>
65: #include <net/pfkeyv2.h>
66:
67: #include <netinet/in.h>
68: #include PATH_IPSEC_H
69: #include <fcntl.h>
70:
71: #include "libpfkey.h"
72:
73: #include "var.h"
74: #include "misc.h"
75: #include "vmbuf.h"
76: #include "plog.h"
77: #include "sockmisc.h"
78: #include "session.h"
79: #include "debug.h"
80:
81: #include "schedule.h"
82: #include "localconf.h"
83: #include "remoteconf.h"
84: #include "handler.h"
85: #include "policy.h"
86: #include "proposal.h"
87: #include "isakmp_var.h"
88: #include "isakmp.h"
89: #include "isakmp_inf.h"
90: #include "ipsec_doi.h"
91: #include "oakley.h"
92: #include "pfkey.h"
93: #include "algorithm.h"
94: #include "sainfo.h"
95: #include "admin.h"
96: #include "evt.h"
97: #include "privsep.h"
98: #include "strnames.h"
99: #include "backupsa.h"
100: #include "gcmalloc.h"
101: #include "nattraversal.h"
102: #include "crypto_openssl.h"
103: #include "grabmyaddr.h"
104:
105: #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
106: #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
107: #endif
108:
109: /* prototype */
110: static u_int ipsecdoi2pfkey_aalg __P((u_int));
111: static u_int ipsecdoi2pfkey_ealg __P((u_int));
112: static u_int ipsecdoi2pfkey_calg __P((u_int));
113: static u_int ipsecdoi2pfkey_alg __P((u_int, u_int));
114: static u_int keylen_aalg __P((u_int));
115: static u_int keylen_ealg __P((u_int, int));
116:
117: static int pk_recvgetspi __P((caddr_t *));
118: static int pk_recvupdate __P((caddr_t *));
119: static int pk_recvadd __P((caddr_t *));
120: static int pk_recvdelete __P((caddr_t *));
121: static int pk_recvacquire __P((caddr_t *));
122: static int pk_recvexpire __P((caddr_t *));
123: static int pk_recvflush __P((caddr_t *));
124: static int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *));
125: static int pk_recvspdupdate __P((caddr_t *));
126: static int pk_recvspdadd __P((caddr_t *));
127: static int pk_recvspddelete __P((caddr_t *));
128: static int pk_recvspdexpire __P((caddr_t *));
129: static int pk_recvspdget __P((caddr_t *));
130: static int pk_recvspddump __P((caddr_t *));
131: static int pk_recvspdflush __P((caddr_t *));
132: #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
133: static int pk_recvmigrate __P((caddr_t *));
134: #endif
135: static struct sadb_msg *pk_recv __P((int, int *));
136:
137: static int (*pkrecvf[]) __P((caddr_t *)) = {
138: NULL,
139: pk_recvgetspi,
140: pk_recvupdate,
141: pk_recvadd,
142: pk_recvdelete,
143: NULL, /* SADB_GET */
144: pk_recvacquire,
145: NULL, /* SABD_REGISTER */
146: pk_recvexpire,
147: pk_recvflush,
148: NULL, /* SADB_DUMP */
149: NULL, /* SADB_X_PROMISC */
150: NULL, /* SADB_X_PCHANGE */
151: pk_recvspdupdate,
152: pk_recvspdadd,
153: pk_recvspddelete,
154: pk_recvspdget,
155: NULL, /* SADB_X_SPDACQUIRE */
156: pk_recvspddump,
157: pk_recvspdflush,
158: NULL, /* SADB_X_SPDSETIDX */
159: pk_recvspdexpire,
160: NULL, /* SADB_X_SPDDELETE2 */
161: NULL, /* SADB_X_NAT_T_NEW_MAPPING */
162: #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
163: pk_recvmigrate,
164: #else
165: NULL, /* SADB_X_MIGRATE */
166: #endif
167: #if (SADB_MAX > 24)
168: #error "SADB extra message?"
169: #endif
170: };
171:
172: static int addnewsp __P((caddr_t *, struct sockaddr *, struct sockaddr *));
173:
174: /* cope with old kame headers - ugly */
175: #ifndef SADB_X_AALG_MD5
176: #define SADB_X_AALG_MD5 SADB_AALG_MD5
177: #endif
178: #ifndef SADB_X_AALG_SHA
179: #define SADB_X_AALG_SHA SADB_AALG_SHA
180: #endif
181: #ifndef SADB_X_AALG_NULL
182: #define SADB_X_AALG_NULL SADB_AALG_NULL
183: #endif
184:
185: #ifndef SADB_X_EALG_BLOWFISHCBC
186: #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
187: #endif
188: #ifndef SADB_X_EALG_CAST128CBC
189: #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
190: #endif
191: #ifndef SADB_X_EALG_RC5CBC
192: #ifdef SADB_EALG_RC5CBC
193: #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
194: #endif
195: #endif
196:
197: /*
198: * PF_KEY packet handler
199: * 0: success
200: * -1: fail
201: */
202: static int
203: pfkey_handler(ctx, fd)
204: void *ctx;
205: int fd;
206: {
207: struct sadb_msg *msg;
208: int len;
209: caddr_t mhp[SADB_EXT_MAX + 1];
210: int error = -1;
211:
212: /* receive pfkey message. */
213: len = 0;
214: msg = (struct sadb_msg *) pk_recv(fd, &len);
215: if (msg == NULL) {
216: if (len < 0) {
217: /* do not report EAGAIN as error; well get
218: * called from main loop later. and it's normal
219: * when spd dump is received during reload and
220: * this function is called in loop. */
221: if (errno == EAGAIN)
222: goto end;
223:
224: plog(LLV_ERROR, LOCATION, NULL,
225: "failed to recv from pfkey (%s)\n",
226: strerror(errno));
227: goto end;
228: } else {
229: /* short message - msg not ready */
230: return 0;
231: }
232: }
233:
234: plog(LLV_DEBUG, LOCATION, NULL, "got pfkey %s message\n",
235: s_pfkey_type(msg->sadb_msg_type));
236: plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
237:
238: /* validity check */
239: if (msg->sadb_msg_errno) {
240: int pri;
241:
242: /* when SPD is empty, treat the state as no error. */
243: if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
244: msg->sadb_msg_errno == ENOENT)
245: pri = LLV_DEBUG;
246: else
247: pri = LLV_ERROR;
248:
249: plog(pri, LOCATION, NULL,
250: "pfkey %s failed: %s\n",
251: s_pfkey_type(msg->sadb_msg_type),
252: strerror(msg->sadb_msg_errno));
253:
254: goto end;
255: }
256:
257: /* check pfkey message. */
258: if (pfkey_align(msg, mhp)) {
259: plog(LLV_ERROR, LOCATION, NULL,
260: "libipsec failed pfkey align (%s)\n",
261: ipsec_strerror());
262: goto end;
263: }
264: if (pfkey_check(mhp)) {
265: plog(LLV_ERROR, LOCATION, NULL,
266: "libipsec failed pfkey check (%s)\n",
267: ipsec_strerror());
268: goto end;
269: }
270: msg = (struct sadb_msg *)mhp[0];
271:
272: /* safety check */
273: if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
274: plog(LLV_ERROR, LOCATION, NULL,
275: "unknown PF_KEY message type=%u\n",
276: msg->sadb_msg_type);
277: goto end;
278: }
279:
280: if (pkrecvf[msg->sadb_msg_type] == NULL) {
281: plog(LLV_INFO, LOCATION, NULL,
282: "unsupported PF_KEY message %s\n",
283: s_pfkey_type(msg->sadb_msg_type));
284: goto end;
285: }
286:
287: if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
288: goto end;
289:
290: error = 1;
291: end:
292: if (msg)
293: racoon_free(msg);
294: return(error);
295: }
296:
297: /*
298: * dump SADB
299: */
300: vchar_t *
301: pfkey_dump_sadb(satype)
302: int satype;
303: {
304: int s;
305: vchar_t *buf = NULL;
306: pid_t pid = getpid();
307: struct sadb_msg *msg = NULL;
308: size_t bl, ml;
309: int len;
310: int bufsiz;
311:
312: if ((s = privsep_socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
313: plog(LLV_ERROR, LOCATION, NULL,
314: "libipsec failed pfkey open: %s\n",
315: ipsec_strerror());
316: return NULL;
317: }
318:
319: if ((bufsiz = pfkey_set_buffer_size(s, lcconf->pfkey_buffer_size)) < 0) {
320: plog(LLV_ERROR, LOCATION, NULL,
321: "libipsec failed pfkey set buffer size to %d: %s\n",
322: lcconf->pfkey_buffer_size, ipsec_strerror());
323: return NULL;
324: } else if (bufsiz < lcconf->pfkey_buffer_size) {
325: plog(LLV_WARNING, LOCATION, NULL,
326: "pfkey socket receive buffer set to %dKB, instead of %d\n",
327: bufsiz, lcconf->pfkey_buffer_size);
328: }
329:
330: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
331: if (pfkey_send_dump(s, satype) < 0) {
332: plog(LLV_ERROR, LOCATION, NULL,
333: "libipsec failed dump: %s\n", ipsec_strerror());
334: goto fail;
335: }
336:
337: while (1) {
338: if (msg)
339: racoon_free(msg);
340: msg = pk_recv(s, &len);
341: if (msg == NULL) {
342: if (len < 0)
343: goto done;
344: else
345: continue;
346: }
347:
348: if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid)
349: {
350: plog(LLV_DEBUG, LOCATION, NULL,
351: "discarding non-sadb dump msg %p, our pid=%i\n", msg, pid);
352: plog(LLV_DEBUG, LOCATION, NULL,
353: "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid);
354: continue;
355: }
356:
357:
358: ml = msg->sadb_msg_len << 3;
359: bl = buf ? buf->l : 0;
360: buf = vrealloc(buf, bl + ml);
361: if (buf == NULL) {
362: plog(LLV_ERROR, LOCATION, NULL,
363: "failed to reallocate buffer to dump.\n");
364: goto fail;
365: }
366: memcpy(buf->v + bl, msg, ml);
367:
368: if (msg->sadb_msg_seq == 0)
369: break;
370: }
371: goto done;
372:
373: fail:
374: if (buf)
375: vfree(buf);
376: buf = NULL;
377: done:
378: if (msg)
379: racoon_free(msg);
380: close(s);
381: return buf;
382: }
383:
384: #ifdef ENABLE_ADMINPORT
385: /*
386: * flush SADB
387: */
388: void
389: pfkey_flush_sadb(proto)
390: u_int proto;
391: {
392: int satype;
393:
394: /* convert to SADB_SATYPE */
395: if ((satype = admin2pfkey_proto(proto)) < 0)
396: return;
397:
398: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
399: if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
400: plog(LLV_ERROR, LOCATION, NULL,
401: "libipsec failed send flush (%s)\n", ipsec_strerror());
402: return;
403: }
404:
405: return;
406: }
407: #endif
408:
409: /*
410: * These are the SATYPEs that we manage. We register to get
411: * PF_KEY messages related to these SATYPEs, and we also use
412: * this list to determine which SATYPEs to delete SAs for when
413: * we receive an INITIAL-CONTACT.
414: */
415: const struct pfkey_satype pfkey_satypes[] = {
416: { SADB_SATYPE_AH, "AH" },
417: { SADB_SATYPE_ESP, "ESP" },
418: { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
419: };
420: const int pfkey_nsatypes =
421: sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
422:
423: /*
424: * PF_KEY initialization
425: */
426: int
427: pfkey_init()
428: {
429: int i, reg_fail;
430: int bufsiz;
431:
432: if ((lcconf->sock_pfkey = pfkey_open()) < 0) {
433: plog(LLV_ERROR, LOCATION, NULL,
434: "libipsec failed pfkey open (%s)\n", ipsec_strerror());
435: return -1;
436: }
437: if ((bufsiz = pfkey_set_buffer_size(lcconf->sock_pfkey,
438: lcconf->pfkey_buffer_size)) < 0) {
439: plog(LLV_ERROR, LOCATION, NULL,
440: "libipsec failed to set pfkey buffer size to %d (%s)\n",
441: lcconf->pfkey_buffer_size, ipsec_strerror());
442: return -1;
443: } else if (bufsiz < lcconf->pfkey_buffer_size) {
444: plog(LLV_WARNING, LOCATION, NULL,
445: "pfkey socket receive buffer set to %dKB, instead of %d\n",
446: bufsiz, lcconf->pfkey_buffer_size);
447: }
448:
449: if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1)
450: plog(LLV_WARNING, LOCATION, NULL,
451: "failed to set the pfkey socket to NONBLOCK\n");
452:
453: for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
454: plog(LLV_DEBUG, LOCATION, NULL,
455: "call pfkey_send_register for %s\n",
456: pfkey_satypes[i].ps_name);
457: if (pfkey_send_register(lcconf->sock_pfkey,
458: pfkey_satypes[i].ps_satype) < 0 ||
459: pfkey_recv_register(lcconf->sock_pfkey) < 0) {
460: plog(LLV_WARNING, LOCATION, NULL,
461: "failed to register %s (%s)\n",
462: pfkey_satypes[i].ps_name,
463: ipsec_strerror());
464: reg_fail++;
465: }
466: }
467:
468: if (reg_fail == pfkey_nsatypes) {
469: plog(LLV_ERROR, LOCATION, NULL,
470: "failed to regist any protocol.\n");
471: pfkey_close(lcconf->sock_pfkey);
472: return -1;
473: }
474:
475: initsp();
476:
477: if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
478: plog(LLV_ERROR, LOCATION, NULL,
479: "libipsec sending spddump failed: %s\n",
480: ipsec_strerror());
481: pfkey_close(lcconf->sock_pfkey);
482: return -1;
483: }
484: #if 0
485: if (pfkey_promisc_toggle(1) < 0) {
486: pfkey_close(lcconf->sock_pfkey);
487: return -1;
488: }
489: #endif
490: monitor_fd(lcconf->sock_pfkey, pfkey_handler, NULL, 0);
491: return 0;
492: }
493:
494: int
495: pfkey_reload()
496: {
497: flushsp();
498:
499: if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
500: plog(LLV_ERROR, LOCATION, NULL,
501: "libipsec sending spddump failed: %s\n",
502: ipsec_strerror());
503: return -1;
504: }
505:
506: while (pfkey_handler(NULL, lcconf->sock_pfkey) > 0)
507: continue;
508:
509: return 0;
510: }
511:
512: /* %%% for conversion */
513: /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
514: static u_int
515: ipsecdoi2pfkey_aalg(hashtype)
516: u_int hashtype;
517: {
518: switch (hashtype) {
519: case IPSECDOI_ATTR_AUTH_HMAC_MD5:
520: return SADB_AALG_MD5HMAC;
521: case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
522: return SADB_AALG_SHA1HMAC;
523: case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
524: #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
525: return SADB_X_AALG_SHA2_256;
526: #else
527: return SADB_X_AALG_SHA2_256HMAC;
528: #endif
529: case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
530: #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
531: return SADB_X_AALG_SHA2_384;
532: #else
533: return SADB_X_AALG_SHA2_384HMAC;
534: #endif
535: case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
536: #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
537: return SADB_X_AALG_SHA2_512;
538: #else
539: return SADB_X_AALG_SHA2_512HMAC;
540: #endif
541: case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */
542: return SADB_AALG_NONE;
543:
544: /* not supported */
545: case IPSECDOI_ATTR_AUTH_DES_MAC:
546: plog(LLV_ERROR, LOCATION, NULL,
547: "Not supported hash type: %u\n", hashtype);
548: return ~0;
549:
550: case 0: /* reserved */
551: default:
552: return SADB_AALG_NONE;
553:
554: plog(LLV_ERROR, LOCATION, NULL,
555: "Invalid hash type: %u\n", hashtype);
556: return ~0;
557: }
558: /*NOTREACHED*/
559: }
560:
561: /* IPSECDOI_ESP -> SADB_EALG */
562: static u_int
563: ipsecdoi2pfkey_ealg(t_id)
564: u_int t_id;
565: {
566: switch (t_id) {
567: case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */
568: return SADB_EALG_DESCBC;
569: case IPSECDOI_ESP_DES:
570: return SADB_EALG_DESCBC;
571: case IPSECDOI_ESP_3DES:
572: return SADB_EALG_3DESCBC;
573: #ifdef SADB_X_EALG_RC5CBC
574: case IPSECDOI_ESP_RC5:
575: return SADB_X_EALG_RC5CBC;
576: #endif
577: case IPSECDOI_ESP_CAST:
578: return SADB_X_EALG_CAST128CBC;
579: case IPSECDOI_ESP_BLOWFISH:
580: return SADB_X_EALG_BLOWFISHCBC;
581: case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD|
582: SADB_X_EXT_IV4B)*/
583: return SADB_EALG_DESCBC;
584: case IPSECDOI_ESP_NULL:
585: return SADB_EALG_NULL;
586: #ifdef SADB_X_EALG_AESCBC
587: case IPSECDOI_ESP_AES:
588: return SADB_X_EALG_AESCBC;
589: #endif
590: #ifdef SADB_X_EALG_TWOFISHCBC
591: case IPSECDOI_ESP_TWOFISH:
592: return SADB_X_EALG_TWOFISHCBC;
593: #endif
594: #ifdef SADB_X_EALG_CAMELLIACBC
595: case IPSECDOI_ESP_CAMELLIA:
596: return SADB_X_EALG_CAMELLIACBC;
597: #endif
598:
599: /* not supported */
600: case IPSECDOI_ESP_3IDEA:
601: case IPSECDOI_ESP_IDEA:
602: case IPSECDOI_ESP_RC4:
603: plog(LLV_ERROR, LOCATION, NULL,
604: "Not supported transform: %u\n", t_id);
605: return ~0;
606:
607: case 0: /* reserved */
608: default:
609: plog(LLV_ERROR, LOCATION, NULL,
610: "Invalid transform id: %u\n", t_id);
611: return ~0;
612: }
613: /*NOTREACHED*/
614: }
615:
616: /* IPCOMP -> SADB_CALG */
617: static u_int
618: ipsecdoi2pfkey_calg(t_id)
619: u_int t_id;
620: {
621: switch (t_id) {
622: case IPSECDOI_IPCOMP_OUI:
623: return SADB_X_CALG_OUI;
624: case IPSECDOI_IPCOMP_DEFLATE:
625: return SADB_X_CALG_DEFLATE;
626: case IPSECDOI_IPCOMP_LZS:
627: return SADB_X_CALG_LZS;
628:
629: case 0: /* reserved */
630: default:
631: plog(LLV_ERROR, LOCATION, NULL,
632: "Invalid transform id: %u\n", t_id);
633: return ~0;
634: }
635: /*NOTREACHED*/
636: }
637:
638: /* IPSECDOI_PROTO -> SADB_SATYPE */
639: u_int
640: ipsecdoi2pfkey_proto(proto)
641: u_int proto;
642: {
643: switch (proto) {
644: case IPSECDOI_PROTO_IPSEC_AH:
645: return SADB_SATYPE_AH;
646: case IPSECDOI_PROTO_IPSEC_ESP:
647: return SADB_SATYPE_ESP;
648: case IPSECDOI_PROTO_IPCOMP:
649: return SADB_X_SATYPE_IPCOMP;
650:
651: default:
652: plog(LLV_ERROR, LOCATION, NULL,
653: "Invalid ipsec_doi proto: %u\n", proto);
654: return ~0;
655: }
656: /*NOTREACHED*/
657: }
658:
659: static u_int
660: ipsecdoi2pfkey_alg(algclass, type)
661: u_int algclass, type;
662: {
663: switch (algclass) {
664: case IPSECDOI_ATTR_AUTH:
665: return ipsecdoi2pfkey_aalg(type);
666: case IPSECDOI_PROTO_IPSEC_ESP:
667: return ipsecdoi2pfkey_ealg(type);
668: case IPSECDOI_PROTO_IPCOMP:
669: return ipsecdoi2pfkey_calg(type);
670: default:
671: plog(LLV_ERROR, LOCATION, NULL,
672: "Invalid ipsec_doi algclass: %u\n", algclass);
673: return ~0;
674: }
675: /*NOTREACHED*/
676: }
677:
678: /* SADB_SATYPE -> IPSECDOI_PROTO */
679: u_int
680: pfkey2ipsecdoi_proto(satype)
681: u_int satype;
682: {
683: switch (satype) {
684: case SADB_SATYPE_AH:
685: return IPSECDOI_PROTO_IPSEC_AH;
686: case SADB_SATYPE_ESP:
687: return IPSECDOI_PROTO_IPSEC_ESP;
688: case SADB_X_SATYPE_IPCOMP:
689: return IPSECDOI_PROTO_IPCOMP;
690:
691: default:
692: plog(LLV_ERROR, LOCATION, NULL,
693: "Invalid pfkey proto: %u\n", satype);
694: return ~0;
695: }
696: /*NOTREACHED*/
697: }
698:
699: /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
700: u_int
701: ipsecdoi2pfkey_mode(mode)
702: u_int mode;
703: {
704: switch (mode) {
705: case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
706: #ifdef ENABLE_NATT
707: case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
708: case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
709: #endif
710: return IPSEC_MODE_TUNNEL;
711: case IPSECDOI_ATTR_ENC_MODE_TRNS:
712: #ifdef ENABLE_NATT
713: case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
714: case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
715: #endif
716: return IPSEC_MODE_TRANSPORT;
717: default:
718: plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
719: return ~0;
720: }
721: /*NOTREACHED*/
722: }
723:
724: /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
725: u_int
726: pfkey2ipsecdoi_mode(mode)
727: u_int mode;
728: {
729: switch (mode) {
730: case IPSEC_MODE_TUNNEL:
731: return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
732: case IPSEC_MODE_TRANSPORT:
733: return IPSECDOI_ATTR_ENC_MODE_TRNS;
734: case IPSEC_MODE_ANY:
735: return IPSECDOI_ATTR_ENC_MODE_ANY;
736: default:
737: plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
738: return ~0;
739: }
740: /*NOTREACHED*/
741: }
742:
743: /* default key length for encryption algorithm */
744: static u_int
745: keylen_aalg(hashtype)
746: u_int hashtype;
747: {
748: int res;
749:
750: if (hashtype == 0)
751: return SADB_AALG_NONE;
752:
753: res = alg_ipsec_hmacdef_hashlen(hashtype);
754: if (res == -1) {
755: plog(LLV_ERROR, LOCATION, NULL,
756: "invalid hmac algorithm %u.\n", hashtype);
757: return ~0;
758: }
759: return res;
760: }
761:
762: /* default key length for encryption algorithm */
763: static u_int
764: keylen_ealg(enctype, encklen)
765: u_int enctype;
766: int encklen;
767: {
768: int res;
769:
770: res = alg_ipsec_encdef_keylen(enctype, encklen);
771: if (res == -1) {
772: plog(LLV_ERROR, LOCATION, NULL,
773: "invalid encryption algorithm %u.\n", enctype);
774: return ~0;
775: }
776: return res;
777: }
778:
779: void
780: pk_fixup_sa_addresses(mhp)
781: caddr_t *mhp;
782: {
783: struct sockaddr *src, *dst;
784:
785: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
786: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
787: set_port(src, PORT_ISAKMP);
788: set_port(dst, PORT_ISAKMP);
789:
790: #ifdef ENABLE_NATT
791: if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
792: /* NAT-T is enabled for this SADB entry; copy
793: * the ports from NAT-T extensions */
794: if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
795: set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
796: if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
797: set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
798: }
799: #endif
800: }
801:
802: int
803: pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
804: e_type, e_keylen, a_type, a_keylen, flags)
805: u_int proto_id;
806: u_int t_id;
807: u_int hashtype;
808: u_int *e_type;
809: u_int *e_keylen;
810: u_int *a_type;
811: u_int *a_keylen;
812: u_int *flags;
813: {
814: *flags = 0;
815: switch (proto_id) {
816: case IPSECDOI_PROTO_IPSEC_ESP:
817: if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
818: goto bad;
819: if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
820: goto bad;
821: *e_keylen >>= 3;
822:
823: if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
824: goto bad;
825: if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
826: goto bad;
827: *a_keylen >>= 3;
828:
829: if (*e_type == SADB_EALG_NONE) {
830: plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
831: goto bad;
832: }
833: break;
834:
835: case IPSECDOI_PROTO_IPSEC_AH:
836: if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
837: goto bad;
838: if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
839: goto bad;
840: *a_keylen >>= 3;
841:
842: if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
843: && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
844: /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
845: *a_type = SADB_X_AALG_MD5;
846: *flags |= SADB_X_EXT_OLD;
847: }
848: *e_type = SADB_EALG_NONE;
849: *e_keylen = 0;
850: if (*a_type == SADB_AALG_NONE) {
851: plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
852: goto bad;
853: }
854: break;
855:
856: case IPSECDOI_PROTO_IPCOMP:
857: if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
858: goto bad;
859: *e_keylen = 0;
860:
861: *flags = SADB_X_EXT_RAWCPI;
862:
863: *a_type = SADB_AALG_NONE;
864: *a_keylen = 0;
865: if (*e_type == SADB_X_CALG_NONE) {
866: plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
867: goto bad;
868: }
869: break;
870:
871: default:
872: plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
873: goto bad;
874: }
875:
876: return 0;
877:
878: bad:
879: errno = EINVAL;
880: return -1;
881: }
882:
883: /*%%%*/
884: /* send getspi message per ipsec protocol per remote address */
885: /*
886: * the local address and remote address in ph1handle are dealed
887: * with destination address and source address respectively.
888: * Because SPI is decided by responder.
889: */
890: int
891: pk_sendgetspi(iph2)
892: struct ph2handle *iph2;
893: {
894: struct sockaddr *src = NULL, *dst = NULL;
895: u_int satype, mode;
896: struct saprop *pp;
897: struct saproto *pr;
898: u_int32_t minspi, maxspi;
899: u_int8_t natt_type = 0;
900: u_int16_t sport = 0, dport = 0;
901:
902: if (iph2->side == INITIATOR)
903: pp = iph2->proposal;
904: else
905: pp = iph2->approval;
906:
907: if (iph2->sa_src && iph2->sa_dst) {
908: /* MIPv6: Use SA addresses, not IKE ones */
909: src = dupsaddr(iph2->sa_src);
910: dst = dupsaddr(iph2->sa_dst);
911: } else {
912: /* Common case: SA addresses and IKE ones are the same */
913: src = dupsaddr(iph2->src);
914: dst = dupsaddr(iph2->dst);
915: }
916:
917: if (src == NULL || dst == NULL) {
918: racoon_free(src);
919: racoon_free(dst);
920: return -1;
921: }
922:
923: for (pr = pp->head; pr != NULL; pr = pr->next) {
924:
925: /* validity check */
926: satype = ipsecdoi2pfkey_proto(pr->proto_id);
927: if (satype == ~0) {
928: plog(LLV_ERROR, LOCATION, NULL,
929: "invalid proto_id %d\n", pr->proto_id);
930: racoon_free(src);
931: racoon_free(dst);
932: return -1;
933: }
934: /* this works around a bug in Linux kernel where it allocates 4 byte
935: spi's for IPCOMP */
936: else if (satype == SADB_X_SATYPE_IPCOMP) {
937: minspi = 0x100;
938: maxspi = 0xffff;
939: }
940: else {
941: minspi = 0;
942: maxspi = 0;
943: }
944: mode = ipsecdoi2pfkey_mode(pr->encmode);
945: if (mode == ~0) {
946: plog(LLV_ERROR, LOCATION, NULL,
947: "invalid encmode %d\n", pr->encmode);
948: racoon_free(src);
949: racoon_free(dst);
950: return -1;
951: }
952:
953: #ifdef ENABLE_NATT
954: if (pr->udp_encap) {
955: natt_type = iph2->ph1->natt_options->encaps_type;
956: sport=extract_port(src);
957: dport=extract_port(dst);
958: }
959: #endif
960:
961: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
962: if (pfkey_send_getspi_nat(
963: lcconf->sock_pfkey,
964: satype,
965: mode,
966: dst, /* src of SA */
967: src, /* dst of SA */
968: natt_type,
969: dport,
970: sport,
971: minspi, maxspi,
972: pr->reqid_in, iph2->seq) < 0) {
973: plog(LLV_ERROR, LOCATION, NULL,
974: "ipseclib failed send getspi (%s)\n",
975: ipsec_strerror());
976: racoon_free(src);
977: racoon_free(dst);
978: return -1;
979: }
980: plog(LLV_DEBUG, LOCATION, NULL,
981: "pfkey GETSPI sent: %s\n",
982: sadbsecas2str(dst, src, satype, 0, mode));
983: }
984:
985: racoon_free(src);
986: racoon_free(dst);
987: return 0;
988: }
989:
990: /*
991: * receive GETSPI from kernel.
992: */
993: static int
994: pk_recvgetspi(mhp)
995: caddr_t *mhp;
996: {
997: struct sadb_msg *msg;
998: struct sadb_sa *sa;
999: struct ph2handle *iph2;
1000: struct sockaddr *src, *dst;
1001: int proto_id;
1002: int allspiok, notfound;
1003: struct saprop *pp;
1004: struct saproto *pr;
1005:
1006: /* validity check */
1007: if (mhp[SADB_EXT_SA] == NULL
1008: || mhp[SADB_EXT_ADDRESS_DST] == NULL
1009: || mhp[SADB_EXT_ADDRESS_SRC] == NULL) {
1010: plog(LLV_ERROR, LOCATION, NULL,
1011: "inappropriate sadb getspi message passed.\n");
1012: return -1;
1013: }
1014: msg = (struct sadb_msg *)mhp[0];
1015: sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1016: pk_fixup_sa_addresses(mhp);
1017: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
1018: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1019:
1020: /* the message has to be processed or not ? */
1021: if (msg->sadb_msg_pid != getpid()) {
1022: plog(LLV_DEBUG, LOCATION, NULL,
1023: "%s message is not interesting "
1024: "because pid %d is not mine.\n",
1025: s_pfkey_type(msg->sadb_msg_type),
1026: msg->sadb_msg_pid);
1027: return -1;
1028: }
1029:
1030: iph2 = getph2byseq(msg->sadb_msg_seq);
1031: if (iph2 == NULL) {
1032: plog(LLV_DEBUG, LOCATION, NULL,
1033: "seq %d of %s message not interesting.\n",
1034: msg->sadb_msg_seq,
1035: s_pfkey_type(msg->sadb_msg_type));
1036: return -1;
1037: }
1038:
1039: if (iph2->status != PHASE2ST_GETSPISENT) {
1040: plog(LLV_ERROR, LOCATION, NULL,
1041: "status mismatch (db:%d msg:%d)\n",
1042: iph2->status, PHASE2ST_GETSPISENT);
1043: return -1;
1044: }
1045:
1046: /* set SPI, and check to get all spi whether or not */
1047: allspiok = 1;
1048: notfound = 1;
1049: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1050: pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
1051:
1052: for (pr = pp->head; pr != NULL; pr = pr->next) {
1053: if (pr->proto_id == proto_id && pr->spi == 0) {
1054: pr->spi = sa->sadb_sa_spi;
1055: notfound = 0;
1056: plog(LLV_DEBUG, LOCATION, NULL,
1057: "pfkey GETSPI succeeded: %s\n",
1058: sadbsecas2str(dst, src,
1059: msg->sadb_msg_satype,
1060: sa->sadb_sa_spi,
1061: ipsecdoi2pfkey_mode(pr->encmode)));
1062: }
1063: if (pr->spi == 0)
1064: allspiok = 0; /* not get all spi */
1065: }
1066:
1067: if (notfound) {
1068: plog(LLV_ERROR, LOCATION, NULL,
1069: "get spi for unknown address %s\n",
1070: saddrwop2str(dst));
1071: return -1;
1072: }
1073:
1074: if (allspiok) {
1075: /* update status */
1076: iph2->status = PHASE2ST_GETSPIDONE;
1077: if (isakmp_post_getspi(iph2) < 0) {
1078: plog(LLV_ERROR, LOCATION, NULL,
1079: "failed to start post getspi.\n");
1080: remph2(iph2);
1081: delph2(iph2);
1082: iph2 = NULL;
1083: return -1;
1084: }
1085: }
1086:
1087: return 0;
1088: }
1089:
1090: /*
1091: * set inbound SA
1092: */
1093: int
1094: pk_sendupdate(iph2)
1095: struct ph2handle *iph2;
1096: {
1097: struct saproto *pr;
1098: struct pfkey_send_sa_args sa_args;
1099:
1100: /* sanity check */
1101: if (iph2->approval == NULL) {
1102: plog(LLV_ERROR, LOCATION, NULL,
1103: "no approvaled SAs found.\n");
1104: return -1;
1105: }
1106:
1107: /* fill in some needed for pfkey_send_update2 */
1108: memset (&sa_args, 0, sizeof (sa_args));
1109: sa_args.so = lcconf->sock_pfkey;
1110: if (iph2->lifetime_secs)
1111: sa_args.l_addtime = iph2->lifetime_secs;
1112: else
1113: sa_args.l_addtime = iph2->approval->lifetime;
1114: sa_args.seq = iph2->seq;
1115: sa_args.wsize = 4;
1116:
1117: if (iph2->sa_src && iph2->sa_dst) {
1118: /* MIPv6: Use SA addresses, not IKE ones */
1119: sa_args.dst = dupsaddr(iph2->sa_src);
1120: sa_args.src = dupsaddr(iph2->sa_dst);
1121: } else {
1122: /* Common case: SA addresses and IKE ones are the same */
1123: sa_args.dst = dupsaddr(iph2->src);
1124: sa_args.src = dupsaddr(iph2->dst);
1125: }
1126:
1127: if (sa_args.src == NULL || sa_args.dst == NULL) {
1128: racoon_free(sa_args.src);
1129: racoon_free(sa_args.dst);
1130: return -1;
1131: }
1132:
1133: for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1134: /* validity check */
1135: sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1136: if (sa_args.satype == ~0) {
1137: plog(LLV_ERROR, LOCATION, NULL,
1138: "invalid proto_id %d\n", pr->proto_id);
1139: racoon_free(sa_args.src);
1140: racoon_free(sa_args.dst);
1141: return -1;
1142: }
1143: else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1144: /* IPCOMP has no replay window */
1145: sa_args.wsize = 0;
1146: }
1147: #ifdef ENABLE_SAMODE_UNSPECIFIED
1148: sa_args.mode = IPSEC_MODE_ANY;
1149: #else
1150: sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1151: if (sa_args.mode == ~0) {
1152: plog(LLV_ERROR, LOCATION, NULL,
1153: "invalid encmode %d\n", pr->encmode);
1154: racoon_free(sa_args.src);
1155: racoon_free(sa_args.dst);
1156: return -1;
1157: }
1158: #endif
1159: /* set algorithm type and key length */
1160: sa_args.e_keylen = pr->head->encklen;
1161: if (pfkey_convertfromipsecdoi(
1162: pr->proto_id,
1163: pr->head->trns_id,
1164: pr->head->authtype,
1165: &sa_args.e_type, &sa_args.e_keylen,
1166: &sa_args.a_type, &sa_args.a_keylen,
1167: &sa_args.flags) < 0){
1168: racoon_free(sa_args.src);
1169: racoon_free(sa_args.dst);
1170: return -1;
1171: }
1172:
1173: #if 0
1174: sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1175: #else
1176: sa_args.l_bytes = 0;
1177: #endif
1178:
1179: #ifdef HAVE_SECCTX
1180: if (*iph2->approval->sctx.ctx_str) {
1181: sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1182: sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1183: sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1184: sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1185: }
1186: #endif /* HAVE_SECCTX */
1187:
1188: #ifdef ENABLE_NATT
1189: if (pr->udp_encap) {
1190: sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
1191: sa_args.l_natt_sport = extract_port(iph2->ph1->remote);
1192: sa_args.l_natt_dport = extract_port(iph2->ph1->local);
1193: sa_args.l_natt_oa = iph2->natoa_src;
1194: #ifdef SADB_X_EXT_NAT_T_FRAG
1195: sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1196: #endif
1197: }
1198: #endif
1199:
1200: /* more info to fill in */
1201: sa_args.spi = pr->spi;
1202: sa_args.reqid = pr->reqid_in;
1203: sa_args.keymat = pr->keymat->v;
1204:
1205: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n");
1206: if (pfkey_send_update2(&sa_args) < 0) {
1207: plog(LLV_ERROR, LOCATION, NULL,
1208: "libipsec failed send update (%s)\n",
1209: ipsec_strerror());
1210: racoon_free(sa_args.src);
1211: racoon_free(sa_args.dst);
1212: return -1;
1213: }
1214:
1215: if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1216: continue;
1217:
1218: /*
1219: * It maybe good idea to call backupsa_to_file() after
1220: * racoon will receive the sadb_update messages.
1221: * But it is impossible because there is not key in the
1222: * information from the kernel.
1223: */
1224:
1225: /* change some things before backing up */
1226: sa_args.wsize = 4;
1227: sa_args.l_bytes = iph2->approval->lifebyte * 1024;
1228:
1229: if (backupsa_to_file(&sa_args) < 0) {
1230: plog(LLV_ERROR, LOCATION, NULL,
1231: "backuped SA failed: %s\n",
1232: sadbsecas2str(sa_args.src, sa_args.dst,
1233: sa_args.satype, sa_args.spi, sa_args.mode));
1234: }
1235: plog(LLV_DEBUG, LOCATION, NULL,
1236: "backuped SA: %s\n",
1237: sadbsecas2str(sa_args.src, sa_args.dst,
1238: sa_args.satype, sa_args.spi, sa_args.mode));
1239: }
1240:
1241: racoon_free(sa_args.src);
1242: racoon_free(sa_args.dst);
1243: return 0;
1244: }
1245:
1246: static int
1247: pk_recvupdate(mhp)
1248: caddr_t *mhp;
1249: {
1250: struct sadb_msg *msg;
1251: struct sadb_sa *sa;
1252: struct sockaddr *src, *dst;
1253: struct ph2handle *iph2;
1254: u_int proto_id, encmode, sa_mode;
1255: int incomplete = 0;
1256: struct saproto *pr;
1257:
1258: /* ignore this message because of local test mode. */
1259: if (f_local)
1260: return 0;
1261:
1262: /* sanity check */
1263: if (mhp[0] == NULL
1264: || mhp[SADB_EXT_SA] == NULL
1265: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1266: || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1267: plog(LLV_ERROR, LOCATION, NULL,
1268: "inappropriate sadb update message passed.\n");
1269: return -1;
1270: }
1271: msg = (struct sadb_msg *)mhp[0];
1272: pk_fixup_sa_addresses(mhp);
1273: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1274: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1275: sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1276:
1277: sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1278: ? IPSEC_MODE_ANY
1279: : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1280:
1281: /* the message has to be processed or not ? */
1282: if (msg->sadb_msg_pid != getpid()) {
1283: plog(LLV_DEBUG, LOCATION, NULL,
1284: "%s message is not interesting "
1285: "because pid %d is not mine.\n",
1286: s_pfkey_type(msg->sadb_msg_type),
1287: msg->sadb_msg_pid);
1288: return -1;
1289: }
1290:
1291: iph2 = getph2byseq(msg->sadb_msg_seq);
1292: if (iph2 == NULL) {
1293: plog(LLV_DEBUG, LOCATION, NULL,
1294: "seq %d of %s message not interesting.\n",
1295: msg->sadb_msg_seq,
1296: s_pfkey_type(msg->sadb_msg_type));
1297: return -1;
1298: }
1299:
1300: if (iph2->status != PHASE2ST_ADDSA) {
1301: plog(LLV_ERROR, LOCATION, NULL,
1302: "status mismatch (db:%d msg:%d)\n",
1303: iph2->status, PHASE2ST_ADDSA);
1304: return -1;
1305: }
1306:
1307: /* check to complete all keys ? */
1308: for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1309: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1310: if (proto_id == ~0) {
1311: plog(LLV_ERROR, LOCATION, NULL,
1312: "invalid proto_id %d\n", msg->sadb_msg_satype);
1313: return -1;
1314: }
1315: encmode = pfkey2ipsecdoi_mode(sa_mode);
1316: if (encmode == ~0) {
1317: plog(LLV_ERROR, LOCATION, NULL,
1318: "invalid encmode %d\n", sa_mode);
1319: return -1;
1320: }
1321:
1322: if (pr->proto_id == proto_id
1323: && pr->spi == sa->sadb_sa_spi) {
1324: pr->ok = 1;
1325: plog(LLV_DEBUG, LOCATION, NULL,
1326: "pfkey UPDATE succeeded: %s\n",
1327: sadbsecas2str(dst, src,
1328: msg->sadb_msg_satype,
1329: sa->sadb_sa_spi,
1330: sa_mode));
1331:
1332: plog(LLV_INFO, LOCATION, NULL,
1333: "IPsec-SA established: %s\n",
1334: sadbsecas2str(dst, src,
1335: msg->sadb_msg_satype, sa->sadb_sa_spi,
1336: sa_mode));
1337: }
1338:
1339: if (pr->ok == 0)
1340: incomplete = 1;
1341: }
1342:
1343: if (incomplete)
1344: return 0;
1345:
1346: /* turn off the timer for calling pfkey_timeover() */
1347: sched_cancel(&iph2->sce);
1348:
1349: /* update status */
1350: iph2->status = PHASE2ST_ESTABLISHED;
1351: evt_phase2(iph2, EVT_PHASE2_UP, NULL);
1352:
1353: #ifdef ENABLE_STATS
1354: gettimeofday(&iph2->end, NULL);
1355: syslog(LOG_NOTICE, "%s(%s): %8.6f",
1356: "phase2", "quick", timedelta(&iph2->start, &iph2->end));
1357: #endif
1358:
1359: /* turn off schedule */
1360: sched_cancel(&iph2->scr);
1361:
1362: /*
1363: * since we are going to reuse the phase2 handler, we need to
1364: * remain it and refresh all the references between ph1 and ph2 to use.
1365: */
1366: sched_schedule(&iph2->sce, iph2->approval->lifetime,
1367: isakmp_ph2expire_stub);
1368:
1369: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1370: return 0;
1371: }
1372:
1373: /*
1374: * set outbound SA
1375: */
1376: int
1377: pk_sendadd(iph2)
1378: struct ph2handle *iph2;
1379: {
1380: struct saproto *pr;
1381: struct pfkey_send_sa_args sa_args;
1382:
1383: /* sanity check */
1384: if (iph2->approval == NULL) {
1385: plog(LLV_ERROR, LOCATION, NULL,
1386: "no approvaled SAs found.\n");
1387: return -1;
1388: }
1389:
1390: /* fill in some needed for pfkey_send_update2 */
1391: memset (&sa_args, 0, sizeof (sa_args));
1392: sa_args.so = lcconf->sock_pfkey;
1393: if (iph2->lifetime_secs)
1394: sa_args.l_addtime = iph2->lifetime_secs;
1395: else
1396: sa_args.l_addtime = iph2->approval->lifetime;
1397: sa_args.seq = iph2->seq;
1398: sa_args.wsize = 4;
1399:
1400: if (iph2->sa_src && iph2->sa_dst) {
1401: /* MIPv6: Use SA addresses, not IKE ones */
1402: sa_args.src = dupsaddr(iph2->sa_src);
1403: sa_args.dst = dupsaddr(iph2->sa_dst);
1404: } else {
1405: /* Common case: SA addresses and IKE ones are the same */
1406: sa_args.src = dupsaddr(iph2->src);
1407: sa_args.dst = dupsaddr(iph2->dst);
1408: }
1409:
1410: if (sa_args.src == NULL || sa_args.dst == NULL) {
1411: racoon_free(sa_args.src);
1412: racoon_free(sa_args.dst);
1413: return -1;
1414: }
1415:
1416: for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1417: /* validity check */
1418: sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1419: if (sa_args.satype == ~0) {
1420: plog(LLV_ERROR, LOCATION, NULL,
1421: "invalid proto_id %d\n", pr->proto_id);
1422: racoon_free(sa_args.src);
1423: racoon_free(sa_args.dst);
1424: return -1;
1425: }
1426: else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1427: /* no replay window for IPCOMP */
1428: sa_args.wsize = 0;
1429: }
1430: #ifdef ENABLE_SAMODE_UNSPECIFIED
1431: sa_args.mode = IPSEC_MODE_ANY;
1432: #else
1433: sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1434: if (sa_args.mode == ~0) {
1435: plog(LLV_ERROR, LOCATION, NULL,
1436: "invalid encmode %d\n", pr->encmode);
1437: racoon_free(sa_args.src);
1438: racoon_free(sa_args.dst);
1439: return -1;
1440: }
1441: #endif
1442:
1443: /* set algorithm type and key length */
1444: sa_args.e_keylen = pr->head->encklen;
1445: if (pfkey_convertfromipsecdoi(
1446: pr->proto_id,
1447: pr->head->trns_id,
1448: pr->head->authtype,
1449: &sa_args.e_type, &sa_args.e_keylen,
1450: &sa_args.a_type, &sa_args.a_keylen,
1451: &sa_args.flags) < 0){
1452: racoon_free(sa_args.src);
1453: racoon_free(sa_args.dst);
1454: return -1;
1455: }
1456:
1457: #if 0
1458: sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1459: #else
1460: sa_args.l_bytes = 0;
1461: #endif
1462:
1463: #ifdef HAVE_SECCTX
1464: if (*iph2->approval->sctx.ctx_str) {
1465: sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1466: sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1467: sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1468: sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1469: }
1470: #endif /* HAVE_SECCTX */
1471:
1472: #ifdef ENABLE_NATT
1473: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
1474: "(NAT flavor)\n");
1475:
1476: if (pr->udp_encap) {
1477: sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
1478: sa_args.l_natt_sport = extract_port(iph2->ph1->local);
1479: sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
1480: sa_args.l_natt_oa = iph2->natoa_dst;
1481: #ifdef SADB_X_EXT_NAT_T_FRAG
1482: sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1483: #endif
1484: }
1485: #endif
1486: /* more info to fill in */
1487: sa_args.spi = pr->spi_p;
1488: sa_args.reqid = pr->reqid_out;
1489: sa_args.keymat = pr->keymat_p->v;
1490:
1491: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
1492: if (pfkey_send_add2(&sa_args) < 0) {
1493: plog(LLV_ERROR, LOCATION, NULL,
1494: "libipsec failed send add (%s)\n",
1495: ipsec_strerror());
1496: racoon_free(sa_args.src);
1497: racoon_free(sa_args.dst);
1498: return -1;
1499: }
1500:
1501: if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1502: continue;
1503:
1504: /*
1505: * It maybe good idea to call backupsa_to_file() after
1506: * racoon will receive the sadb_update messages.
1507: * But it is impossible because there is not key in the
1508: * information from the kernel.
1509: */
1510: if (backupsa_to_file(&sa_args) < 0) {
1511: plog(LLV_ERROR, LOCATION, NULL,
1512: "backuped SA failed: %s\n",
1513: sadbsecas2str(sa_args.src, sa_args.dst,
1514: sa_args.satype, sa_args.spi, sa_args.mode));
1515: }
1516: plog(LLV_DEBUG, LOCATION, NULL,
1517: "backuped SA: %s\n",
1518: sadbsecas2str(sa_args.src, sa_args.dst,
1519: sa_args.satype, sa_args.spi, sa_args.mode));
1520: }
1521: racoon_free(sa_args.src);
1522: racoon_free(sa_args.dst);
1523: return 0;
1524: }
1525:
1526: static int
1527: pk_recvadd(mhp)
1528: caddr_t *mhp;
1529: {
1530: struct sadb_msg *msg;
1531: struct sadb_sa *sa;
1532: struct sockaddr *src, *dst;
1533: struct ph2handle *iph2;
1534: u_int sa_mode;
1535:
1536: /* ignore this message because of local test mode. */
1537: if (f_local)
1538: return 0;
1539:
1540: /* sanity check */
1541: if (mhp[0] == NULL
1542: || mhp[SADB_EXT_SA] == NULL
1543: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1544: || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1545: plog(LLV_ERROR, LOCATION, NULL,
1546: "inappropriate sadb add message passed.\n");
1547: return -1;
1548: }
1549: msg = (struct sadb_msg *)mhp[0];
1550: pk_fixup_sa_addresses(mhp);
1551: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1552: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1553: sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1554:
1555: sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1556: ? IPSEC_MODE_ANY
1557: : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1558:
1559: /* the message has to be processed or not ? */
1560: if (msg->sadb_msg_pid != getpid()) {
1561: plog(LLV_DEBUG, LOCATION, NULL,
1562: "%s message is not interesting "
1563: "because pid %d is not mine.\n",
1564: s_pfkey_type(msg->sadb_msg_type),
1565: msg->sadb_msg_pid);
1566: return -1;
1567: }
1568:
1569: iph2 = getph2byseq(msg->sadb_msg_seq);
1570: if (iph2 == NULL) {
1571: plog(LLV_DEBUG, LOCATION, NULL,
1572: "seq %d of %s message not interesting.\n",
1573: msg->sadb_msg_seq,
1574: s_pfkey_type(msg->sadb_msg_type));
1575: return -1;
1576: }
1577:
1578: /*
1579: * NOTE don't update any status of phase2 handle
1580: * because they must be updated by SADB_UPDATE message
1581: */
1582:
1583: plog(LLV_INFO, LOCATION, NULL,
1584: "IPsec-SA established: %s\n",
1585: sadbsecas2str(src, dst,
1586: msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1587:
1588: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1589: return 0;
1590: }
1591:
1592: static int
1593: pk_recvexpire(mhp)
1594: caddr_t *mhp;
1595: {
1596: struct sadb_msg *msg;
1597: struct sadb_sa *sa;
1598: struct sockaddr *src, *dst;
1599: struct ph2handle *iph2;
1600: u_int proto_id, sa_mode;
1601:
1602: /* sanity check */
1603: if (mhp[0] == NULL
1604: || mhp[SADB_EXT_SA] == NULL
1605: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1606: || mhp[SADB_EXT_ADDRESS_DST] == NULL
1607: || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1608: && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1609: plog(LLV_ERROR, LOCATION, NULL,
1610: "inappropriate sadb expire message passed.\n");
1611: return -1;
1612: }
1613: msg = (struct sadb_msg *)mhp[0];
1614: sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1615: pk_fixup_sa_addresses(mhp);
1616: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1617: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1618:
1619: sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1620: ? IPSEC_MODE_ANY
1621: : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1622:
1623: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1624: if (proto_id == ~0) {
1625: plog(LLV_ERROR, LOCATION, NULL,
1626: "invalid proto_id %d\n", msg->sadb_msg_satype);
1627: return -1;
1628: }
1629:
1630: plog(LLV_INFO, LOCATION, NULL,
1631: "IPsec-SA expired: %s\n",
1632: sadbsecas2str(src, dst,
1633: msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1634:
1635: iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1636: if (iph2 == NULL) {
1637: /*
1638: * Ignore it because two expire messages are come up.
1639: * phase2 handler has been deleted already when 2nd message
1640: * is received.
1641: */
1642: plog(LLV_DEBUG, LOCATION, NULL,
1643: "no such a SA found: %s\n",
1644: sadbsecas2str(src, dst,
1645: msg->sadb_msg_satype, sa->sadb_sa_spi,
1646: sa_mode));
1647: return 0;
1648: }
1649:
1650: /* resent expiry message? */
1651: if (iph2->status > PHASE2ST_ESTABLISHED)
1652: return 0;
1653:
1654: /* still negotiating? */
1655: if (iph2->status < PHASE2ST_ESTABLISHED) {
1656: /* not a hard timeout? */
1657: if (mhp[SADB_EXT_LIFETIME_HARD] == NULL)
1658: return 0;
1659:
1660: /*
1661: * We were negotiating for that SA (w/o much success
1662: * from current status) and kernel has decided our time
1663: * is over trying (xfrm_larval_drop controls that and
1664: * is enabled by default on Linux >= 2.6.28 kernels).
1665: */
1666: plog(LLV_WARNING, LOCATION, NULL,
1667: "PF_KEY EXPIRE message received from kernel for SA"
1668: " being negotiated. Stopping negotiation.\n");
1669: }
1670:
1671: /* turn off the timer for calling isakmp_ph2expire() */
1672: sched_cancel(&iph2->sce);
1673:
1674: if (iph2->status == PHASE2ST_ESTABLISHED &&
1675: iph2->side == INITIATOR) {
1676: struct ph1handle *iph1hint;
1677: /*
1678: * Active phase 2 expired and we were initiator.
1679: * Begin new phase 2 exchange, so we can keep on sending
1680: * traffic.
1681: */
1682:
1683: /* update status for re-use */
1684: iph1hint = iph2->ph1;
1685: initph2(iph2);
1686: iph2->status = PHASE2ST_STATUS2;
1687:
1688: /* start quick exchange */
1689: if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
1690: plog(LLV_ERROR, LOCATION, iph2->dst,
1691: "failed to begin ipsec sa "
1692: "re-negotication.\n");
1693: remph2(iph2);
1694: delph2(iph2);
1695: return -1;
1696: }
1697:
1698: return 0;
1699: }
1700:
1701: /*
1702: * We are responder or the phase 2 was not established.
1703: * Just remove the ph2handle to reflect SADB.
1704: */
1705: iph2->status = PHASE2ST_EXPIRED;
1706: remph2(iph2);
1707: delph2(iph2);
1708:
1709: return 0;
1710: }
1711:
1712: static int
1713: pk_recvacquire(mhp)
1714: caddr_t *mhp;
1715: {
1716: struct sadb_msg *msg;
1717: struct sadb_x_policy *xpl;
1718: struct secpolicy *sp_out = NULL, *sp_in = NULL;
1719: struct ph2handle *iph2;
1720: struct sockaddr *src, *dst; /* IKE addresses (for exchanges) */
1721: struct sockaddr *sp_src, *sp_dst; /* SP addresses (selectors). */
1722: struct sockaddr *sa_src = NULL, *sa_dst = NULL ; /* SA addresses */
1723: #ifdef HAVE_SECCTX
1724: struct sadb_x_sec_ctx *m_sec_ctx;
1725: #endif /* HAVE_SECCTX */
1726: struct policyindex spidx;
1727:
1728: /* ignore this message because of local test mode. */
1729: if (f_local)
1730: return 0;
1731:
1732: /* sanity check */
1733: if (mhp[0] == NULL
1734: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1735: || mhp[SADB_EXT_ADDRESS_DST] == NULL
1736: || mhp[SADB_X_EXT_POLICY] == NULL) {
1737: plog(LLV_ERROR, LOCATION, NULL,
1738: "inappropriate sadb acquire message passed.\n");
1739: return -1;
1740: }
1741: msg = (struct sadb_msg *)mhp[0];
1742: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1743: /* acquire does not have nat-t ports; so do not bother setting
1744: * the default port 500; just use the port zero for wildcard
1745: * matching the get a valid natted destination */
1746: sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1747: sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1748:
1749: #ifdef HAVE_SECCTX
1750: m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
1751:
1752: if (m_sec_ctx != NULL) {
1753: plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
1754: m_sec_ctx->sadb_x_ctx_doi);
1755: plog(LLV_INFO, LOCATION, NULL,
1756: "security context algorithm: %u\n",
1757: m_sec_ctx->sadb_x_ctx_alg);
1758: plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
1759: m_sec_ctx->sadb_x_ctx_len);
1760: plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
1761: ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
1762: }
1763: #endif /* HAVE_SECCTX */
1764:
1765: /* ignore if type is not IPSEC_POLICY_IPSEC */
1766: if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1767: plog(LLV_DEBUG, LOCATION, NULL,
1768: "ignore ACQUIRE message. type is not IPsec.\n");
1769: return 0;
1770: }
1771:
1772: /* ignore it if src or dst are multicast addresses. */
1773: if ((sp_dst->sa_family == AF_INET
1774: && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_dst)->sin_addr.s_addr)))
1775: #ifdef INET6
1776: || (sp_dst->sa_family == AF_INET6
1777: && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_dst)->sin6_addr))
1778: #endif
1779: ) {
1780: plog(LLV_DEBUG, LOCATION, NULL,
1781: "ignore due to multicast destination address: %s.\n",
1782: saddrwop2str(sp_dst));
1783: return 0;
1784: }
1785:
1786: if ((sp_src->sa_family == AF_INET
1787: && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_src)->sin_addr.s_addr)))
1788: #ifdef INET6
1789: || (sp_src->sa_family == AF_INET6
1790: && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_src)->sin6_addr))
1791: #endif
1792: ) {
1793: plog(LLV_DEBUG, LOCATION, NULL,
1794: "ignore due to multicast source address: %s.\n",
1795: saddrwop2str(sp_src));
1796: return 0;
1797: }
1798:
1799: /* search for proper policyindex */
1800: sp_out = getspbyspid(xpl->sadb_x_policy_id);
1801: if (sp_out == NULL) {
1802: plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1803: xpl->sadb_x_policy_id);
1804: return -1;
1805: }
1806: plog(LLV_DEBUG, LOCATION, NULL,
1807: "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1808:
1809: /* Before going further, let first get the source and destination
1810: * address that would be used for IKE negotiation. The logic is:
1811: * - if SP from SPD image contains local and remote hints, we
1812: * use them (provided by MIGRATE).
1813: * - otherwise, we use the ones from the ipsecrequest, which means:
1814: * - the addresses from the request for transport mode
1815: * - the endpoints addresses for tunnel mode
1816: *
1817: * Note that:
1818: * 1) racoon does not support negotiation of bundles which
1819: * simplifies the lookup for the addresses in the ipsecrequest
1820: * list, as we expect only one.
1821: * 2) We do source and destination parts all together and do not
1822: * accept semi-defined information. This is just a decision,
1823: * there might be needs.
1824: *
1825: * --arno
1826: */
1827: if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) {
1828: /* For Tunnel mode, SA addresses are the endpoints */
1829: src = (struct sockaddr *) &sp_out->req->saidx.src;
1830: dst = (struct sockaddr *) &sp_out->req->saidx.dst;
1831: } else {
1832: /* Otherwise use requested addresses.
1833: *
1834: * We need to explicitly setup sa_src and sa_dst too,
1835: * since the SA ports are different from IKE port. And
1836: * src/dst ports will be overwritten when the matching
1837: * phase1 is found. */
1838: src = sa_src = sp_src;
1839: dst = sa_dst = sp_dst;
1840: }
1841: if (sp_out->local && sp_out->remote) {
1842: /* hints available, let's use them */
1843: sa_src = src;
1844: sa_dst = dst;
1845: src = (struct sockaddr *) sp_out->local;
1846: dst = (struct sockaddr *) sp_out->remote;
1847: }
1848:
1849: /*
1850: * If there is a phase 2 handler against the policy identifier in
1851: * the acquire message, and if
1852: * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1853: * should ignore such a acquire message because the phase 2
1854: * is just negotiating.
1855: * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1856: * has to prcesss such a acquire message because racoon may
1857: * lost the expire message.
1858: */
1859: iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id);
1860: if (iph2 != NULL) {
1861: if (iph2->status < PHASE2ST_ESTABLISHED) {
1862: plog(LLV_DEBUG, LOCATION, NULL,
1863: "ignore the acquire because ph2 found\n");
1864: return -1;
1865: }
1866: if (iph2->status == PHASE2ST_EXPIRED)
1867: iph2 = NULL;
1868: /*FALLTHROUGH*/
1869: }
1870:
1871: /* Check we are listening on source address. If not, ignore. */
1872: if (myaddr_getsport(src) == -1) {
1873: plog(LLV_DEBUG, LOCATION, NULL,
1874: "Not listening on source address %s. Ignoring ACQUIRE.\n",
1875: saddrwop2str(src));
1876: return 0;
1877: }
1878:
1879: /* get inbound policy */
1880: {
1881:
1882: memset(&spidx, 0, sizeof(spidx));
1883: spidx.dir = IPSEC_DIR_INBOUND;
1884: memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1885: memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1886: spidx.prefs = sp_out->spidx.prefd;
1887: spidx.prefd = sp_out->spidx.prefs;
1888: spidx.ul_proto = sp_out->spidx.ul_proto;
1889:
1890: #ifdef HAVE_SECCTX
1891: if (m_sec_ctx) {
1892: spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
1893: spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
1894: spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
1895: memcpy(spidx.sec_ctx.ctx_str,
1896: ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
1897: spidx.sec_ctx.ctx_strlen);
1898: }
1899: #endif /* HAVE_SECCTX */
1900:
1901: sp_in = getsp(&spidx);
1902: if (sp_in) {
1903: plog(LLV_DEBUG, LOCATION, NULL,
1904: "suitable inbound SP found: %s.\n",
1905: spidx2str(&sp_in->spidx));
1906: } else {
1907: plog(LLV_NOTIFY, LOCATION, NULL,
1908: "no in-bound policy found: %s\n",
1909: spidx2str(&spidx));
1910: }
1911: }
1912:
1913: /* allocate a phase 2 */
1914: iph2 = newph2();
1915: if (iph2 == NULL) {
1916: plog(LLV_ERROR, LOCATION, NULL,
1917: "failed to allocate phase2 entry.\n");
1918: return -1;
1919: }
1920: iph2->side = INITIATOR;
1921: iph2->spid = xpl->sadb_x_policy_id;
1922: iph2->satype = msg->sadb_msg_satype;
1923: iph2->seq = msg->sadb_msg_seq;
1924: iph2->status = PHASE2ST_STATUS2;
1925:
1926: /* set address used by IKE for the negotiation (might differ from
1927: * SA address, i.e. might not be tunnel endpoints or addresses
1928: * of transport mode SA) */
1929: iph2->dst = dupsaddr(dst);
1930: if (iph2->dst == NULL) {
1931: delph2(iph2);
1932: return -1;
1933: }
1934: iph2->src = dupsaddr(src);
1935: if (iph2->src == NULL) {
1936: delph2(iph2);
1937: return -1;
1938: }
1939:
1940: /* If sa_src and sa_dst have been set, this mean we have to
1941: * set iph2->sa_src and iph2->sa_dst to provide the addresses
1942: * of the SA because iph2->src and iph2->dst are only the ones
1943: * used for the IKE exchanges. Those that need these addresses
1944: * are for instance pk_sendupdate() or pk_sendgetspi() */
1945: if (sa_src) {
1946: iph2->sa_src = dupsaddr(sa_src);
1947: iph2->sa_dst = dupsaddr(sa_dst);
1948: }
1949:
1950: if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
1951: delph2(iph2);
1952: return -1;
1953: }
1954:
1955: #ifdef HAVE_SECCTX
1956: if (m_sec_ctx) {
1957: set_secctx_in_proposal(iph2, spidx);
1958: }
1959: #endif /* HAVE_SECCTX */
1960:
1961: insph2(iph2);
1962:
1963: /* start isakmp initiation by using ident exchange */
1964: /* XXX should be looped if there are multiple phase 2 handler. */
1965: if (isakmp_post_acquire(iph2, NULL, TRUE) < 0) {
1966: plog(LLV_ERROR, LOCATION, NULL,
1967: "failed to begin ipsec sa negotication.\n");
1968: remph2(iph2);
1969: delph2(iph2);
1970: return -1;
1971: }
1972:
1973: return 0;
1974: }
1975:
1976: static int
1977: pk_recvdelete(mhp)
1978: caddr_t *mhp;
1979: {
1980: struct sadb_msg *msg;
1981: struct sadb_sa *sa;
1982: struct sockaddr *src, *dst;
1983: struct ph2handle *iph2 = NULL;
1984: u_int proto_id;
1985:
1986: /* ignore this message because of local test mode. */
1987: if (f_local)
1988: return 0;
1989:
1990: /* sanity check */
1991: if (mhp[0] == NULL
1992: || mhp[SADB_EXT_SA] == NULL
1993: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1994: || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1995: plog(LLV_ERROR, LOCATION, NULL,
1996: "inappropriate sadb delete message passed.\n");
1997: return -1;
1998: }
1999: msg = (struct sadb_msg *)mhp[0];
2000: sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
2001: pk_fixup_sa_addresses(mhp);
2002: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
2003: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
2004:
2005: /* the message has to be processed or not ? */
2006: if (msg->sadb_msg_pid == getpid()) {
2007: plog(LLV_DEBUG, LOCATION, NULL,
2008: "%s message is not interesting "
2009: "because the message was originated by me.\n",
2010: s_pfkey_type(msg->sadb_msg_type));
2011: return -1;
2012: }
2013:
2014: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
2015: if (proto_id == ~0) {
2016: plog(LLV_ERROR, LOCATION, NULL,
2017: "invalid proto_id %d\n", msg->sadb_msg_satype);
2018: return -1;
2019: }
2020:
2021: iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
2022: if (iph2 == NULL) {
2023: /* ignore */
2024: plog(LLV_ERROR, LOCATION, NULL,
2025: "no iph2 found: %s\n",
2026: sadbsecas2str(src, dst, msg->sadb_msg_satype,
2027: sa->sadb_sa_spi, IPSEC_MODE_ANY));
2028: return 0;
2029: }
2030:
2031: plog(LLV_ERROR, LOCATION, NULL,
2032: "pfkey DELETE received: %s\n",
2033: sadbsecas2str(src, dst,
2034: msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
2035:
2036: /* send delete information */
2037: if (iph2->status == PHASE2ST_ESTABLISHED)
2038: isakmp_info_send_d2(iph2);
2039:
2040: remph2(iph2);
2041: delph2(iph2);
2042:
2043: return 0;
2044: }
2045:
2046: static int
2047: pk_recvflush(mhp)
2048: caddr_t *mhp;
2049: {
2050: /* ignore this message because of local test mode. */
2051: if (f_local)
2052: return 0;
2053:
2054: /* sanity check */
2055: if (mhp[0] == NULL) {
2056: plog(LLV_ERROR, LOCATION, NULL,
2057: "inappropriate sadb flush message passed.\n");
2058: return -1;
2059: }
2060:
2061: flushph2();
2062:
2063: return 0;
2064: }
2065:
2066: static int
2067: getsadbpolicy(policy0, policylen0, type, iph2)
2068: caddr_t *policy0;
2069: int *policylen0, type;
2070: struct ph2handle *iph2;
2071: {
2072: struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2073: struct sockaddr *src = NULL, *dst = NULL;
2074: struct sadb_x_policy *xpl;
2075: struct sadb_x_ipsecrequest *xisr;
2076: struct saproto *pr;
2077: struct saproto **pr_rlist;
2078: int rlist_len = 0;
2079: caddr_t policy, p;
2080: int policylen;
2081: int xisrlen;
2082: u_int satype, mode;
2083: int len = 0;
2084: #ifdef HAVE_SECCTX
2085: int ctxlen = 0;
2086: #endif /* HAVE_SECCTX */
2087:
2088:
2089: /* get policy buffer size */
2090: policylen = sizeof(struct sadb_x_policy);
2091: if (type != SADB_X_SPDDELETE) {
2092: if (iph2->sa_src && iph2->sa_dst) {
2093: src = iph2->sa_src; /* MIPv6: Use SA addresses, */
2094: dst = iph2->sa_dst; /* not IKE ones */
2095: } else {
2096: src = iph2->src; /* Common case: SA addresses */
2097: dst = iph2->dst; /* and IKE ones are the same */
2098: }
2099:
2100: for (pr = iph2->approval->head; pr; pr = pr->next) {
2101: xisrlen = sizeof(*xisr);
2102: if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2103: xisrlen += (sysdep_sa_len(src) +
2104: sysdep_sa_len(dst));
2105: }
2106:
2107: policylen += PFKEY_ALIGN8(xisrlen);
2108: }
2109: }
2110:
2111: #ifdef HAVE_SECCTX
2112: if (*spidx->sec_ctx.ctx_str) {
2113: ctxlen = sizeof(struct sadb_x_sec_ctx)
2114: + PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
2115: policylen += ctxlen;
2116: }
2117: #endif /* HAVE_SECCTX */
2118:
2119: /* make policy structure */
2120: policy = racoon_malloc(policylen);
2121: memset((void*)policy, 0xcd, policylen);
2122: if (!policy) {
2123: plog(LLV_ERROR, LOCATION, NULL,
2124: "buffer allocation failed.\n");
2125: return -1;
2126: }
2127:
2128: xpl = (struct sadb_x_policy *)policy;
2129: xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2130: xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2131: xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2132: xpl->sadb_x_policy_dir = spidx->dir;
2133: xpl->sadb_x_policy_id = 0;
2134: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2135: xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2136: #endif
2137: len++;
2138:
2139: #ifdef HAVE_SECCTX
2140: if (*spidx->sec_ctx.ctx_str) {
2141: struct sadb_x_sec_ctx *p;
2142:
2143: p = (struct sadb_x_sec_ctx *)(xpl + len);
2144: memset(p, 0, ctxlen);
2145: p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
2146: p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2147: p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
2148: p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
2149: p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
2150:
2151: memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
2152: len += ctxlen;
2153: }
2154: #endif /* HAVE_SECCTX */
2155:
2156: /* no need to append policy information any more if type is SPDDELETE */
2157: if (type == SADB_X_SPDDELETE)
2158: goto end;
2159:
2160: xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
2161:
2162: /* The order of things is reversed for use in add policy messages */
2163: for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
2164: pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
2165: if (!pr_rlist) {
2166: plog(LLV_ERROR, LOCATION, NULL,
2167: "buffer allocation failed.\n");
2168: return -1;
2169: }
2170: pr_rlist[rlist_len--] = NULL;
2171: for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
2172: rlist_len = 0;
2173:
2174: for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
2175:
2176: satype = doi2ipproto(pr->proto_id);
2177: if (satype == ~0) {
2178: plog(LLV_ERROR, LOCATION, NULL,
2179: "invalid proto_id %d\n", pr->proto_id);
2180: goto err;
2181: }
2182: mode = ipsecdoi2pfkey_mode(pr->encmode);
2183: if (mode == ~0) {
2184: plog(LLV_ERROR, LOCATION, NULL,
2185: "invalid encmode %d\n", pr->encmode);
2186: goto err;
2187: }
2188:
2189: /*
2190: * the policy level cannot be unique because the policy
2191: * is defined later than SA, so req_id cannot be bound to SA.
2192: */
2193: xisr->sadb_x_ipsecrequest_proto = satype;
2194: xisr->sadb_x_ipsecrequest_mode = mode;
2195: if(iph2->proposal->head->reqid_in > 0){
2196: xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
2197: xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
2198: }else{
2199: xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2200: xisr->sadb_x_ipsecrequest_reqid = 0;
2201: }
2202: p = (caddr_t)(xisr + 1);
2203:
2204: xisrlen = sizeof(*xisr);
2205:
2206: if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2207: int src_len, dst_len;
2208:
2209: src_len = sysdep_sa_len(src);
2210: dst_len = sysdep_sa_len(dst);
2211: xisrlen += src_len + dst_len;
2212:
2213: memcpy(p, src, src_len);
2214: p += src_len;
2215:
2216: memcpy(p, dst, dst_len);
2217: p += dst_len;
2218: }
2219:
2220: xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2221: xisr = (struct sadb_x_ipsecrequest *)p;
2222:
2223: }
2224: racoon_free(pr_rlist);
2225:
2226: end:
2227: *policy0 = policy;
2228: *policylen0 = policylen;
2229:
2230: return 0;
2231:
2232: err:
2233: if (policy)
2234: racoon_free(policy);
2235: if (pr_rlist) racoon_free(pr_rlist);
2236:
2237: return -1;
2238: }
2239:
2240: int
2241: pk_sendspdupdate2(iph2)
2242: struct ph2handle *iph2;
2243: {
2244: struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2245: caddr_t policy = NULL;
2246: int policylen = 0;
2247: u_int64_t ltime, vtime;
2248:
2249: ltime = iph2->approval->lifetime;
2250: vtime = 0;
2251:
2252: if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2253: plog(LLV_ERROR, LOCATION, NULL,
2254: "getting sadb policy failed.\n");
2255: return -1;
2256: }
2257:
2258: if (pfkey_send_spdupdate2(
2259: lcconf->sock_pfkey,
2260: (struct sockaddr *)&spidx->src,
2261: spidx->prefs,
2262: (struct sockaddr *)&spidx->dst,
2263: spidx->prefd,
2264: spidx->ul_proto,
2265: ltime, vtime,
2266: policy, policylen, 0) < 0) {
2267: plog(LLV_ERROR, LOCATION, NULL,
2268: "libipsec failed send spdupdate2 (%s)\n",
2269: ipsec_strerror());
2270: goto end;
2271: }
2272: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
2273:
2274: end:
2275: if (policy)
2276: racoon_free(policy);
2277:
2278: return 0;
2279: }
2280:
2281: static int
2282: pk_recvspdupdate(mhp)
2283: caddr_t *mhp;
2284: {
2285: struct sadb_address *saddr, *daddr;
2286: struct sadb_x_policy *xpl;
2287: struct sadb_lifetime *lt;
2288: struct policyindex spidx;
2289: struct secpolicy *sp;
2290: struct sockaddr *local=NULL, *remote=NULL;
2291: u_int64_t created;
2292: int ret;
2293:
2294: /* sanity check */
2295: if (mhp[0] == NULL
2296: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2297: || mhp[SADB_EXT_ADDRESS_DST] == NULL
2298: || mhp[SADB_X_EXT_POLICY] == NULL) {
2299: plog(LLV_ERROR, LOCATION, NULL,
2300: "inappropriate sadb spdupdate message passed.\n");
2301: return -1;
2302: }
2303: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2304: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2305: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2306: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2307: if(lt != NULL)
2308: created = lt->sadb_lifetime_addtime;
2309: else
2310: created = 0;
2311:
2312: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2313: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2314: saddr + 1,
2315: daddr + 1,
2316: saddr->sadb_address_prefixlen,
2317: daddr->sadb_address_prefixlen,
2318: saddr->sadb_address_proto,
2319: xpl->sadb_x_policy_priority,
2320: created,
2321: &spidx);
2322: #else
2323: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2324: saddr + 1,
2325: daddr + 1,
2326: saddr->sadb_address_prefixlen,
2327: daddr->sadb_address_prefixlen,
2328: saddr->sadb_address_proto,
2329: created,
2330: &spidx);
2331: #endif
2332:
2333: #ifdef HAVE_SECCTX
2334: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2335: struct sadb_x_sec_ctx *ctx;
2336:
2337: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2338: spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2339: spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2340: spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2341: memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2342: }
2343: #endif /* HAVE_SECCTX */
2344:
2345: sp = getsp(&spidx);
2346: if (sp == NULL) {
2347: plog(LLV_DEBUG, LOCATION, NULL,
2348: "this policy did not exist for removal: \"%s\"\n",
2349: spidx2str(&spidx));
2350: } else {
2351: /* preserve hints before deleting the SP */
2352: local = sp->local;
2353: remote = sp->remote;
2354: sp->local = NULL;
2355: sp->remote = NULL;
2356:
2357: remsp(sp);
2358: delsp(sp);
2359: }
2360:
2361: /* Add new SP (with old hints) */
2362: ret = addnewsp(mhp, local, remote);
2363:
2364: if (local != NULL)
2365: racoon_free(local);
2366: if (remote != NULL)
2367: racoon_free(remote);
2368:
2369: if (ret < 0)
2370: return -1;
2371:
2372: return 0;
2373: }
2374:
2375: /*
2376: * this function has to be used by responder side.
2377: */
2378: int
2379: pk_sendspdadd2(iph2)
2380: struct ph2handle *iph2;
2381: {
2382: struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2383: caddr_t policy = NULL;
2384: int policylen = 0;
2385: u_int64_t ltime, vtime;
2386:
2387: ltime = iph2->approval->lifetime;
2388: vtime = 0;
2389:
2390: if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2391: plog(LLV_ERROR, LOCATION, NULL,
2392: "getting sadb policy failed.\n");
2393: return -1;
2394: }
2395:
2396: if (pfkey_send_spdadd2(
2397: lcconf->sock_pfkey,
2398: (struct sockaddr *)&spidx->src,
2399: spidx->prefs,
2400: (struct sockaddr *)&spidx->dst,
2401: spidx->prefd,
2402: spidx->ul_proto,
2403: ltime, vtime,
2404: policy, policylen, 0) < 0) {
2405: plog(LLV_ERROR, LOCATION, NULL,
2406: "libipsec failed send spdadd2 (%s)\n",
2407: ipsec_strerror());
2408: goto end;
2409: }
2410: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
2411:
2412: end:
2413: if (policy)
2414: racoon_free(policy);
2415:
2416: return 0;
2417: }
2418:
2419: static int
2420: pk_recvspdadd(mhp)
2421: caddr_t *mhp;
2422: {
2423: struct sadb_address *saddr, *daddr;
2424: struct sadb_x_policy *xpl;
2425: struct sadb_lifetime *lt;
2426: struct policyindex spidx;
2427: struct secpolicy *sp;
2428: struct sockaddr *local = NULL, *remote = NULL;
2429: u_int64_t created;
2430: int ret;
2431:
2432: /* sanity check */
2433: if (mhp[0] == NULL
2434: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2435: || mhp[SADB_EXT_ADDRESS_DST] == NULL
2436: || mhp[SADB_X_EXT_POLICY] == NULL) {
2437: plog(LLV_ERROR, LOCATION, NULL,
2438: "inappropriate sadb spdadd message passed.\n");
2439: return -1;
2440: }
2441: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2442: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2443: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2444: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2445: if(lt != NULL)
2446: created = lt->sadb_lifetime_addtime;
2447: else
2448: created = 0;
2449:
2450: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2451: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2452: saddr + 1,
2453: daddr + 1,
2454: saddr->sadb_address_prefixlen,
2455: daddr->sadb_address_prefixlen,
2456: saddr->sadb_address_proto,
2457: xpl->sadb_x_policy_priority,
2458: created,
2459: &spidx);
2460: #else
2461: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2462: saddr + 1,
2463: daddr + 1,
2464: saddr->sadb_address_prefixlen,
2465: daddr->sadb_address_prefixlen,
2466: saddr->sadb_address_proto,
2467: created,
2468: &spidx);
2469: #endif
2470:
2471: #ifdef HAVE_SECCTX
2472: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2473: struct sadb_x_sec_ctx *ctx;
2474:
2475: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2476: spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2477: spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2478: spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2479: memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2480: }
2481: #endif /* HAVE_SECCTX */
2482:
2483: sp = getsp(&spidx);
2484: if (sp != NULL) {
2485: plog(LLV_ERROR, LOCATION, NULL,
2486: "such policy already exists. "
2487: "anyway replace it: %s\n",
2488: spidx2str(&spidx));
2489:
2490: /* preserve hints before deleting the SP */
2491: local = sp->local;
2492: remote = sp->remote;
2493: sp->local = NULL;
2494: sp->remote = NULL;
2495:
2496: remsp(sp);
2497: delsp(sp);
2498: }
2499:
2500: /* Add new SP (with old hints) */
2501: ret = addnewsp(mhp, local, remote);
2502:
2503: if (local != NULL)
2504: racoon_free(local);
2505: if (remote != NULL)
2506: racoon_free(remote);
2507:
2508: if (ret < 0)
2509: return -1;
2510:
2511: return 0;
2512: }
2513:
2514: /*
2515: * this function has to be used by responder side.
2516: */
2517: int
2518: pk_sendspddelete(iph2)
2519: struct ph2handle *iph2;
2520: {
2521: struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2522: caddr_t policy = NULL;
2523: int policylen;
2524:
2525: if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2526: plog(LLV_ERROR, LOCATION, NULL,
2527: "getting sadb policy failed.\n");
2528: return -1;
2529: }
2530:
2531: if (pfkey_send_spddelete(
2532: lcconf->sock_pfkey,
2533: (struct sockaddr *)&spidx->src,
2534: spidx->prefs,
2535: (struct sockaddr *)&spidx->dst,
2536: spidx->prefd,
2537: spidx->ul_proto,
2538: policy, policylen, 0) < 0) {
2539: plog(LLV_ERROR, LOCATION, NULL,
2540: "libipsec failed send spddelete (%s)\n",
2541: ipsec_strerror());
2542: goto end;
2543: }
2544: plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2545:
2546: end:
2547: if (policy)
2548: racoon_free(policy);
2549:
2550: return 0;
2551: }
2552:
2553: static int
2554: pk_recvspddelete(mhp)
2555: caddr_t *mhp;
2556: {
2557: struct sadb_address *saddr, *daddr;
2558: struct sadb_x_policy *xpl;
2559: struct sadb_lifetime *lt;
2560: struct policyindex spidx;
2561: struct secpolicy *sp;
2562: u_int64_t created;
2563:
2564: /* sanity check */
2565: if (mhp[0] == NULL
2566: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2567: || mhp[SADB_EXT_ADDRESS_DST] == NULL
2568: || mhp[SADB_X_EXT_POLICY] == NULL) {
2569: plog(LLV_ERROR, LOCATION, NULL,
2570: "inappropriate sadb spddelete message passed.\n");
2571: return -1;
2572: }
2573: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2574: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2575: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2576: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2577: if(lt != NULL)
2578: created = lt->sadb_lifetime_addtime;
2579: else
2580: created = 0;
2581:
2582: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2583: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2584: saddr + 1,
2585: daddr + 1,
2586: saddr->sadb_address_prefixlen,
2587: daddr->sadb_address_prefixlen,
2588: saddr->sadb_address_proto,
2589: xpl->sadb_x_policy_priority,
2590: created,
2591: &spidx);
2592: #else
2593: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2594: saddr + 1,
2595: daddr + 1,
2596: saddr->sadb_address_prefixlen,
2597: daddr->sadb_address_prefixlen,
2598: saddr->sadb_address_proto,
2599: created,
2600: &spidx);
2601: #endif
2602:
2603: #ifdef HAVE_SECCTX
2604: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2605: struct sadb_x_sec_ctx *ctx;
2606:
2607: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2608: spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2609: spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2610: spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2611: memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2612: }
2613: #endif /* HAVE_SECCTX */
2614:
2615: sp = getsp(&spidx);
2616: if (sp == NULL) {
2617: plog(LLV_ERROR, LOCATION, NULL,
2618: "no policy found: %s\n",
2619: spidx2str(&spidx));
2620: return -1;
2621: }
2622:
2623: remsp(sp);
2624: delsp(sp);
2625:
2626: return 0;
2627: }
2628:
2629: static int
2630: pk_recvspdexpire(mhp)
2631: caddr_t *mhp;
2632: {
2633: struct sadb_address *saddr, *daddr;
2634: struct sadb_x_policy *xpl;
2635: struct sadb_lifetime *lt;
2636: struct policyindex spidx;
2637: struct secpolicy *sp;
2638: u_int64_t created;
2639:
2640: /* sanity check */
2641: if (mhp[0] == NULL
2642: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2643: || mhp[SADB_EXT_ADDRESS_DST] == NULL
2644: || mhp[SADB_X_EXT_POLICY] == NULL) {
2645: plog(LLV_ERROR, LOCATION, NULL,
2646: "inappropriate sadb spdexpire message passed.\n");
2647: return -1;
2648: }
2649: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2650: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2651: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2652: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2653: if(lt != NULL)
2654: created = lt->sadb_lifetime_addtime;
2655: else
2656: created = 0;
2657:
2658: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2659: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2660: saddr + 1,
2661: daddr + 1,
2662: saddr->sadb_address_prefixlen,
2663: daddr->sadb_address_prefixlen,
2664: saddr->sadb_address_proto,
2665: xpl->sadb_x_policy_priority,
2666: created,
2667: &spidx);
2668: #else
2669: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2670: saddr + 1,
2671: daddr + 1,
2672: saddr->sadb_address_prefixlen,
2673: daddr->sadb_address_prefixlen,
2674: saddr->sadb_address_proto,
2675: created,
2676: &spidx);
2677: #endif
2678:
2679: #ifdef HAVE_SECCTX
2680: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2681: struct sadb_x_sec_ctx *ctx;
2682:
2683: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2684: spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2685: spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2686: spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2687: memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2688: }
2689: #endif /* HAVE_SECCTX */
2690:
2691: sp = getsp(&spidx);
2692: if (sp == NULL) {
2693: plog(LLV_ERROR, LOCATION, NULL,
2694: "no policy found: %s\n",
2695: spidx2str(&spidx));
2696: return -1;
2697: }
2698:
2699: remsp(sp);
2700: delsp(sp);
2701:
2702: return 0;
2703: }
2704:
2705: static int
2706: pk_recvspdget(mhp)
2707: caddr_t *mhp;
2708: {
2709: /* sanity check */
2710: if (mhp[0] == NULL) {
2711: plog(LLV_ERROR, LOCATION, NULL,
2712: "inappropriate sadb spdget message passed.\n");
2713: return -1;
2714: }
2715:
2716: return 0;
2717: }
2718:
2719: static int
2720: pk_recvspddump(mhp)
2721: caddr_t *mhp;
2722: {
2723: struct sadb_msg *msg;
2724: struct sadb_address *saddr, *daddr;
2725: struct sadb_x_policy *xpl;
2726: struct sadb_lifetime *lt;
2727: struct policyindex spidx;
2728: struct secpolicy *sp;
2729: struct sockaddr *local=NULL, *remote=NULL;
2730: u_int64_t created;
2731: int ret;
2732:
2733: /* sanity check */
2734: if (mhp[0] == NULL) {
2735: plog(LLV_ERROR, LOCATION, NULL,
2736: "inappropriate sadb spddump message passed.\n");
2737: return -1;
2738: }
2739: msg = (struct sadb_msg *)mhp[0];
2740: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2741: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2742: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2743: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2744: if(lt != NULL)
2745: created = lt->sadb_lifetime_addtime;
2746: else
2747: created = 0;
2748:
2749: if (saddr == NULL || daddr == NULL || xpl == NULL) {
2750: plog(LLV_ERROR, LOCATION, NULL,
2751: "inappropriate sadb spddump message passed.\n");
2752: return -1;
2753: }
2754:
2755: #ifdef HAVE_PFKEY_POLICY_PRIORITY
2756: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2757: saddr + 1,
2758: daddr + 1,
2759: saddr->sadb_address_prefixlen,
2760: daddr->sadb_address_prefixlen,
2761: saddr->sadb_address_proto,
2762: xpl->sadb_x_policy_priority,
2763: created,
2764: &spidx);
2765: #else
2766: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2767: saddr + 1,
2768: daddr + 1,
2769: saddr->sadb_address_prefixlen,
2770: daddr->sadb_address_prefixlen,
2771: saddr->sadb_address_proto,
2772: created,
2773: &spidx);
2774: #endif
2775:
2776: #ifdef HAVE_SECCTX
2777: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2778: struct sadb_x_sec_ctx *ctx;
2779:
2780: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2781: spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2782: spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2783: spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2784: memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2785: }
2786: #endif /* HAVE_SECCTX */
2787:
2788: sp = getsp(&spidx);
2789: if (sp != NULL) {
2790: plog(LLV_ERROR, LOCATION, NULL,
2791: "such policy already exists. "
2792: "anyway replace it: %s\n",
2793: spidx2str(&spidx));
2794:
2795: /* preserve hints before deleting the SP */
2796: local = sp->local;
2797: remote = sp->remote;
2798: sp->local = NULL;
2799: sp->remote = NULL;
2800:
2801: remsp(sp);
2802: delsp(sp);
2803: }
2804:
2805: /* Add new SP (with old hints) */
2806: ret = addnewsp(mhp, local, remote);
2807:
2808: if (local != NULL)
2809: racoon_free(local);
2810: if (remote != NULL)
2811: racoon_free(remote);
2812:
2813: if (ret < 0)
2814: return -1;
2815:
2816: return 0;
2817: }
2818:
2819: static int
2820: pk_recvspdflush(mhp)
2821: caddr_t *mhp;
2822: {
2823: /* sanity check */
2824: if (mhp[0] == NULL) {
2825: plog(LLV_ERROR, LOCATION, NULL,
2826: "inappropriate sadb spdflush message passed.\n");
2827: return -1;
2828: }
2829:
2830: flushsp();
2831:
2832: return 0;
2833: }
2834:
2835: #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
2836:
2837: /* MIGRATE support (pk_recvmigrate() is the handler of MIGRATE message).
2838: *
2839: * pk_recvmigrate()
2840: * 1) some preprocessing and checks
2841: * 2) parsing of sadb_x_kmaddress extension
2842: * 3) SP lookup using selectors and content of policy extension from MIGRATE
2843: * 4) resolution of current local and remote IKE addresses
2844: * 5) Use of addresses to get Phase 1 handler if any
2845: * 6) Update of IKE addresses in Phase 1 (iph1->local and iph1->remote)
2846: * 7) Update of IKE addresses in Phase 2 (iph2->src and iph2->dst)
2847: * 8) Update of IKE addresses in SP (sp->local and sp->remote)
2848: * 9) Loop on sadb_x_ipsecrequests pairs from MIGRATE
2849: * - update of associated ipsecrequests entries in sp->req (should be
2850: * only one as racoon does not support bundles), i.e. update of
2851: * tunnel endpoints when required.
2852: * - If tunnel mode endpoints have been updated, lookup of associated
2853: * Phase 2 handle to also update sa_src and sa_dst entries
2854: *
2855: * XXX Note that we do not support yet the update of SA addresses for transport
2856: * mode, but only the update of SA addresses for tunnel mode (endpoints).
2857: * Reasons are:
2858: * - there is no initial need for MIPv6
2859: * - racoon does not support bundles
2860: * - this would imply more work to deal with sainfo update (if feasible).
2861: */
2862:
2863: /* Generic argument structure for migration callbacks */
2864: struct migrate_args {
2865: struct sockaddr *local;
2866: struct sockaddr *remote;
2867: };
2868:
2869: /*
2870: * Update local and remote addresses of given Phase 1. Schedule removal
2871: * if negotiation was going on and restart a one from updated address.
2872: *
2873: * -1 is returned on error. 0 if everything went right.
2874: */
2875: static int
2876: migrate_ph1_ike_addresses(iph1, arg)
2877: struct ph1handle *iph1;
2878: void *arg;
2879: {
2880: struct migrate_args *ma = (struct migrate_args *) arg;
2881: struct remoteconf *rmconf;
2882: u_int16_t port;
2883:
2884: /* Already up-to-date? */
2885: if (cmpsaddr(iph1->local, ma->local) == CMPSADDR_MATCH &&
2886: cmpsaddr(iph1->remote, ma->remote) == CMPSADDR_MATCH)
2887: return 0;
2888:
2889: if (iph1->status < PHASE1ST_ESTABLISHED) {
2890: /* Bad luck! We received a MIGRATE *while* negotiating
2891: * Phase 1 (i.e. it was not established yet). If we act as
2892: * initiator we need to restart the negotiation. As
2893: * responder, our best bet is to update our addresses
2894: * and wait for the initiator to do something */
2895: plog(LLV_WARNING, LOCATION, NULL, "MIGRATE received *during* "
2896: "Phase 1 negotiation (%s).\n",
2897: saddr2str_fromto("%s => %s", ma->local, ma->remote));
2898:
2899: /* If we are not acting as initiator, let's just leave and
2900: * let the remote peer handle the restart */
2901: rmconf = getrmconf(ma->remote, 0);
2902: if (rmconf == NULL || !rmconf->passive) {
2903: iph1->status = PHASE1ST_EXPIRED;
2904: isakmp_ph1delete(iph1);
2905:
2906: /* This is unlikely, but let's just check if a Phase 1
2907: * for the new addresses already exist */
2908: if (getph1byaddr(ma->local, ma->remote, 0)) {
2909: plog(LLV_WARNING, LOCATION, NULL, "No need "
2910: "to start a new Phase 1 negotiation. One "
2911: "already exists.\n");
2912: return 0;
2913: }
2914:
2915: plog(LLV_WARNING, LOCATION, NULL, "As initiator, "
2916: "restarting it.\n");
2917: /* Note that the insertion of the new Phase 1 will not
2918: * interfere with the fact we are called from enumph1,
2919: * because it is inserted as first element. --arno */
2920: isakmp_ph1begin_i(rmconf, ma->local, ma->remote);
2921:
2922: return 0;
2923: }
2924: }
2925:
2926: if (iph1->local != NULL) {
2927: plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 local "
2928: "address from %s\n",
2929: saddr2str_fromto("%s to %s", iph1->local, ma->local));
2930: port = extract_port(iph1->local);
2931: racoon_free(iph1->local);
2932: } else
2933: port = 0;
2934:
2935: iph1->local = dupsaddr(ma->local);
2936: if (iph1->local == NULL) {
2937: plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2938: "Phase 1 local address.\n");
2939: return -1;
2940: }
2941: set_port(iph1->local, port);
2942:
2943: if (iph1->remote != NULL) {
2944: plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 remote "
2945: "address from %s\n",
2946: saddr2str_fromto("%s to %s", iph1->remote, ma->remote));
2947: port = extract_port(iph1->remote);
2948: racoon_free(iph1->remote);
2949: } else
2950: port = 0;
2951:
2952: iph1->remote = dupsaddr(ma->remote);
2953: if (iph1->remote == NULL) {
2954: plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2955: "Phase 1 remote address.\n");
2956: return -1;
2957: }
2958: set_port(iph1->remote, port);
2959:
2960: return 0;
2961: }
2962:
2963: /* Update src and dst of all current Phase 2 handles.
2964: * with provided local and remote addresses.
2965: * Our intent is NOT to modify IPsec SA endpoints but IKE
2966: * addresses so we need to take care to separate those if
2967: * they are different. -1 is returned on error. 0 if everything
2968: * went right.
2969: *
2970: * Note: we do not maintain port information as it is not
2971: * expected to be meaningful --arno
2972: */
2973: static int
2974: migrate_ph2_ike_addresses(iph2, arg)
2975: struct ph2handle *iph2;
2976: void *arg;
2977: {
2978: struct migrate_args *ma = (struct migrate_args *) arg;
2979: struct ph1handle *iph1;
2980:
2981: /* If Phase 2 has an associated Phase 1, migrate addresses */
2982: if (iph2->ph1)
2983: migrate_ph1_ike_addresses(iph2->ph1, arg);
2984:
2985: /* Already up-to-date? */
2986: if (cmpsaddr(iph2->src, ma->local) == CMPSADDR_MATCH &&
2987: cmpsaddr(iph2->dst, ma->remote) == CMPSADDR_MATCH)
2988: return 0;
2989:
2990: /* save src/dst as sa_src/sa_dst before rewriting */
2991: if (iph2->sa_src == NULL && iph2->sa_dst == NULL) {
2992: iph2->sa_src = iph2->src;
2993: iph2->sa_dst = iph2->dst;
2994: iph2->src = NULL;
2995: iph2->dst = NULL;
2996: }
2997:
2998: if (iph2->src != NULL)
2999: racoon_free(iph2->src);
3000: iph2->src = dupsaddr(ma->local);
3001: if (iph2->src == NULL) {
3002: plog(LLV_ERROR, LOCATION, NULL,
3003: "unable to allocate Phase 2 src address.\n");
3004: return -1;
3005: }
3006:
3007: if (iph2->dst != NULL)
3008: racoon_free(iph2->dst);
3009: iph2->dst = dupsaddr(ma->remote);
3010: if (iph2->dst == NULL) {
3011: plog(LLV_ERROR, LOCATION, NULL,
3012: "unable to allocate Phase 2 dst address.\n");
3013: return -1;
3014: }
3015:
3016: return 0;
3017: }
3018:
3019: /* Consider existing Phase 2 handles with given spid and update their source
3020: * and destination addresses for SA. As racoon does not support bundles, if
3021: * we modify multiple occurrences, this probably imply rekeying has happened.
3022: *
3023: * Both addresses passed to the function are expected not to be NULL and of
3024: * same family. -1 is returned on error. 0 if everything went right.
3025: *
3026: * Specific care is needed to support Phase 2 for which negotiation has
3027: * already started but are which not yet established.
3028: */
3029: static int
3030: migrate_ph2_sa_addresses(iph2, args)
3031: struct ph2handle *iph2;
3032: void *args;
3033: {
3034: struct migrate_args *ma = (struct migrate_args *) args;
3035:
3036: if (iph2->sa_src != NULL) {
3037: racoon_free(iph2->sa_src);
3038: iph2->sa_src = NULL;
3039: }
3040:
3041: if (iph2->sa_dst != NULL) {
3042: racoon_free(iph2->sa_dst);
3043: iph2->sa_dst = NULL;
3044: }
3045:
3046: iph2->sa_src = dupsaddr(ma->local);
3047: if (iph2->sa_src == NULL) {
3048: plog(LLV_ERROR, LOCATION, NULL,
3049: "unable to allocate Phase 2 sa_src address.\n");
3050: return -1;
3051: }
3052:
3053: iph2->sa_dst = dupsaddr(ma->remote);
3054: if (iph2->sa_dst == NULL) {
3055: plog(LLV_ERROR, LOCATION, NULL,
3056: "unable to allocate Phase 2 sa_dst address.\n");
3057: return -1;
3058: }
3059:
3060: if (iph2->status < PHASE2ST_ESTABLISHED) {
3061: struct remoteconf *rmconf;
3062: /* We were negotiating for that SA when we received the MIGRATE.
3063: * We cannot simply update the addresses and let the exchange
3064: * go on. We have to restart the whole negotiation if we are
3065: * the initiator. Otherwise (acting as responder), we just need
3066: * to delete our ph2handle and wait for the initiator to start
3067: * a new negotiation. */
3068:
3069: if (iph2->ph1 && iph2->ph1->rmconf)
3070: rmconf = iph2->ph1->rmconf;
3071: else
3072: rmconf = getrmconf(iph2->dst, 0);
3073:
3074: if (rmconf && !rmconf->passive) {
3075: struct ph1handle *iph1hint;
3076:
3077: plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3078: "*during* IPsec SA negotiation. As initiator, "
3079: "restarting it.\n");
3080:
3081: /* Turn off expiration timer ...*/
3082: sched_cancel(&iph2->sce);
3083: iph2->status = PHASE2ST_EXPIRED;
3084:
3085: /* ... clean Phase 2 handle ... */
3086: iph1hint = iph2->ph1;
3087: initph2(iph2);
3088: iph2->status = PHASE2ST_STATUS2;
3089:
3090: /* and start a new negotiation */
3091: if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
3092: plog(LLV_ERROR, LOCATION, iph2->dst, "failed "
3093: "to begin IPsec SA renegotiation after "
3094: "MIGRATE reception.\n");
3095: remph2(iph2);
3096: delph2(iph2);
3097: return -1;
3098: }
3099: } else {
3100: plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3101: "*during* IPsec SA negotiation. As responder, let's"
3102: "wait for the initiator to act.\n");
3103:
3104: /* Simply schedule deletion */
3105: isakmp_ph2expire(iph2);
3106: }
3107: }
3108:
3109: return 0;
3110: }
3111:
3112: /* Update SP hints (local and remote addresses) for future IKE
3113: * negotiations of SA associated with that SP. -1 is returned
3114: * on error. 0 if everything went right.
3115: *
3116: * Note: we do not maintain port information as it is not
3117: * expected to be meaningful --arno
3118: */
3119: static int
3120: migrate_sp_ike_addresses(sp, local, remote)
3121: struct secpolicy *sp;
3122: struct sockaddr *local, *remote;
3123: {
3124: if (sp == NULL || local == NULL || remote == NULL)
3125: return -1;
3126:
3127: if (sp->local != NULL)
3128: racoon_free(sp->local);
3129:
3130: sp->local = dupsaddr(local);
3131: if (sp->local == NULL) {
3132: plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3133: "local hint for SP.\n");
3134: return -1;
3135: }
3136:
3137: if (sp->remote != NULL)
3138: racoon_free(sp->remote);
3139:
3140: sp->remote = dupsaddr(remote);
3141: if (sp->remote == NULL) {
3142: plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3143: "remote hint for SP.\n");
3144: return -1;
3145: }
3146:
3147: return 0;
3148: }
3149:
3150: /* Given current ipsecrequest (isr_cur) to be migrated in considered
3151: tree, the function first checks that it matches the expected one
3152: (xisr_old) provided in MIGRATE message and then updates the addresses
3153: if it is tunnel mode (with content of xisr_new). Various other checks
3154: are performed. For transport mode, structures are not modified, only
3155: the checks are done. -1 is returned on error. */
3156: static int
3157: migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new)
3158: u_int32_t spid;
3159: struct ipsecrequest *isr_cur;
3160: struct sadb_x_ipsecrequest *xisr_old, *xisr_new;
3161: {
3162: struct secasindex *saidx = &isr_cur->saidx;
3163: struct sockaddr *osaddr, *odaddr, *nsaddr, *ndaddr;
3164: struct ph2selector ph2sel;
3165: struct migrate_args ma;
3166:
3167: /* First, check that mode and proto do match */
3168: if (xisr_old->sadb_x_ipsecrequest_proto != saidx->proto ||
3169: xisr_old->sadb_x_ipsecrequest_mode != saidx->mode ||
3170: xisr_new->sadb_x_ipsecrequest_proto != saidx->proto ||
3171: xisr_new->sadb_x_ipsecrequest_mode != saidx->mode)
3172: return -1;
3173:
3174: /* Then, verify reqid if necessary */
3175: if (isr_cur->saidx.reqid &&
3176: (xisr_old->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3177: xisr_new->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3178: isr_cur->saidx.reqid != xisr_old->sadb_x_ipsecrequest_reqid ||
3179: isr_cur->saidx.reqid != xisr_new->sadb_x_ipsecrequest_reqid))
3180: return -1;
3181:
3182: /* If not tunnel mode, our work is over */
3183: if (saidx->mode != IPSEC_MODE_TUNNEL) {
3184: plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3185: "non tunnel mode isr, skipping SA address migration.\n");
3186: return 0;
3187: }
3188:
3189: /* Tunnel mode: let's check addresses do match and then update them. */
3190: osaddr = (struct sockaddr *)(xisr_old + 1);
3191: odaddr = (struct sockaddr *)(((u_int8_t *)osaddr) + sysdep_sa_len(osaddr));
3192: nsaddr = (struct sockaddr *)(xisr_new + 1);
3193: ndaddr = (struct sockaddr *)(((u_int8_t *)nsaddr) + sysdep_sa_len(nsaddr));
3194:
3195: /* Check family does match */
3196: if (osaddr->sa_family != odaddr->sa_family ||
3197: nsaddr->sa_family != ndaddr->sa_family)
3198: return -1;
3199:
3200: /* Check family does match */
3201: if (saidx->src.ss_family != osaddr->sa_family)
3202: return -1;
3203:
3204: /* We log IPv4 to IPv6 and IPv6 to IPv4 switches */
3205: if (nsaddr->sa_family != osaddr->sa_family)
3206: plog(LLV_INFO, LOCATION, NULL, "SADB_X_MIGRATE: "
3207: "changing address families (%d to %d) for endpoints.\n",
3208: osaddr->sa_family, nsaddr->sa_family);
3209:
3210: if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) != CMPSADDR_MATCH ||
3211: cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst) != CMPSADDR_MATCH) {
3212: plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3213: "mismatch of addresses in saidx and xisr.\n");
3214: return -1;
3215: }
3216:
3217: /* Excellent. Let's grab associated Phase 2 handle (if any)
3218: * and update its sa_src and sa_dst entries. Note that we
3219: * make the assumption that racoon does not support bundles
3220: * and make the lookup using spid: we blindly update
3221: * sa_src and sa_dst for _all_ found Phase 2 handles */
3222: memset(&ph2sel, 0, sizeof(ph2sel));
3223: ph2sel.spid = spid;
3224:
3225: memset(&ma, 0, sizeof(ma));
3226: ma.local = nsaddr;
3227: ma.remote = ndaddr;
3228:
3229: if (enumph2(&ph2sel, migrate_ph2_sa_addresses, &ma) < 0)
3230: return -1;
3231:
3232: /* Now we can do the update of endpoints in secasindex */
3233: memcpy(&saidx->src, nsaddr, sysdep_sa_len(nsaddr));
3234: memcpy(&saidx->dst, ndaddr, sysdep_sa_len(ndaddr));
3235:
3236: return 0;
3237: }
3238:
3239: /* Process the raw (unparsed yet) list of sadb_x_ipsecrequests of MIGRATE
3240: * message. For each sadb_x_ipsecrequest pair (old followed by new),
3241: * the corresponding ipsecrequest entry in the SP is updated. Associated
3242: * existing Phase 2 handle is also updated (if any) */
3243: static int
3244: migrate_sp_isr_list(sp, xisr_list, xisr_list_len)
3245: struct secpolicy *sp;
3246: struct sadb_x_ipsecrequest *xisr_list;
3247: int xisr_list_len;
3248: {
3249: struct sadb_x_ipsecrequest *xisr_new, *xisr_old = xisr_list;
3250: int xisr_old_len, xisr_new_len;
3251: struct ipsecrequest *isr_cur;
3252:
3253: isr_cur = sp->req; /* ipsecrequest list from from sp */
3254:
3255: while (xisr_list_len > 0 && isr_cur != NULL) {
3256: /* Get old xisr (length field is in bytes) */
3257: xisr_old_len = xisr_old->sadb_x_ipsecrequest_len;
3258: if (xisr_old_len < sizeof(*xisr_old) ||
3259: xisr_old_len + sizeof(*xisr_new) > xisr_list_len) {
3260: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3261: "invalid ipsecrequest length. Exiting.\n");
3262: return -1;
3263: }
3264:
3265: /* Get new xisr with updated info */
3266: xisr_new = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_old) + xisr_old_len);
3267: xisr_new_len = xisr_new->sadb_x_ipsecrequest_len;
3268: if (xisr_new_len < sizeof(*xisr_new) ||
3269: xisr_new_len + xisr_old_len > xisr_list_len) {
3270: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3271: "invalid ipsecrequest length. Exiting.\n");
3272: return -1;
3273: }
3274:
3275: /* Start by migrating current ipsecrequest from SP */
3276: if (migrate_ph2_one_isr(sp->id, isr_cur, xisr_old, xisr_new) == -1) {
3277: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3278: "Unable to match and migrate isr. Exiting.\n");
3279: return -1;
3280: }
3281:
3282: /* Update pointers for next round */
3283: xisr_list_len -= xisr_old_len + xisr_new_len;
3284: xisr_old = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_new) +
3285: xisr_new_len);
3286:
3287: isr_cur = isr_cur->next; /* Get next ipsecrequest from SP */
3288: }
3289:
3290: /* Check we had the same amount of pairs in the MIGRATE
3291: as the number of ipsecrequests in the SP */
3292: if ((xisr_list_len != 0) || isr_cur != NULL) {
3293: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3294: "number of ipsecrequest does not match the one in SP.\n");
3295: return -1;
3296: }
3297:
3298: return 0;
3299: }
3300:
3301: /* Parse sadb_x_kmaddress extension and make local and remote
3302: * parameters point to the new addresses (zero copy). -1 is
3303: * returned on error, meaning that addresses are not usable */
3304: static int
3305: parse_kmaddress(kmaddr, local, remote)
3306: struct sadb_x_kmaddress *kmaddr;
3307: struct sockaddr **local, **remote;
3308: {
3309: int addrslen, local_len=0;
3310: struct ph1handle *iph1;
3311:
3312: if (kmaddr == NULL)
3313: return -1;
3314:
3315: /* Grab addresses in sadb_x_kmaddress extension */
3316: addrslen = PFKEY_EXTLEN(kmaddr) - sizeof(*kmaddr);
3317: if (addrslen < sizeof(struct sockaddr))
3318: return -1;
3319:
3320: *local = (struct sockaddr *)(kmaddr + 1);
3321:
3322: switch ((*local)->sa_family) {
3323: case AF_INET:
3324: local_len = sizeof(struct sockaddr_in);
3325: break;
3326: #ifdef INET6
3327: case AF_INET6:
3328: local_len = sizeof(struct sockaddr_in6);
3329: break;
3330: #endif
3331: default:
3332: return -1;
3333: }
3334:
3335: if (addrslen != PFKEY_ALIGN8(2*local_len))
3336: return -1;
3337:
3338: *remote = (struct sockaddr *)(((u_int8_t *)(*local)) + local_len);
3339:
3340: if ((*local)->sa_family != (*remote)->sa_family)
3341: return -1;
3342:
3343: return 0;
3344: }
3345:
3346: /* Handler of PF_KEY MIGRATE message. Helpers are above */
3347: static int
3348: pk_recvmigrate(mhp)
3349: caddr_t *mhp;
3350: {
3351: struct sadb_address *saddr, *daddr;
3352: struct sockaddr *old_saddr, *new_saddr;
3353: struct sockaddr *old_daddr, *new_daddr;
3354: struct sockaddr *old_local, *old_remote;
3355: struct sockaddr *local, *remote;
3356: struct sadb_x_kmaddress *kmaddr;
3357: struct sadb_x_policy *xpl;
3358: struct sadb_x_ipsecrequest *xisr_list;
3359: struct sadb_lifetime *lt;
3360: struct policyindex spidx;
3361: struct secpolicy *sp;
3362: struct ipsecrequest *isr_cur;
3363: struct secasindex *oldsaidx;
3364: struct ph2handle *iph2;
3365: struct ph1handle *iph1;
3366: struct ph2selector ph2sel;
3367: struct ph1selector ph1sel;
3368: u_int32_t spid;
3369: u_int64_t created;
3370: int xisr_list_len;
3371: int ulproto;
3372: struct migrate_args ma;
3373:
3374: /* Some sanity checks */
3375:
3376: if (mhp[0] == NULL
3377: || mhp[SADB_EXT_ADDRESS_SRC] == NULL
3378: || mhp[SADB_EXT_ADDRESS_DST] == NULL
3379: || mhp[SADB_X_EXT_KMADDRESS] == NULL
3380: || mhp[SADB_X_EXT_POLICY] == NULL) {
3381: plog(LLV_ERROR, LOCATION, NULL,
3382: "SADB_X_MIGRATE: invalid MIGRATE message received.\n");
3383: return -1;
3384: }
3385: kmaddr = (struct sadb_x_kmaddress *)mhp[SADB_X_EXT_KMADDRESS];
3386: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3387: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3388: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3389: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3390: if (lt != NULL)
3391: created = lt->sadb_lifetime_addtime;
3392: else
3393: created = 0;
3394:
3395: if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
3396: plog(LLV_WARNING, LOCATION, NULL,"SADB_X_MIGRATE: "
3397: "found non IPsec policy in MIGRATE message. Exiting.\n");
3398: return -1;
3399: }
3400:
3401: if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3402: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3403: "invalid size for sadb_x_policy. Exiting.\n");
3404: return -1;
3405: }
3406:
3407: /* Some logging to help debbugging */
3408: if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
3409: plog(LLV_DEBUG, LOCATION, NULL,
3410: "SADB_X_MIGRATE: Outbound SA being migrated.\n");
3411: else
3412: plog(LLV_DEBUG, LOCATION, NULL,
3413: "SADB_X_MIGRATE: Inbound SA being migrated.\n");
3414:
3415: /* validity check */
3416: xisr_list = (struct sadb_x_ipsecrequest *)(xpl + 1);
3417: xisr_list_len = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3418: if (xisr_list_len < sizeof(*xisr_list)) {
3419: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3420: "invalid sadb_x_policy message length. Exiting.\n");
3421: return -1;
3422: }
3423:
3424: if (parse_kmaddress(kmaddr, &local, &remote) == -1) {
3425: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3426: "invalid sadb_x_kmaddress extension. Exiting.\n");
3427: return -1;
3428: }
3429:
3430: /* 0 means ANY */
3431: if (saddr->sadb_address_proto == 0)
3432: ulproto = IPSEC_ULPROTO_ANY;
3433: else
3434: ulproto = saddr->sadb_address_proto;
3435:
3436: #ifdef HAVE_PFKEY_POLICY_PRIORITY
3437: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3438: saddr + 1,
3439: daddr + 1,
3440: saddr->sadb_address_prefixlen,
3441: daddr->sadb_address_prefixlen,
3442: ulproto,
3443: xpl->sadb_x_policy_priority,
3444: created,
3445: &spidx);
3446: #else
3447: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3448: saddr + 1,
3449: daddr + 1,
3450: saddr->sadb_address_prefixlen,
3451: daddr->sadb_address_prefixlen,
3452: ulproto,
3453: created,
3454: &spidx);
3455: #endif
3456:
3457: /* Everything seems ok, let's get the SP.
3458: *
3459: * XXX We could also do the lookup using the spid from xpl.
3460: * I don't know which one is better. --arno */
3461: sp = getsp(&spidx);
3462: if (sp == NULL) {
3463: plog(LLV_ERROR, LOCATION, NULL,
3464: "SADB_X_MIGRATE: Passed policy does not exist: %s\n",
3465: spidx2str(&spidx));
3466: return -1;
3467: }
3468:
3469: /* Get the best source and destination addresses used for IKE
3470: * negotiation, to find and migrate existing Phase 1 */
3471: if (sp->local && sp->remote) {
3472: /* hints available, let's use them */
3473: old_local = (struct sockaddr *)sp->local;
3474: old_remote = (struct sockaddr *)sp->remote;
3475: } else if (sp->req && sp->req->saidx.mode == IPSEC_MODE_TUNNEL) {
3476: /* Tunnel mode and no hint, use endpoints */
3477: old_local = (struct sockaddr *)&sp->req->saidx.src;
3478: old_remote = (struct sockaddr *)&sp->req->saidx.dst;
3479: } else {
3480: /* default, use selectors as fallback */
3481: old_local = (struct sockaddr *)&sp->spidx.src;
3482: old_remote = (struct sockaddr *)&sp->spidx.dst;
3483: }
3484:
3485: /* We migrate all Phase 1 that match our old local and remote
3486: * addresses (no matter their state).
3487: *
3488: * XXX In fact, we should probably havea special treatment for
3489: * Phase 1 that are being established when we receive a MIGRATE.
3490: * This can happen if a movement occurs during the initial IKE
3491: * negotiation. In that case, I wonder if should restart the
3492: * negotiation from the new address or just update things like
3493: * we do it now.
3494: *
3495: * XXX while looking at getph1byaddr(), the comment at the
3496: * beginning of the function expects comparison to happen
3497: * without ports considerations but it uses CMPSADDR() which
3498: * relies either on cmpsaddrstrict() or cmpsaddrwop() based
3499: * on NAT-T support being activated. That make me wonder if I
3500: * should force ports to 0 (ANY) in local and remote values
3501: * used below.
3502: *
3503: * -- arno */
3504:
3505: /* Apply callback data ...*/
3506: memset(&ma, 0, sizeof(ma));
3507: ma.local = local;
3508: ma.remote = remote;
3509:
3510: /* Fill phase1 match criteria ... */
3511: memset(&ph1sel, 0, sizeof(ph1sel));
3512: ph1sel.local = old_local;
3513: ph1sel.remote = old_remote;
3514:
3515:
3516: /* Have matching Phase 1 found and addresses updated. As this is a
3517: * time consuming task on a busy responder, and MIGRATE messages
3518: * are always sent for *both* inbound and outbound (and possibly
3519: * forward), we only do that for outbound SP. */
3520: if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND &&
3521: enumph1(&ph1sel, migrate_ph1_ike_addresses, &ma) < 0) {
3522: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3523: "to migrate Phase 1 addresses.\n");
3524: return -1;
3525: }
3526:
3527: /* We can now update IKE addresses in Phase 2 handle. */
3528: memset(&ph2sel, 0, sizeof(ph2sel));
3529: ph2sel.spid = sp->id;
3530: if (enumph2(&ph2sel, migrate_ph2_ike_addresses, &ma) < 0) {
3531: plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3532: "to migrate Phase 2 IKE addresses.\n");
3533: return -1;
3534: }
3535:
3536: /* and _then_ in SP. */
3537: if (migrate_sp_ike_addresses(sp, local, remote) < 0) {
3538: plog(LLV_ERROR, LOCATION, NULL,
3539: "SADB_X_MIGRATE: Unable to migrate SP IKE addresses.\n");
3540: return -1;
3541: }
3542:
3543: /* Loop on sadb_x_ipsecrequest list to possibly update sp->req
3544: * entries and associated live Phase 2 handles (their sa_src
3545: * and sa_dst) */
3546: if (migrate_sp_isr_list(sp, xisr_list, xisr_list_len) < 0) {
3547: plog(LLV_ERROR, LOCATION, NULL,
3548: "SADB_X_MIGRATE: Unable to migrate isr list.\n");
3549: return -1;
3550: }
3551:
3552: return 0;
3553: }
3554: #endif
3555:
3556: /*
3557: * send error against acquire message to kernel.
3558: */
3559: int
3560: pk_sendeacquire(iph2)
3561: struct ph2handle *iph2;
3562: {
3563: struct sadb_msg *newmsg;
3564: int len;
3565:
3566: len = sizeof(struct sadb_msg);
3567: newmsg = racoon_calloc(1, len);
3568: if (newmsg == NULL) {
3569: plog(LLV_ERROR, LOCATION, NULL,
3570: "failed to get buffer to send acquire.\n");
3571: return -1;
3572: }
3573:
3574: memset(newmsg, 0, len);
3575: newmsg->sadb_msg_version = PF_KEY_V2;
3576: newmsg->sadb_msg_type = SADB_ACQUIRE;
3577: newmsg->sadb_msg_errno = ENOENT; /* XXX */
3578: newmsg->sadb_msg_satype = iph2->satype;
3579: newmsg->sadb_msg_len = PFKEY_UNIT64(len);
3580: newmsg->sadb_msg_reserved = 0;
3581: newmsg->sadb_msg_seq = iph2->seq;
3582: newmsg->sadb_msg_pid = (u_int32_t)getpid();
3583:
3584: /* send message */
3585: len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
3586:
3587: racoon_free(newmsg);
3588:
3589: return 0;
3590: }
3591:
3592: /*
3593: * check if the algorithm is supported or not.
3594: * OUT 0: ok
3595: * -1: ng
3596: */
3597: int
3598: pk_checkalg(class, calg, keylen)
3599: int class, calg, keylen;
3600: {
3601: int sup, error;
3602: u_int alg;
3603: struct sadb_alg alg0;
3604:
3605: switch (algclass2doi(class)) {
3606: case IPSECDOI_PROTO_IPSEC_ESP:
3607: sup = SADB_EXT_SUPPORTED_ENCRYPT;
3608: break;
3609: case IPSECDOI_ATTR_AUTH:
3610: sup = SADB_EXT_SUPPORTED_AUTH;
3611: break;
3612: case IPSECDOI_PROTO_IPCOMP:
3613: plog(LLV_DEBUG, LOCATION, NULL,
3614: "no check of compression algorithm; "
3615: "not supported in sadb message.\n");
3616: return 0;
3617: default:
3618: plog(LLV_ERROR, LOCATION, NULL,
3619: "invalid algorithm class.\n");
3620: return -1;
3621: }
3622: alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
3623: if (alg == ~0)
3624: return -1;
3625:
3626: if (keylen == 0) {
3627: if (ipsec_get_keylen(sup, alg, &alg0)) {
3628: plog(LLV_ERROR, LOCATION, NULL,
3629: "%s.\n", ipsec_strerror());
3630: return -1;
3631: }
3632: keylen = alg0.sadb_alg_minbits;
3633: }
3634:
3635: error = ipsec_check_keylen(sup, alg, keylen);
3636: if (error)
3637: plog(LLV_ERROR, LOCATION, NULL,
3638: "%s.\n", ipsec_strerror());
3639:
3640: return error;
3641: }
3642:
3643: /*
3644: * differences with pfkey_recv() in libipsec/pfkey.c:
3645: * - never performs busy wait loop.
3646: * - returns NULL and set *lenp to negative on fatal failures
3647: * - returns NULL and set *lenp to non-negative on non-fatal failures
3648: * - returns non-NULL on success
3649: */
3650: static struct sadb_msg *
3651: pk_recv(so, lenp)
3652: int so;
3653: int *lenp;
3654: {
3655: struct sadb_msg buf, *newmsg;
3656: int reallen;
3657: int retry = 0;
3658:
3659: *lenp = -1;
3660: do
3661: {
3662: plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
3663: *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
3664: retry++;
3665: }
3666: while (*lenp < 0 && errno == EAGAIN && retry < 3);
3667:
3668: if (*lenp < 0)
3669: return NULL; /*fatal*/
3670:
3671: else if (*lenp < sizeof(buf))
3672: return NULL;
3673:
3674: reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
3675: if (reallen < sizeof(buf)) {
3676: *lenp = -1;
3677: errno = EIO;
3678: return NULL; /*fatal*/
3679: }
3680: if ((newmsg = racoon_calloc(1, reallen)) == NULL)
3681: return NULL;
3682:
3683: *lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
3684: if (*lenp < 0) {
3685: racoon_free(newmsg);
3686: return NULL; /*fatal*/
3687: } else if (*lenp != reallen) {
3688: racoon_free(newmsg);
3689: return NULL;
3690: }
3691:
3692: *lenp = recv(so, (caddr_t)newmsg, reallen, 0);
3693: if (*lenp < 0) {
3694: racoon_free(newmsg);
3695: return NULL; /*fatal*/
3696: } else if (*lenp != reallen) {
3697: racoon_free(newmsg);
3698: return NULL;
3699: }
3700:
3701: return newmsg;
3702: }
3703:
3704: /* see handler.h */
3705: u_int32_t
3706: pk_getseq()
3707: {
3708: return eay_random();
3709: }
3710:
3711: static int
3712: addnewsp(mhp, local, remote)
3713: caddr_t *mhp;
3714: struct sockaddr *local, *remote;
3715: {
3716: struct secpolicy *new = NULL;
3717: struct sadb_address *saddr, *daddr;
3718: struct sadb_x_policy *xpl;
3719: struct sadb_lifetime *lt;
3720: u_int64_t created;
3721:
3722: /* sanity check */
3723: if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
3724: || mhp[SADB_EXT_ADDRESS_DST] == NULL
3725: || mhp[SADB_X_EXT_POLICY] == NULL) {
3726: plog(LLV_ERROR, LOCATION, NULL,
3727: "inappropriate sadb spd management message passed.\n");
3728: goto bad;
3729: }
3730:
3731: saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3732: daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3733: xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3734: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3735: if(lt != NULL)
3736: created = lt->sadb_lifetime_addtime;
3737: else
3738: created = 0;
3739: lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3740: if(lt != NULL)
3741: created = lt->sadb_lifetime_addtime;
3742: else
3743: created = 0;
3744:
3745: #ifdef __linux__
3746: /* bsd skips over per-socket policies because there will be no
3747: * src and dst extensions in spddump messages. On Linux the only
3748: * way to achieve the same is check for policy id.
3749: */
3750: if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
3751: #endif
3752:
3753: new = newsp();
3754: if (new == NULL) {
3755: plog(LLV_ERROR, LOCATION, NULL,
3756: "failed to allocate buffer\n");
3757: goto bad;
3758: }
3759:
3760: new->spidx.dir = xpl->sadb_x_policy_dir;
3761: new->id = xpl->sadb_x_policy_id;
3762: new->policy = xpl->sadb_x_policy_type;
3763: new->req = NULL;
3764:
3765: /* check policy */
3766: switch (xpl->sadb_x_policy_type) {
3767: case IPSEC_POLICY_DISCARD:
3768: case IPSEC_POLICY_NONE:
3769: case IPSEC_POLICY_ENTRUST:
3770: case IPSEC_POLICY_BYPASS:
3771: break;
3772:
3773: case IPSEC_POLICY_IPSEC:
3774: {
3775: int tlen;
3776: struct sadb_x_ipsecrequest *xisr;
3777: struct ipsecrequest **p_isr = &new->req;
3778:
3779: /* validity check */
3780: if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3781: plog(LLV_ERROR, LOCATION, NULL,
3782: "invalid msg length.\n");
3783: goto bad;
3784: }
3785:
3786: tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3787: xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
3788:
3789: while (tlen > 0) {
3790:
3791: /* length check */
3792: if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
3793: plog(LLV_ERROR, LOCATION, NULL,
3794: "invalid msg length.\n");
3795: goto bad;
3796: }
3797:
3798: /* allocate request buffer */
3799: *p_isr = newipsecreq();
3800: if (*p_isr == NULL) {
3801: plog(LLV_ERROR, LOCATION, NULL,
3802: "failed to get new ipsecreq.\n");
3803: goto bad;
3804: }
3805:
3806: /* set values */
3807: (*p_isr)->next = NULL;
3808:
3809: switch (xisr->sadb_x_ipsecrequest_proto) {
3810: case IPPROTO_ESP:
3811: case IPPROTO_AH:
3812: case IPPROTO_IPCOMP:
3813: break;
3814: default:
3815: plog(LLV_ERROR, LOCATION, NULL,
3816: "invalid proto type: %u\n",
3817: xisr->sadb_x_ipsecrequest_proto);
3818: goto bad;
3819: }
3820: (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
3821:
3822: switch (xisr->sadb_x_ipsecrequest_mode) {
3823: case IPSEC_MODE_TRANSPORT:
3824: case IPSEC_MODE_TUNNEL:
3825: break;
3826: case IPSEC_MODE_ANY:
3827: default:
3828: plog(LLV_ERROR, LOCATION, NULL,
3829: "invalid mode: %u\n",
3830: xisr->sadb_x_ipsecrequest_mode);
3831: goto bad;
3832: }
3833: (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
3834:
3835: switch (xisr->sadb_x_ipsecrequest_level) {
3836: case IPSEC_LEVEL_DEFAULT:
3837: case IPSEC_LEVEL_USE:
3838: case IPSEC_LEVEL_REQUIRE:
3839: break;
3840: case IPSEC_LEVEL_UNIQUE:
3841: (*p_isr)->saidx.reqid =
3842: xisr->sadb_x_ipsecrequest_reqid;
3843: break;
3844:
3845: default:
3846: plog(LLV_ERROR, LOCATION, NULL,
3847: "invalid level: %u\n",
3848: xisr->sadb_x_ipsecrequest_level);
3849: goto bad;
3850: }
3851: (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
3852:
3853: /* set IP addresses if there */
3854: if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
3855: struct sockaddr *paddr;
3856:
3857: paddr = (struct sockaddr *)(xisr + 1);
3858: bcopy(paddr, &(*p_isr)->saidx.src,
3859: sysdep_sa_len(paddr));
3860:
3861: paddr = (struct sockaddr *)((caddr_t)paddr
3862: + sysdep_sa_len(paddr));
3863: bcopy(paddr, &(*p_isr)->saidx.dst,
3864: sysdep_sa_len(paddr));
3865: }
3866:
3867: (*p_isr)->sp = new;
3868:
3869: /* initialization for the next. */
3870: p_isr = &(*p_isr)->next;
3871: tlen -= xisr->sadb_x_ipsecrequest_len;
3872:
3873: /* validity check */
3874: if (tlen < 0) {
3875: plog(LLV_ERROR, LOCATION, NULL,
3876: "becoming tlen < 0\n");
3877: }
3878:
3879: xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
3880: + xisr->sadb_x_ipsecrequest_len);
3881: }
3882: }
3883: break;
3884: default:
3885: plog(LLV_ERROR, LOCATION, NULL,
3886: "invalid policy type.\n");
3887: goto bad;
3888: }
3889:
3890: #ifdef HAVE_PFKEY_POLICY_PRIORITY
3891: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3892: saddr + 1,
3893: daddr + 1,
3894: saddr->sadb_address_prefixlen,
3895: daddr->sadb_address_prefixlen,
3896: saddr->sadb_address_proto,
3897: xpl->sadb_x_policy_priority,
3898: created,
3899: &new->spidx);
3900: #else
3901: KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3902: saddr + 1,
3903: daddr + 1,
3904: saddr->sadb_address_prefixlen,
3905: daddr->sadb_address_prefixlen,
3906: saddr->sadb_address_proto,
3907: created,
3908: &new->spidx);
3909: #endif
3910:
3911: #ifdef HAVE_SECCTX
3912: if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
3913: struct sadb_x_sec_ctx *ctx;
3914:
3915: ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
3916: new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
3917: new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
3918: new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
3919: memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
3920: }
3921: #endif /* HAVE_SECCTX */
3922:
3923: /* Set local and remote hints for that SP, if available */
3924: if (local && remote) {
3925: new->local = dupsaddr(local);
3926: new->remote = dupsaddr(remote);
3927: }
3928:
3929: inssp(new);
3930:
3931: return 0;
3932: bad:
3933: if (new != NULL) {
3934: if (new->req != NULL)
3935: racoon_free(new->req);
3936: racoon_free(new);
3937: }
3938: return -1;
3939: }
3940:
3941: /* proto/mode/src->dst spi */
3942: const char *
3943: sadbsecas2str(src, dst, proto, spi, mode)
3944: struct sockaddr *src, *dst;
3945: int proto;
3946: u_int32_t spi;
3947: int mode;
3948: {
3949: static char buf[256];
3950: u_int doi_proto, doi_mode = 0;
3951: char *p;
3952: int blen, i;
3953:
3954: doi_proto = pfkey2ipsecdoi_proto(proto);
3955: if (doi_proto == ~0)
3956: return NULL;
3957: if (mode) {
3958: doi_mode = pfkey2ipsecdoi_mode(mode);
3959: if (doi_mode == ~0)
3960: return NULL;
3961: }
3962:
3963: blen = sizeof(buf) - 1;
3964: p = buf;
3965:
3966: i = snprintf(p, blen, "%s%s%s ",
3967: s_ipsecdoi_proto(doi_proto),
3968: mode ? "/" : "",
3969: mode ? s_ipsecdoi_encmode(doi_mode) : "");
3970: if (i < 0 || i >= blen)
3971: return NULL;
3972: p += i;
3973: blen -= i;
3974:
3975: i = snprintf(p, blen, "%s->", saddr2str(src));
3976: if (i < 0 || i >= blen)
3977: return NULL;
3978: p += i;
3979: blen -= i;
3980:
3981: i = snprintf(p, blen, "%s ", saddr2str(dst));
3982: if (i < 0 || i >= blen)
3983: return NULL;
3984: p += i;
3985: blen -= i;
3986:
3987: if (spi) {
3988: snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3989: (unsigned long)ntohl(spi));
3990: }
3991:
3992: return buf;
3993: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>