working version with crypto
[anytun.git] / keyexchange / isakmpd-20041012 / policy.c
blob279b3a18867af25d4dcf0238fcf25373334d68a3
1 /* $OpenBSD: policy.c,v 1.78 2004/08/08 19:11:06 deraadt Exp $ */
2 /* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
4 /*
5 * Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved.
6 * Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
7 * Copyright (c) 2001 HÃ¥kan Olsson. All rights reserved.
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.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * This code was written under funding by Ericsson Radio Systems.
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/mman.h>
37 #include <sys/queue.h>
38 #include <sys/stat.h>
39 #include <regex.h>
40 #include <ctype.h>
41 #include <fcntl.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 #include <keynote.h>
47 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50 #include <errno.h>
51 #include <openssl/ssl.h>
52 #include <netdb.h>
54 #include "sysdep.h"
56 #include "conf.h"
57 #include "exchange.h"
58 #include "ipsec.h"
59 #include "isakmp_doi.h"
60 #include "sa.h"
61 #include "transport.h"
62 #include "log.h"
63 #include "message.h"
64 #include "monitor.h"
65 #include "util.h"
66 #include "policy.h"
67 #include "x509.h"
69 char **policy_asserts = NULL;
70 int ignore_policy = 0;
71 int policy_asserts_num = 0;
72 struct exchange *policy_exchange = 0;
73 struct sa *policy_sa = 0;
74 struct sa *policy_isakmp_sa = 0;
76 static const char hextab[] = {
77 '0', '1', '2', '3', '4', '5', '6', '7',
78 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
82 * Adaptation of Vixie's inet_ntop4 ()
84 static const char *
85 my_inet_ntop4(const in_addr_t *src, char *dst, size_t size, int normalize)
87 static const char fmt[] = "%03u.%03u.%03u.%03u";
88 char tmp[sizeof "255.255.255.255"];
89 in_addr_t src2;
91 if (normalize)
92 src2 = ntohl(*src);
93 else
94 src2 = *src;
96 if (snprintf(tmp, sizeof tmp, fmt, ((u_int8_t *)&src2)[0],
97 ((u_int8_t *)&src2)[1], ((u_int8_t *)&src2)[2],
98 ((u_int8_t *)&src2)[3]) > (int)size) {
99 errno = ENOSPC;
100 return 0;
102 strlcpy(dst, tmp, size);
103 return dst;
106 static const char *
107 my_inet_ntop6(const unsigned char *src, char *dst, size_t size)
109 static const char fmt[] =
110 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x";
111 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
113 if (snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3],
114 src[4], src[5], src[6], src[7], src[8], src[9], src[10], src[11],
115 src[12], src[13], src[14], src[15]) > (int)size) {
116 errno = ENOSPC;
117 return 0;
119 strlcpy(dst, tmp, size);
120 return dst;
123 char *
124 policy_callback(char *name)
126 struct proto *proto;
128 u_int8_t *attr, *value, *id, *idlocal, *idremote;
129 size_t id_sz, idlocalsz, idremotesz;
130 struct sockaddr *sin;
131 struct ipsec_exch *ie;
132 struct ipsec_sa *is;
133 size_t i;
134 int fmt, lifetype = 0;
135 in_addr_t net, subnet;
136 u_int16_t len, type;
137 time_t tt;
138 char *addr;
139 static char mytimeofday[15];
141 /* We use all these as a cache. */
142 #define PMAX 32
143 static char *esp_present, *ah_present, *comp_present;
144 static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
145 static char *comp_alg, ah_life_kbytes[PMAX], ah_life_seconds[PMAX];
146 static char esp_life_kbytes[PMAX], esp_life_seconds[PMAX];
147 static char comp_life_kbytes[PMAX];
148 static char *ah_ecn, *esp_ecn, *comp_ecn;
149 static char comp_life_seconds[PMAX], *ah_encapsulation;
150 static char *esp_encapsulation, *comp_encapsulation;
151 static char ah_key_length[PMAX], esp_key_length[PMAX];
152 static char ah_key_rounds[PMAX], esp_key_rounds[PMAX];
153 static char comp_dict_size[PMAX], comp_private_alg[PMAX];
154 static char *remote_filter_type, *local_filter_type;
155 static char remote_filter_addr_upper[NI_MAXHOST];
156 static char remote_filter_addr_lower[NI_MAXHOST];
157 static char local_filter_addr_upper[NI_MAXHOST];
158 static char local_filter_addr_lower[NI_MAXHOST];
159 static char ah_group_desc[PMAX], esp_group_desc[PMAX];
160 static char comp_group_desc[PMAX], remote_ike_address[NI_MAXHOST];
161 static char local_ike_address[NI_MAXHOST];
162 static char *remote_id_type, remote_id_addr_upper[NI_MAXHOST];
163 static char *phase_1, remote_id_addr_lower[NI_MAXHOST];
164 static char *remote_id_proto, remote_id_port[PMAX];
165 static char remote_filter_port[PMAX], local_filter_port[PMAX];
166 static char *remote_filter_proto, *local_filter_proto, *pfs;
167 static char *initiator, remote_filter_proto_num[3];
168 static char local_filter_proto_num[3], remote_id_proto_num[3];
169 static char phase1_group[PMAX];
171 /* Allocated. */
172 static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
174 static int dirty = 1;
176 /* We only need to set dirty at initialization time really. */
177 if (strcmp(name, KEYNOTE_CALLBACK_CLEANUP) == 0
178 || strcmp(name, KEYNOTE_CALLBACK_INITIALIZE) == 0) {
179 esp_present = ah_present = comp_present = pfs = "no";
180 ah_hash_alg = ah_auth_alg = phase_1 = "";
181 esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
182 ah_ecn = esp_ecn = comp_ecn = "no";
183 esp_encapsulation = comp_encapsulation = "";
184 remote_filter_type = "";
185 local_filter_type = remote_id_type = initiator = "";
186 remote_filter_proto = local_filter_proto = "";
187 remote_id_proto = "";
189 if (remote_filter != 0) {
190 free(remote_filter);
191 remote_filter = 0;
193 if (local_filter != 0) {
194 free(local_filter);
195 local_filter = 0;
197 if (remote_id != 0) {
198 free(remote_id);
199 remote_id = 0;
201 memset(remote_ike_address, 0, sizeof remote_ike_address);
202 memset(local_ike_address, 0, sizeof local_ike_address);
203 memset(ah_life_kbytes, 0, sizeof ah_life_kbytes);
204 memset(ah_life_seconds, 0, sizeof ah_life_seconds);
205 memset(esp_life_kbytes, 0, sizeof esp_life_kbytes);
206 memset(esp_life_seconds, 0, sizeof esp_life_seconds);
207 memset(comp_life_kbytes, 0, sizeof comp_life_kbytes);
208 memset(comp_life_seconds, 0, sizeof comp_life_seconds);
209 memset(ah_key_length, 0, sizeof ah_key_length);
210 memset(ah_key_rounds, 0, sizeof ah_key_rounds);
211 memset(esp_key_length, 0, sizeof esp_key_length);
212 memset(esp_key_rounds, 0, sizeof esp_key_rounds);
213 memset(comp_dict_size, 0, sizeof comp_dict_size);
214 memset(comp_private_alg, 0, sizeof comp_private_alg);
215 memset(remote_filter_addr_upper, 0,
216 sizeof remote_filter_addr_upper);
217 memset(remote_filter_addr_lower, 0,
218 sizeof remote_filter_addr_lower);
219 memset(local_filter_addr_upper, 0,
220 sizeof local_filter_addr_upper);
221 memset(local_filter_addr_lower, 0,
222 sizeof local_filter_addr_lower);
223 memset(remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
224 memset(remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
225 memset(ah_group_desc, 0, sizeof ah_group_desc);
226 memset(esp_group_desc, 0, sizeof esp_group_desc);
227 memset(remote_id_port, 0, sizeof remote_id_port);
228 memset(remote_filter_port, 0, sizeof remote_filter_port);
229 memset(local_filter_port, 0, sizeof local_filter_port);
230 memset(phase1_group, 0, sizeof phase1_group);
232 dirty = 1;
233 return "";
236 * If dirty is set, this is the first request for an attribute, so
237 * populate our value cache.
239 if (dirty) {
240 ie = policy_exchange->data;
242 if (ie->pfs)
243 pfs = "yes";
245 is = policy_isakmp_sa->data;
246 snprintf(phase1_group, sizeof phase1_group, "%u",
247 is->group_desc);
249 for (proto = TAILQ_FIRST(&policy_sa->protos); proto;
250 proto = TAILQ_NEXT(proto, link)) {
251 switch (proto->proto) {
252 case IPSEC_PROTO_IPSEC_AH:
253 ah_present = "yes";
254 switch (proto->id) {
255 case IPSEC_AH_MD5:
256 ah_hash_alg = "md5";
257 break;
259 case IPSEC_AH_SHA:
260 ah_hash_alg = "sha";
261 break;
263 case IPSEC_AH_RIPEMD:
264 ah_hash_alg = "ripemd";
265 break;
267 case IPSEC_AH_SHA2_256:
268 ah_auth_alg = "sha2-256";
269 break;
271 case IPSEC_AH_SHA2_384:
272 ah_auth_alg = "sha2-384";
273 break;
275 case IPSEC_AH_SHA2_512:
276 ah_auth_alg = "sha2-512";
277 break;
279 case IPSEC_AH_DES:
280 ah_hash_alg = "des";
281 break;
284 break;
286 case IPSEC_PROTO_IPSEC_ESP:
287 esp_present = "yes";
288 switch (proto->id) {
289 case IPSEC_ESP_DES_IV64:
290 esp_enc_alg = "des-iv64";
291 break;
293 case IPSEC_ESP_DES:
294 esp_enc_alg = "des";
295 break;
297 case IPSEC_ESP_3DES:
298 esp_enc_alg = "3des";
299 break;
301 case IPSEC_ESP_AES:
302 case IPSEC_ESP_AES_128_CTR:
303 esp_enc_alg = "aes";
304 break;
306 case IPSEC_ESP_RC5:
307 esp_enc_alg = "rc5";
308 break;
310 case IPSEC_ESP_IDEA:
311 esp_enc_alg = "idea";
312 break;
314 case IPSEC_ESP_CAST:
315 esp_enc_alg = "cast";
316 break;
318 case IPSEC_ESP_BLOWFISH:
319 esp_enc_alg = "blowfish";
320 break;
322 case IPSEC_ESP_3IDEA:
323 esp_enc_alg = "3idea";
324 break;
326 case IPSEC_ESP_DES_IV32:
327 esp_enc_alg = "des-iv32";
328 break;
330 case IPSEC_ESP_RC4:
331 esp_enc_alg = "rc4";
332 break;
334 case IPSEC_ESP_NULL:
335 esp_enc_alg = "null";
336 break;
339 break;
341 case IPSEC_PROTO_IPCOMP:
342 comp_present = "yes";
343 switch (proto->id) {
344 case IPSEC_IPCOMP_OUI:
345 comp_alg = "oui";
346 break;
348 case IPSEC_IPCOMP_DEFLATE:
349 comp_alg = "deflate";
350 break;
352 case IPSEC_IPCOMP_LZS:
353 comp_alg = "lzs";
354 break;
356 case IPSEC_IPCOMP_V42BIS:
357 comp_alg = "v42bis";
358 break;
361 break;
364 for (attr = proto->chosen->p +
365 ISAKMP_TRANSFORM_SA_ATTRS_OFF;
366 attr < proto->chosen->p +
367 GET_ISAKMP_GEN_LENGTH(proto->chosen->p);
368 attr = value + len) {
369 if (attr + ISAKMP_ATTR_VALUE_OFF >
370 (proto->chosen->p +
371 GET_ISAKMP_GEN_LENGTH(proto->chosen->p)))
372 return "";
374 type = GET_ISAKMP_ATTR_TYPE(attr);
375 fmt = ISAKMP_ATTR_FORMAT(type);
376 type = ISAKMP_ATTR_TYPE(type);
377 value = attr + (fmt ?
378 ISAKMP_ATTR_LENGTH_VALUE_OFF :
379 ISAKMP_ATTR_VALUE_OFF);
380 len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
381 GET_ISAKMP_ATTR_LENGTH_VALUE(attr));
383 if (value + len > proto->chosen->p +
384 GET_ISAKMP_GEN_LENGTH(proto->chosen->p))
385 return "";
387 switch (type) {
388 case IPSEC_ATTR_SA_LIFE_TYPE:
389 lifetype = decode_16(value);
390 break;
392 case IPSEC_ATTR_SA_LIFE_DURATION:
393 switch (proto->proto) {
394 case IPSEC_PROTO_IPSEC_AH:
395 if (lifetype == IPSEC_DURATION_SECONDS) {
396 if (len == 2)
397 snprintf(ah_life_seconds, sizeof ah_life_seconds,
398 "%u", decode_16(value));
399 else
400 snprintf(ah_life_seconds, sizeof ah_life_seconds,
401 "%u", decode_32(value));
402 } else {
403 if (len == 2)
404 snprintf(ah_life_kbytes, sizeof ah_life_kbytes,
405 "%u", decode_16(value));
406 else
407 snprintf(ah_life_kbytes, sizeof ah_life_kbytes,
408 "%u", decode_32(value));
411 break;
413 case IPSEC_PROTO_IPSEC_ESP:
414 if (lifetype == IPSEC_DURATION_SECONDS) {
415 if (len == 2)
416 snprintf(esp_life_seconds,
417 sizeof esp_life_seconds, "%u",
418 decode_16(value));
419 else
420 snprintf(esp_life_seconds,
421 sizeof esp_life_seconds, "%u",
422 decode_32(value));
423 } else {
424 if (len == 2)
425 snprintf(esp_life_kbytes,
426 sizeof esp_life_kbytes, "%u",
427 decode_16(value));
428 else
429 snprintf(esp_life_kbytes,
430 sizeof esp_life_kbytes, "%u",
431 decode_32(value));
434 break;
436 case IPSEC_PROTO_IPCOMP:
437 if (lifetype == IPSEC_DURATION_SECONDS) {
438 if (len == 2)
439 snprintf(comp_life_seconds,
440 sizeof comp_life_seconds, "%u",
441 decode_16(value));
442 else
443 snprintf(comp_life_seconds,
444 sizeof comp_life_seconds, "%u",
445 decode_32(value));
446 } else {
447 if (len == 2)
448 snprintf(comp_life_kbytes,
449 sizeof comp_life_kbytes, "%u",
450 decode_16(value));
451 else
452 snprintf(comp_life_kbytes,
453 sizeof comp_life_kbytes, "%u",
454 decode_32(value));
456 break;
458 break;
460 case IPSEC_ATTR_GROUP_DESCRIPTION:
461 switch (proto->proto) {
462 case IPSEC_PROTO_IPSEC_AH:
463 snprintf(ah_group_desc,
464 sizeof ah_group_desc, "%u",
465 decode_16(value));
466 break;
468 case IPSEC_PROTO_IPSEC_ESP:
469 snprintf(esp_group_desc,
470 sizeof esp_group_desc, "%u",
471 decode_16(value));
472 break;
474 case IPSEC_PROTO_IPCOMP:
475 snprintf(comp_group_desc,
476 sizeof comp_group_desc, "%u",
477 decode_16(value));
478 break;
480 break;
482 case IPSEC_ATTR_ECN_TUNNEL:
483 if (decode_16(value))
484 switch (proto->proto) {
485 case IPSEC_PROTO_IPSEC_AH:
486 ah_ecn = "yes";
487 break;
489 case IPSEC_PROTO_IPSEC_ESP:
490 esp_ecn = "yes";
491 break;
493 case IPSEC_PROTO_IPCOMP:
494 comp_ecn = "yes";
495 break;
498 case IPSEC_ATTR_ENCAPSULATION_MODE:
499 if (decode_16(value) == IPSEC_ENCAP_TUNNEL)
500 switch (proto->proto) {
501 case IPSEC_PROTO_IPSEC_AH:
502 ah_encapsulation = "tunnel";
503 break;
505 case IPSEC_PROTO_IPSEC_ESP:
506 esp_encapsulation = "tunnel";
507 break;
509 case IPSEC_PROTO_IPCOMP:
510 comp_encapsulation = "tunnel";
511 break;
513 #if defined (USE_NAT_TRAVERSAL)
514 else if (decode_16(value) ==
515 IPSEC_ENCAP_UDP_ENCAP_TUNNEL ||
516 decode_16(value) ==
517 IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT)
518 switch (proto->proto) {
519 case IPSEC_PROTO_IPSEC_AH:
520 ah_encapsulation = "udp-encap-tunnel";
521 break;
523 case IPSEC_PROTO_IPSEC_ESP:
524 esp_encapsulation = "udp-encap-tunnel";
525 break;
527 case IPSEC_PROTO_IPCOMP:
528 comp_encapsulation = "udp-encap-tunnel";
529 break;
531 /* XXX IPSEC_ENCAP_UDP_ENCAP_TRANSPORT */
532 #endif
533 else
534 switch (proto->proto) {
535 case IPSEC_PROTO_IPSEC_AH:
536 ah_encapsulation = "transport";
537 break;
539 case IPSEC_PROTO_IPSEC_ESP:
540 esp_encapsulation = "transport";
541 break;
543 case IPSEC_PROTO_IPCOMP:
544 comp_encapsulation = "transport";
545 break;
547 break;
549 case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
550 switch (proto->proto) {
551 case IPSEC_PROTO_IPSEC_AH:
552 switch (decode_16(value)) {
553 case IPSEC_AUTH_HMAC_MD5:
554 ah_auth_alg = "hmac-md5";
555 break;
557 case IPSEC_AUTH_HMAC_SHA:
558 ah_auth_alg = "hmac-sha";
559 break;
561 case IPSEC_AUTH_HMAC_RIPEMD:
562 ah_auth_alg = "hmac-ripemd";
563 break;
565 case IPSEC_AUTH_HMAC_SHA2_256:
566 ah_auth_alg = "hmac-sha2-256";
567 break;
569 case IPSEC_AUTH_HMAC_SHA2_384:
570 ah_auth_alg = "hmac-sha2-384";
571 break;
573 case IPSEC_AUTH_HMAC_SHA2_512:
574 ah_auth_alg = "hmac-sha2-512";
575 break;
577 case IPSEC_AUTH_DES_MAC:
578 ah_auth_alg = "des-mac";
579 break;
581 case IPSEC_AUTH_KPDK:
582 ah_auth_alg = "kpdk";
583 break;
585 break;
587 case IPSEC_PROTO_IPSEC_ESP:
588 switch (decode_16(value)) {
589 case IPSEC_AUTH_HMAC_MD5:
590 esp_auth_alg = "hmac-md5";
591 break;
593 case IPSEC_AUTH_HMAC_SHA:
594 esp_auth_alg = "hmac-sha";
595 break;
597 case IPSEC_AUTH_HMAC_RIPEMD:
598 esp_auth_alg = "hmac-ripemd";
599 break;
601 case IPSEC_AUTH_HMAC_SHA2_256:
602 esp_auth_alg = "hmac-sha2-256";
603 break;
605 case IPSEC_AUTH_HMAC_SHA2_384:
606 esp_auth_alg = "hmac-sha2-384";
607 break;
609 case IPSEC_AUTH_HMAC_SHA2_512:
610 esp_auth_alg = "hmac-sha2-512";
611 break;
613 case IPSEC_AUTH_DES_MAC:
614 esp_auth_alg = "des-mac";
615 break;
617 case IPSEC_AUTH_KPDK:
618 esp_auth_alg = "kpdk";
619 break;
621 break;
623 break;
625 case IPSEC_ATTR_KEY_LENGTH:
626 switch (proto->proto) {
627 case IPSEC_PROTO_IPSEC_AH:
628 snprintf(ah_key_length,
629 sizeof ah_key_length, "%u",
630 decode_16(value));
631 break;
633 case IPSEC_PROTO_IPSEC_ESP:
634 snprintf(esp_key_length,
635 sizeof esp_key_length, "%u",
636 decode_16(value));
637 break;
639 break;
641 case IPSEC_ATTR_KEY_ROUNDS:
642 switch (proto->proto) {
643 case IPSEC_PROTO_IPSEC_AH:
644 snprintf(ah_key_rounds,
645 sizeof ah_key_rounds, "%u",
646 decode_16(value));
647 break;
649 case IPSEC_PROTO_IPSEC_ESP:
650 snprintf(esp_key_rounds,
651 sizeof esp_key_rounds, "%u",
652 decode_16(value));
653 break;
655 break;
657 case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
658 snprintf(comp_dict_size,
659 sizeof comp_dict_size, "%u",
660 decode_16(value));
661 break;
663 case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
664 snprintf(comp_private_alg,
665 sizeof comp_private_alg, "%u",
666 decode_16(value));
667 break;
672 policy_sa->transport->vtbl->get_src(policy_sa->transport,
673 &sin);
674 if (sockaddr2text(sin, &addr, 1)) {
675 log_error("policy_callback: sockaddr2text failed");
676 goto bad;
678 strlcpy(local_ike_address, addr, sizeof local_ike_address);
679 free(addr);
681 policy_sa->transport->vtbl->get_dst(policy_sa->transport,
682 &sin);
683 if (sockaddr2text(sin, &addr, 1)) {
684 log_error("policy_callback: sockaddr2text failed");
685 goto bad;
687 strlcpy(remote_ike_address, addr, sizeof remote_ike_address);
688 free(addr);
690 switch (policy_isakmp_sa->exch_type) {
691 case ISAKMP_EXCH_AGGRESSIVE:
692 phase_1 = "aggressive";
693 break;
695 case ISAKMP_EXCH_ID_PROT:
696 phase_1 = "main";
697 break;
700 if (policy_isakmp_sa->initiator) {
701 id = policy_isakmp_sa->id_r;
702 id_sz = policy_isakmp_sa->id_r_len;
703 } else {
704 id = policy_isakmp_sa->id_i;
705 id_sz = policy_isakmp_sa->id_i_len;
708 switch (id[0]) {
709 case IPSEC_ID_IPV4_ADDR:
710 remote_id_type = "IPv4 address";
712 net = decode_32(id + ISAKMP_ID_DATA_OFF -
713 ISAKMP_GEN_SZ);
714 my_inet_ntop4(&net, remote_id_addr_upper,
715 sizeof remote_id_addr_upper - 1, 1);
716 my_inet_ntop4(&net, remote_id_addr_lower,
717 sizeof remote_id_addr_lower - 1, 1);
718 remote_id = strdup(remote_id_addr_upper);
719 if (!remote_id) {
720 log_error("policy_callback: "
721 "strdup (\"%s\") failed",
722 remote_id_addr_upper);
723 goto bad;
725 break;
727 case IPSEC_ID_IPV4_RANGE:
728 remote_id_type = "IPv4 range";
730 net = decode_32(id + ISAKMP_ID_DATA_OFF -
731 ISAKMP_GEN_SZ);
732 my_inet_ntop4(&net, remote_id_addr_lower,
733 sizeof remote_id_addr_lower - 1, 1);
734 net = decode_32(id + ISAKMP_ID_DATA_OFF -
735 ISAKMP_GEN_SZ + 4);
736 my_inet_ntop4(&net, remote_id_addr_upper,
737 sizeof remote_id_addr_upper - 1, 1);
738 len = strlen(remote_id_addr_upper) +
739 strlen(remote_id_addr_lower) + 2;
740 remote_id = calloc(len, sizeof(char));
741 if (!remote_id) {
742 log_error("policy_callback: "
743 "calloc (%d, %lu) failed", len,
744 (unsigned long)sizeof(char));
745 goto bad;
747 strlcpy(remote_id, remote_id_addr_lower, len);
748 strlcat(remote_id, "-", len);
749 strlcat(remote_id, remote_id_addr_upper, len);
750 break;
752 case IPSEC_ID_IPV4_ADDR_SUBNET:
753 remote_id_type = "IPv4 subnet";
755 net = decode_32(id + ISAKMP_ID_DATA_OFF -
756 ISAKMP_GEN_SZ);
757 subnet = decode_32(id + ISAKMP_ID_DATA_OFF -
758 ISAKMP_GEN_SZ + 4);
759 net &= subnet;
760 my_inet_ntop4(&net, remote_id_addr_lower,
761 sizeof remote_id_addr_lower - 1, 1);
762 net |= ~subnet;
763 my_inet_ntop4(&net, remote_id_addr_upper,
764 sizeof remote_id_addr_upper - 1, 1);
765 len = strlen(remote_id_addr_upper) +
766 strlen(remote_id_addr_lower) + 2;
767 remote_id = calloc(len, sizeof(char));
768 if (!remote_id) {
769 log_error("policy_callback: "
770 "calloc (%d, %lu) failed", len,
771 (unsigned long)sizeof(char));
772 goto bad;
774 strlcpy(remote_id, remote_id_addr_lower, len);
775 strlcat(remote_id, "-", len);
776 strlcat(remote_id, remote_id_addr_upper, len);
777 break;
779 case IPSEC_ID_IPV6_ADDR:
780 remote_id_type = "IPv6 address";
781 my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
782 remote_id_addr_upper, sizeof remote_id_addr_upper);
783 strlcpy(remote_id_addr_lower, remote_id_addr_upper,
784 sizeof remote_id_addr_lower);
785 remote_id = strdup(remote_id_addr_upper);
786 if (!remote_id) {
787 log_error("policy_callback: "
788 "strdup (\"%s\") failed",
789 remote_id_addr_upper);
790 goto bad;
792 break;
794 case IPSEC_ID_IPV6_RANGE:
795 remote_id_type = "IPv6 range";
797 my_inet_ntop6(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
798 remote_id_addr_lower,
799 sizeof remote_id_addr_lower - 1);
801 my_inet_ntop6(id + ISAKMP_ID_DATA_OFF -
802 ISAKMP_GEN_SZ + 16, remote_id_addr_upper,
803 sizeof remote_id_addr_upper - 1);
805 len = strlen(remote_id_addr_upper) +
806 strlen(remote_id_addr_lower) + 2;
807 remote_id = calloc(len, sizeof(char));
808 if (!remote_id) {
809 log_error("policy_callback: "
810 "calloc (%d, %lu) failed", len,
811 (unsigned long)sizeof(char));
812 goto bad;
814 strlcpy(remote_id, remote_id_addr_lower, len);
815 strlcat(remote_id, "-", len);
816 strlcat(remote_id, remote_id_addr_upper, len);
817 break;
819 case IPSEC_ID_IPV6_ADDR_SUBNET:
821 struct in6_addr net, mask;
823 remote_id_type = "IPv6 subnet";
825 bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, &net,
826 sizeof(net));
827 bcopy(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16,
828 &mask, sizeof(mask));
830 for (i = 0; i < 16; i++)
831 net.s6_addr[i] &= mask.s6_addr[i];
833 my_inet_ntop6((unsigned char *)&net,
834 remote_id_addr_lower,
835 sizeof remote_id_addr_lower - 1);
837 for (i = 0; i < 16; i++)
838 net.s6_addr[i] |= ~mask.s6_addr[i];
840 my_inet_ntop6((unsigned char *)&net,
841 remote_id_addr_upper,
842 sizeof remote_id_addr_upper - 1);
844 len = strlen(remote_id_addr_upper) +
845 strlen(remote_id_addr_lower) + 2;
846 remote_id = calloc(len, sizeof(char));
847 if (!remote_id) {
848 log_error("policy_callback: "
849 "calloc (%d, %lu) failed", len,
850 (unsigned long)sizeof(char));
851 goto bad;
853 strlcpy(remote_id, remote_id_addr_lower, len);
854 strlcat(remote_id, "-", len);
855 strlcat(remote_id, remote_id_addr_upper, len);
856 break;
859 case IPSEC_ID_FQDN:
860 remote_id_type = "FQDN";
861 remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF +
862 ISAKMP_GEN_SZ + 1, sizeof(char));
863 if (!remote_id) {
864 log_error("policy_callback: "
865 "calloc (%lu, %lu) failed",
866 (unsigned long)id_sz - ISAKMP_ID_DATA_OFF +
867 ISAKMP_GEN_SZ + 1,
868 (unsigned long)sizeof(char));
869 goto bad;
871 memcpy(remote_id,
872 id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
873 id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
874 break;
876 case IPSEC_ID_USER_FQDN:
877 remote_id_type = "User FQDN";
878 remote_id = calloc(id_sz - ISAKMP_ID_DATA_OFF +
879 ISAKMP_GEN_SZ + 1, sizeof(char));
880 if (!remote_id) {
881 log_error("policy_callback: "
882 "calloc (%lu, %lu) failed",
883 (unsigned long)id_sz - ISAKMP_ID_DATA_OFF +
884 ISAKMP_GEN_SZ + 1,
885 (unsigned long)sizeof(char));
886 goto bad;
888 memcpy(remote_id,
889 id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
890 id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
891 break;
893 case IPSEC_ID_DER_ASN1_DN:
894 remote_id_type = "ASN1 DN";
896 remote_id = x509_DN_string(id + ISAKMP_ID_DATA_OFF -
897 ISAKMP_GEN_SZ,
898 id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
899 if (!remote_id) {
900 LOG_DBG((LOG_POLICY, 50,
901 "policy_callback: failed to decode name"));
902 goto bad;
904 break;
906 case IPSEC_ID_DER_ASN1_GN: /* XXX */
907 remote_id_type = "ASN1 GN";
908 break;
910 case IPSEC_ID_KEY_ID:
911 remote_id_type = "Key ID";
912 remote_id = calloc(2 * (id_sz - ISAKMP_ID_DATA_OFF +
913 ISAKMP_GEN_SZ) + 1, sizeof(char));
914 if (!remote_id) {
915 log_error("policy_callback: "
916 "calloc (%lu, %lu) failed",
917 2 * ((unsigned long)id_sz -
918 ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
919 (unsigned long)sizeof(char));
920 goto bad;
922 /* Does it contain any non-printable characters ? */
923 for (i = 0;
924 i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
925 i++)
926 if (!isprint(*(id + ISAKMP_ID_DATA_OFF -
927 ISAKMP_GEN_SZ + i)))
928 break;
929 if (i >= id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) {
930 memcpy(remote_id, id + ISAKMP_ID_DATA_OFF -
931 ISAKMP_GEN_SZ,
932 id_sz - ISAKMP_ID_DATA_OFF +
933 ISAKMP_GEN_SZ);
934 break;
936 /* Non-printable characters, convert to hex */
937 for (i = 0;
938 i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ;
939 i++) {
940 remote_id[2 * i] = hextab[*(id +
941 ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4];
942 remote_id[2 * i + 1] = hextab[*(id +
943 ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF];
945 break;
947 default:
948 log_print("policy_callback: "
949 "unknown remote ID type %u", id[0]);
950 goto bad;
953 switch (id[1]) {
954 case IPPROTO_TCP:
955 remote_id_proto = "tcp";
956 break;
958 case IPPROTO_UDP:
959 remote_id_proto = "udp";
960 break;
962 #ifdef IPPROTO_ETHERIP
963 case IPPROTO_ETHERIP:
964 remote_id_proto = "etherip";
965 break;
966 #endif
968 default:
969 snprintf(remote_id_proto_num,
970 sizeof remote_id_proto_num, "%d",
971 id[1]);
972 remote_id_proto = remote_id_proto_num;
973 break;
976 snprintf(remote_id_port, sizeof remote_id_port, "%u",
977 decode_16(id + 2));
979 if (policy_exchange->initiator) {
980 initiator = "yes";
981 idlocal = ie->id_ci;
982 idremote = ie->id_cr;
983 idlocalsz = ie->id_ci_sz;
984 idremotesz = ie->id_cr_sz;
985 } else {
986 initiator = "no";
987 idlocal = ie->id_cr;
988 idremote = ie->id_ci;
989 idlocalsz = ie->id_cr_sz;
990 idremotesz = ie->id_ci_sz;
993 /* Initialize the ID variables. */
994 if (idremote) {
995 switch (GET_ISAKMP_ID_TYPE(idremote)) {
996 case IPSEC_ID_IPV4_ADDR:
997 remote_filter_type = "IPv4 address";
999 net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
1000 my_inet_ntop4(&net, remote_filter_addr_upper,
1001 sizeof remote_filter_addr_upper - 1, 1);
1002 my_inet_ntop4(&net, remote_filter_addr_lower,
1003 sizeof remote_filter_addr_lower - 1, 1);
1004 remote_filter =
1005 strdup(remote_filter_addr_upper);
1006 if (!remote_filter) {
1007 log_error("policy_callback: strdup "
1008 "(\"%s\") failed",
1009 remote_filter_addr_upper);
1010 goto bad;
1012 break;
1014 case IPSEC_ID_IPV4_RANGE:
1015 remote_filter_type = "IPv4 range";
1017 net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
1018 my_inet_ntop4(&net, remote_filter_addr_lower,
1019 sizeof remote_filter_addr_lower - 1, 1);
1020 net = decode_32(idremote + ISAKMP_ID_DATA_OFF +
1022 my_inet_ntop4(&net, remote_filter_addr_upper,
1023 sizeof remote_filter_addr_upper - 1, 1);
1024 len = strlen(remote_filter_addr_upper) +
1025 strlen(remote_filter_addr_lower) + 2;
1026 remote_filter = calloc(len, sizeof(char));
1027 if (!remote_filter) {
1028 log_error("policy_callback: calloc "
1029 "(%d, %lu) failed", len,
1030 (unsigned long)sizeof(char));
1031 goto bad;
1033 strlcpy(remote_filter,
1034 remote_filter_addr_lower, len);
1035 strlcat(remote_filter, "-", len);
1036 strlcat(remote_filter,
1037 remote_filter_addr_upper, len);
1038 break;
1040 case IPSEC_ID_IPV4_ADDR_SUBNET:
1041 remote_filter_type = "IPv4 subnet";
1043 net = decode_32(idremote + ISAKMP_ID_DATA_OFF);
1044 subnet = decode_32(idremote +
1045 ISAKMP_ID_DATA_OFF + 4);
1046 net &= subnet;
1047 my_inet_ntop4(&net, remote_filter_addr_lower,
1048 sizeof remote_filter_addr_lower - 1, 1);
1049 net |= ~subnet;
1050 my_inet_ntop4(&net, remote_filter_addr_upper,
1051 sizeof remote_filter_addr_upper - 1, 1);
1052 len = strlen(remote_filter_addr_upper) +
1053 strlen(remote_filter_addr_lower) + 2;
1054 remote_filter = calloc(len, sizeof(char));
1055 if (!remote_filter) {
1056 log_error("policy_callback: calloc "
1057 "(%d, %lu) failed", len,
1058 (unsigned long)sizeof(char));
1059 goto bad;
1061 strlcpy(remote_filter,
1062 remote_filter_addr_lower, len);
1063 strlcat(remote_filter, "-", len);
1064 strlcat(remote_filter,
1065 remote_filter_addr_upper, len);
1066 break;
1068 case IPSEC_ID_IPV6_ADDR:
1069 remote_filter_type = "IPv6 address";
1070 my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF,
1071 remote_filter_addr_upper,
1072 sizeof remote_filter_addr_upper - 1);
1073 strlcpy(remote_filter_addr_lower,
1074 remote_filter_addr_upper,
1075 sizeof remote_filter_addr_lower);
1076 remote_filter =
1077 strdup(remote_filter_addr_upper);
1078 if (!remote_filter) {
1079 log_error("policy_callback: strdup "
1080 "(\"%s\") failed",
1081 remote_filter_addr_upper);
1082 goto bad;
1084 break;
1086 case IPSEC_ID_IPV6_RANGE:
1087 remote_filter_type = "IPv6 range";
1089 my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF,
1090 remote_filter_addr_lower,
1091 sizeof remote_filter_addr_lower - 1);
1093 my_inet_ntop6(idremote + ISAKMP_ID_DATA_OFF +
1094 16, remote_filter_addr_upper,
1095 sizeof remote_filter_addr_upper - 1);
1097 len = strlen(remote_filter_addr_upper) +
1098 strlen(remote_filter_addr_lower) + 2;
1099 remote_filter = calloc(len, sizeof(char));
1100 if (!remote_filter) {
1101 log_error("policy_callback: calloc "
1102 "(%d, %lu) failed", len,
1103 (unsigned long)sizeof(char));
1104 goto bad;
1106 strlcpy(remote_filter,
1107 remote_filter_addr_lower, len);
1108 strlcat(remote_filter, "-", len);
1109 strlcat(remote_filter,
1110 remote_filter_addr_upper, len);
1111 break;
1113 case IPSEC_ID_IPV6_ADDR_SUBNET:
1115 struct in6_addr net, mask;
1117 remote_filter_type = "IPv6 subnet";
1119 bcopy(idremote + ISAKMP_ID_DATA_OFF,
1120 &net, sizeof(net));
1121 bcopy(idremote + ISAKMP_ID_DATA_OFF +
1122 16, &mask, sizeof(mask));
1124 for (i = 0; i < 16; i++)
1125 net.s6_addr[i] &=
1126 mask.s6_addr[i];
1128 my_inet_ntop6((unsigned char *)&net,
1129 remote_filter_addr_lower,
1130 sizeof remote_filter_addr_lower - 1);
1132 for (i = 0; i < 16; i++)
1133 net.s6_addr[i] |=
1134 ~mask.s6_addr[i];
1136 my_inet_ntop6((unsigned char *)&net,
1137 remote_filter_addr_upper,
1138 sizeof remote_filter_addr_upper - 1);
1140 len = strlen(remote_filter_addr_upper)
1141 + strlen(remote_filter_addr_lower) + 2;
1142 remote_filter = calloc(len,
1143 sizeof(char));
1144 if (!remote_filter) {
1145 log_error("policy_callback: "
1146 "calloc (%d, %lu) failed",
1147 len,
1148 (unsigned long)sizeof(char));
1149 goto bad;
1151 strlcpy(remote_filter,
1152 remote_filter_addr_lower, len);
1153 strlcat(remote_filter, "-", len);
1154 strlcat(remote_filter,
1155 remote_filter_addr_upper, len);
1156 break;
1159 case IPSEC_ID_FQDN:
1160 remote_filter_type = "FQDN";
1161 remote_filter = malloc(idremotesz -
1162 ISAKMP_ID_DATA_OFF + 1);
1163 if (!remote_filter) {
1164 log_error("policy_callback: "
1165 "malloc (%lu) failed",
1166 (unsigned long)idremotesz -
1167 ISAKMP_ID_DATA_OFF + 1);
1168 goto bad;
1170 memcpy(remote_filter,
1171 idremote + ISAKMP_ID_DATA_OFF,
1172 idremotesz - ISAKMP_ID_DATA_OFF);
1173 remote_filter[idremotesz - ISAKMP_ID_DATA_OFF]
1174 = '\0';
1175 break;
1177 case IPSEC_ID_USER_FQDN:
1178 remote_filter_type = "User FQDN";
1179 remote_filter = malloc(idremotesz -
1180 ISAKMP_ID_DATA_OFF + 1);
1181 if (!remote_filter) {
1182 log_error("policy_callback: "
1183 "malloc (%lu) failed",
1184 (unsigned long)idremotesz -
1185 ISAKMP_ID_DATA_OFF + 1);
1186 goto bad;
1188 memcpy(remote_filter,
1189 idremote + ISAKMP_ID_DATA_OFF,
1190 idremotesz - ISAKMP_ID_DATA_OFF);
1191 remote_filter[idremotesz - ISAKMP_ID_DATA_OFF]
1192 = '\0';
1193 break;
1195 case IPSEC_ID_DER_ASN1_DN:
1196 remote_filter_type = "ASN1 DN";
1198 remote_filter = x509_DN_string(idremote +
1199 ISAKMP_ID_DATA_OFF,
1200 idremotesz - ISAKMP_ID_DATA_OFF);
1201 if (!remote_filter) {
1202 LOG_DBG((LOG_POLICY, 50,
1203 "policy_callback: "
1204 "failed to decode name"));
1205 goto bad;
1207 break;
1209 case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure
1210 * what's in this. */
1211 remote_filter_type = "ASN1 GN";
1212 break;
1214 case IPSEC_ID_KEY_ID:
1215 remote_filter_type = "Key ID";
1216 remote_filter
1217 = calloc(2 * (idremotesz -
1218 ISAKMP_ID_DATA_OFF) + 1,
1219 sizeof(char));
1220 if (!remote_filter) {
1221 log_error("policy_callback: "
1222 "calloc (%lu, %lu) failed",
1223 2 * ((unsigned long)idremotesz -
1224 ISAKMP_ID_DATA_OFF) + 1,
1225 (unsigned long)sizeof(char));
1226 goto bad;
1229 * Does it contain any non-printable
1230 * characters ?
1232 for (i = 0;
1233 i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
1234 if (!isprint(*(idremote +
1235 ISAKMP_ID_DATA_OFF + i)))
1236 break;
1237 if (i >= idremotesz - ISAKMP_ID_DATA_OFF) {
1238 memcpy(remote_filter,
1239 idremote + ISAKMP_ID_DATA_OFF,
1240 idremotesz - ISAKMP_ID_DATA_OFF);
1241 break;
1243 /* Non-printable characters, convert to hex */
1244 for (i = 0;
1245 i < idremotesz - ISAKMP_ID_DATA_OFF;
1246 i++) {
1247 remote_filter[2 * i]
1248 = hextab[*(idremote +
1249 ISAKMP_ID_DATA_OFF) >> 4];
1250 remote_filter[2 * i + 1]
1251 = hextab[*(idremote +
1252 ISAKMP_ID_DATA_OFF) & 0xF];
1254 break;
1256 default:
1257 log_print("policy_callback: "
1258 "unknown Remote ID type %u",
1259 GET_ISAKMP_ID_TYPE(idremote));
1260 goto bad;
1263 switch (idremote[ISAKMP_GEN_SZ + 1]) {
1264 case IPPROTO_TCP:
1265 remote_filter_proto = "tcp";
1266 break;
1268 case IPPROTO_UDP:
1269 remote_filter_proto = "udp";
1270 break;
1272 #ifdef IPPROTO_ETHERIP
1273 case IPPROTO_ETHERIP:
1274 remote_filter_proto = "etherip";
1275 break;
1276 #endif
1278 default:
1279 snprintf(remote_filter_proto_num,
1280 sizeof remote_filter_proto_num, "%d",
1281 idremote[ISAKMP_GEN_SZ + 1]);
1282 remote_filter_proto = remote_filter_proto_num;
1283 break;
1286 snprintf(remote_filter_port, sizeof remote_filter_port,
1287 "%u", decode_16(idremote + ISAKMP_GEN_SZ + 2));
1288 } else {
1289 policy_sa->transport->vtbl->get_dst(policy_sa->transport, &sin);
1290 switch (sin->sa_family) {
1291 case AF_INET:
1292 remote_filter_type = "IPv4 address";
1293 break;
1294 case AF_INET6:
1295 remote_filter_type = "IPv6 address";
1296 break;
1297 default:
1298 log_print("policy_callback: "
1299 "unsupported protocol family %d",
1300 sin->sa_family);
1301 goto bad;
1303 if (sockaddr2text(sin, &addr, 1)) {
1304 log_error("policy_callback: "
1305 "sockaddr2text failed");
1306 goto bad;
1308 memcpy(remote_filter_addr_upper, addr,
1309 sizeof remote_filter_addr_upper);
1310 memcpy(remote_filter_addr_lower, addr,
1311 sizeof remote_filter_addr_lower);
1312 free(addr);
1313 remote_filter = strdup(remote_filter_addr_upper);
1314 if (!remote_filter) {
1315 log_error("policy_callback: "
1316 "strdup (\"%s\") failed",
1317 remote_filter_addr_upper);
1318 goto bad;
1322 if (idlocal) {
1323 switch (GET_ISAKMP_ID_TYPE(idlocal)) {
1324 case IPSEC_ID_IPV4_ADDR:
1325 local_filter_type = "IPv4 address";
1327 net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
1328 my_inet_ntop4(&net, local_filter_addr_upper,
1329 sizeof local_filter_addr_upper - 1, 1);
1330 my_inet_ntop4(&net, local_filter_addr_lower,
1331 sizeof local_filter_addr_upper - 1, 1);
1332 local_filter = strdup(local_filter_addr_upper);
1333 if (!local_filter) {
1334 log_error("policy_callback: "
1335 "strdup (\"%s\") failed",
1336 local_filter_addr_upper);
1337 goto bad;
1339 break;
1341 case IPSEC_ID_IPV4_RANGE:
1342 local_filter_type = "IPv4 range";
1344 net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
1345 my_inet_ntop4(&net, local_filter_addr_lower,
1346 sizeof local_filter_addr_lower - 1, 1);
1347 net = decode_32(idlocal + ISAKMP_ID_DATA_OFF +
1349 my_inet_ntop4(&net, local_filter_addr_upper,
1350 sizeof local_filter_addr_upper - 1, 1);
1351 len = strlen(local_filter_addr_upper)
1352 + strlen(local_filter_addr_lower) + 2;
1353 local_filter = calloc(len, sizeof(char));
1354 if (!local_filter) {
1355 log_error("policy_callback: "
1356 "calloc (%d, %lu) failed", len,
1357 (unsigned long)sizeof(char));
1358 goto bad;
1360 strlcpy(local_filter, local_filter_addr_lower,
1361 len);
1362 strlcat(local_filter, "-", len);
1363 strlcat(local_filter, local_filter_addr_upper,
1364 len);
1365 break;
1367 case IPSEC_ID_IPV4_ADDR_SUBNET:
1368 local_filter_type = "IPv4 subnet";
1370 net = decode_32(idlocal + ISAKMP_ID_DATA_OFF);
1371 subnet = decode_32(idlocal +
1372 ISAKMP_ID_DATA_OFF + 4);
1373 net &= subnet;
1374 my_inet_ntop4(&net, local_filter_addr_lower,
1375 sizeof local_filter_addr_lower - 1, 1);
1376 net |= ~subnet;
1377 my_inet_ntop4(&net, local_filter_addr_upper,
1378 sizeof local_filter_addr_upper - 1, 1);
1379 len = strlen(local_filter_addr_upper)
1380 + strlen(local_filter_addr_lower) + 2;
1381 local_filter = calloc(len, sizeof(char));
1382 if (!local_filter) {
1383 log_error("policy_callback: "
1384 "calloc (%d, %lu) failed", len,
1385 (unsigned long)sizeof(char));
1386 goto bad;
1388 strlcpy(local_filter, local_filter_addr_lower,
1389 len);
1390 strlcat(local_filter, "-", len);
1391 strlcat(local_filter, local_filter_addr_upper,
1392 len);
1393 break;
1395 case IPSEC_ID_IPV6_ADDR:
1396 local_filter_type = "IPv6 address";
1397 my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF,
1398 local_filter_addr_upper,
1399 sizeof local_filter_addr_upper - 1);
1400 strlcpy(local_filter_addr_lower,
1401 local_filter_addr_upper,
1402 sizeof local_filter_addr_lower);
1403 local_filter = strdup(local_filter_addr_upper);
1404 if (!local_filter) {
1405 log_error("policy_callback: "
1406 "strdup (\"%s\") failed",
1407 local_filter_addr_upper);
1408 goto bad;
1410 break;
1412 case IPSEC_ID_IPV6_RANGE:
1413 local_filter_type = "IPv6 range";
1415 my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF,
1416 local_filter_addr_lower,
1417 sizeof local_filter_addr_lower - 1);
1419 my_inet_ntop6(idlocal + ISAKMP_ID_DATA_OFF +
1420 16, local_filter_addr_upper,
1421 sizeof local_filter_addr_upper - 1);
1423 len = strlen(local_filter_addr_upper)
1424 + strlen(local_filter_addr_lower) + 2;
1425 local_filter = calloc(len, sizeof(char));
1426 if (!local_filter) {
1427 log_error("policy_callback: "
1428 "calloc (%d, %lu) failed", len,
1429 (unsigned long)sizeof(char));
1430 goto bad;
1432 strlcpy(local_filter, local_filter_addr_lower,
1433 len);
1434 strlcat(local_filter, "-", len);
1435 strlcat(local_filter, local_filter_addr_upper,
1436 len);
1437 break;
1439 case IPSEC_ID_IPV6_ADDR_SUBNET:
1441 struct in6_addr net, mask;
1443 local_filter_type = "IPv6 subnet";
1445 bcopy(idlocal + ISAKMP_ID_DATA_OFF,
1446 &net, sizeof(net));
1447 bcopy(idlocal + ISAKMP_ID_DATA_OFF +
1448 16, &mask, sizeof(mask));
1450 for (i = 0; i < 16; i++)
1451 net.s6_addr[i] &=
1452 mask.s6_addr[i];
1454 my_inet_ntop6((unsigned char *)&net,
1455 local_filter_addr_lower,
1456 sizeof local_filter_addr_lower - 1);
1458 for (i = 0; i < 16; i++)
1459 net.s6_addr[i] |=
1460 ~mask.s6_addr[i];
1462 my_inet_ntop6((unsigned char *)&net,
1463 local_filter_addr_upper,
1464 sizeof local_filter_addr_upper -
1467 len = strlen(local_filter_addr_upper)
1468 + strlen(local_filter_addr_lower)
1469 + 2;
1470 local_filter = calloc(len,
1471 sizeof(char));
1472 if (!local_filter) {
1473 log_error("policy_callback: "
1474 "calloc (%d, %lu) failed",
1475 len,
1476 (unsigned long)sizeof(char));
1477 goto bad;
1479 strlcpy(local_filter,
1480 local_filter_addr_lower, len);
1481 strlcat(local_filter, "-", len);
1482 strlcat(local_filter,
1483 local_filter_addr_upper, len);
1484 break;
1487 case IPSEC_ID_FQDN:
1488 local_filter_type = "FQDN";
1489 local_filter = malloc(idlocalsz -
1490 ISAKMP_ID_DATA_OFF + 1);
1491 if (!local_filter) {
1492 log_error("policy_callback: "
1493 "malloc (%lu) failed",
1494 (unsigned long)idlocalsz -
1495 ISAKMP_ID_DATA_OFF + 1);
1496 goto bad;
1498 memcpy(local_filter,
1499 idlocal + ISAKMP_ID_DATA_OFF,
1500 idlocalsz - ISAKMP_ID_DATA_OFF);
1501 local_filter[idlocalsz - ISAKMP_ID_DATA_OFF]
1502 = '\0';
1503 break;
1505 case IPSEC_ID_USER_FQDN:
1506 local_filter_type = "User FQDN";
1507 local_filter = malloc(idlocalsz -
1508 ISAKMP_ID_DATA_OFF + 1);
1509 if (!local_filter) {
1510 log_error("policy_callback: "
1511 "malloc (%lu) failed",
1512 (unsigned long)idlocalsz -
1513 ISAKMP_ID_DATA_OFF + 1);
1514 goto bad;
1516 memcpy(local_filter,
1517 idlocal + ISAKMP_ID_DATA_OFF,
1518 idlocalsz - ISAKMP_ID_DATA_OFF);
1519 local_filter[idlocalsz - ISAKMP_ID_DATA_OFF]
1520 = '\0';
1521 break;
1523 case IPSEC_ID_DER_ASN1_DN:
1524 local_filter_type = "ASN1 DN";
1526 local_filter = x509_DN_string(idlocal +
1527 ISAKMP_ID_DATA_OFF,
1528 idlocalsz - ISAKMP_ID_DATA_OFF);
1529 if (!local_filter) {
1530 LOG_DBG((LOG_POLICY, 50,
1531 "policy_callback: failed to decode"
1532 " name"));
1533 goto bad;
1535 break;
1537 case IPSEC_ID_DER_ASN1_GN:
1538 /* XXX -- not sure what's in this. */
1539 local_filter_type = "ASN1 GN";
1540 break;
1542 case IPSEC_ID_KEY_ID:
1543 local_filter_type = "Key ID";
1544 local_filter = calloc(2 * (idlocalsz -
1545 ISAKMP_ID_DATA_OFF) + 1,
1546 sizeof(char));
1547 if (!local_filter) {
1548 log_error("policy_callback: "
1549 "calloc (%lu, %lu) failed",
1550 2 * ((unsigned long)idlocalsz -
1551 ISAKMP_ID_DATA_OFF) + 1,
1552 (unsigned long)sizeof(char));
1553 goto bad;
1556 * Does it contain any non-printable
1557 * characters ?
1559 for (i = 0;
1560 i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
1561 if (!isprint(*(idlocal +
1562 ISAKMP_ID_DATA_OFF + i)))
1563 break;
1564 if (i >= idlocalsz - ISAKMP_ID_DATA_OFF) {
1565 memcpy(local_filter, idlocal +
1566 ISAKMP_ID_DATA_OFF,
1567 idlocalsz - ISAKMP_ID_DATA_OFF);
1568 break;
1570 /* Non-printable characters, convert to hex */
1571 for (i = 0;
1572 i < idlocalsz - ISAKMP_ID_DATA_OFF; i++) {
1573 local_filter[2 * i]
1574 = hextab[*(idlocal +
1575 ISAKMP_ID_DATA_OFF) >> 4];
1576 local_filter[2 * i + 1]
1577 = hextab[*(idlocal +
1578 ISAKMP_ID_DATA_OFF) & 0xF];
1580 break;
1582 default:
1583 log_print("policy_callback: "
1584 "unknown Local ID type %u",
1585 GET_ISAKMP_ID_TYPE(idlocal));
1586 goto bad;
1589 switch (idlocal[ISAKMP_GEN_SZ + 1]) {
1590 case IPPROTO_TCP:
1591 local_filter_proto = "tcp";
1592 break;
1594 case IPPROTO_UDP:
1595 local_filter_proto = "udp";
1596 break;
1598 #ifdef IPPROTO_ETHERIP
1599 case IPPROTO_ETHERIP:
1600 local_filter_proto = "etherip";
1601 break;
1602 #endif
1604 default:
1605 snprintf(local_filter_proto_num,
1606 sizeof local_filter_proto_num,
1607 "%d", idlocal[ISAKMP_GEN_SZ + 1]);
1608 local_filter_proto = local_filter_proto_num;
1609 break;
1612 snprintf(local_filter_port, sizeof local_filter_port,
1613 "%u", decode_16(idlocal + ISAKMP_GEN_SZ + 2));
1614 } else {
1615 policy_sa->transport->vtbl->get_src(policy_sa->transport,
1616 (struct sockaddr **)&sin);
1617 switch (sin->sa_family) {
1618 case AF_INET:
1619 local_filter_type = "IPv4 address";
1620 break;
1621 case AF_INET6:
1622 local_filter_type = "IPv6 address";
1623 break;
1624 default:
1625 log_print("policy_callback: "
1626 "unsupported protocol family %d",
1627 sin->sa_family);
1628 goto bad;
1631 if (sockaddr2text(sin, &addr, 1)) {
1632 log_error("policy_callback: "
1633 "sockaddr2text failed");
1634 goto bad;
1636 memcpy(local_filter_addr_upper, addr,
1637 sizeof local_filter_addr_upper);
1638 memcpy(local_filter_addr_lower, addr,
1639 sizeof local_filter_addr_lower);
1640 free(addr);
1641 local_filter = strdup(local_filter_addr_upper);
1642 if (!local_filter) {
1643 log_error("policy_callback: "
1644 "strdup (\"%s\") failed",
1645 local_filter_addr_upper);
1646 goto bad;
1650 LOG_DBG((LOG_POLICY, 80,
1651 "Policy context (action attributes):"));
1652 LOG_DBG((LOG_POLICY, 80, "esp_present == %s", esp_present));
1653 LOG_DBG((LOG_POLICY, 80, "ah_present == %s", ah_present));
1654 LOG_DBG((LOG_POLICY, 80, "comp_present == %s", comp_present));
1655 LOG_DBG((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg));
1656 LOG_DBG((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg));
1657 LOG_DBG((LOG_POLICY, 80, "comp_alg == %s", comp_alg));
1658 LOG_DBG((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg));
1659 LOG_DBG((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg));
1660 LOG_DBG((LOG_POLICY, 80, "ah_life_seconds == %s",
1661 ah_life_seconds));
1662 LOG_DBG((LOG_POLICY, 80, "ah_life_kbytes == %s",
1663 ah_life_kbytes));
1664 LOG_DBG((LOG_POLICY, 80, "esp_life_seconds == %s",
1665 esp_life_seconds));
1666 LOG_DBG((LOG_POLICY, 80, "esp_life_kbytes == %s",
1667 esp_life_kbytes));
1668 LOG_DBG((LOG_POLICY, 80, "comp_life_seconds == %s",
1669 comp_life_seconds));
1670 LOG_DBG((LOG_POLICY, 80, "comp_life_kbytes == %s",
1671 comp_life_kbytes));
1672 LOG_DBG((LOG_POLICY, 80, "ah_encapsulation == %s",
1673 ah_encapsulation));
1674 LOG_DBG((LOG_POLICY, 80, "esp_encapsulation == %s",
1675 esp_encapsulation));
1676 LOG_DBG((LOG_POLICY, 80, "comp_encapsulation == %s",
1677 comp_encapsulation));
1678 LOG_DBG((LOG_POLICY, 80, "comp_dict_size == %s",
1679 comp_dict_size));
1680 LOG_DBG((LOG_POLICY, 80, "comp_private_alg == %s",
1681 comp_private_alg));
1682 LOG_DBG((LOG_POLICY, 80, "ah_key_length == %s",
1683 ah_key_length));
1684 LOG_DBG((LOG_POLICY, 80, "ah_key_rounds == %s",
1685 ah_key_rounds));
1686 LOG_DBG((LOG_POLICY, 80, "esp_key_length == %s",
1687 esp_key_length));
1688 LOG_DBG((LOG_POLICY, 80, "esp_key_rounds == %s",
1689 esp_key_rounds));
1690 LOG_DBG((LOG_POLICY, 80, "ah_group_desc == %s",
1691 ah_group_desc));
1692 LOG_DBG((LOG_POLICY, 80, "esp_group_desc == %s",
1693 esp_group_desc));
1694 LOG_DBG((LOG_POLICY, 80, "comp_group_desc == %s",
1695 comp_group_desc));
1696 LOG_DBG((LOG_POLICY, 80, "ah_ecn == %s", ah_ecn));
1697 LOG_DBG((LOG_POLICY, 80, "esp_ecn == %s", esp_ecn));
1698 LOG_DBG((LOG_POLICY, 80, "comp_ecn == %s", comp_ecn));
1699 LOG_DBG((LOG_POLICY, 80, "remote_filter_type == %s",
1700 remote_filter_type));
1701 LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_upper == %s",
1702 remote_filter_addr_upper));
1703 LOG_DBG((LOG_POLICY, 80, "remote_filter_addr_lower == %s",
1704 remote_filter_addr_lower));
1705 LOG_DBG((LOG_POLICY, 80, "remote_filter == %s",
1706 (remote_filter ? remote_filter : "")));
1707 LOG_DBG((LOG_POLICY, 80, "remote_filter_port == %s",
1708 remote_filter_port));
1709 LOG_DBG((LOG_POLICY, 80, "remote_filter_proto == %s",
1710 remote_filter_proto));
1711 LOG_DBG((LOG_POLICY, 80, "local_filter_type == %s",
1712 local_filter_type));
1713 LOG_DBG((LOG_POLICY, 80, "local_filter_addr_upper == %s",
1714 local_filter_addr_upper));
1715 LOG_DBG((LOG_POLICY, 80, "local_filter_addr_lower == %s",
1716 local_filter_addr_lower));
1717 LOG_DBG((LOG_POLICY, 80, "local_filter == %s",
1718 (local_filter ? local_filter : "")));
1719 LOG_DBG((LOG_POLICY, 80, "local_filter_port == %s",
1720 local_filter_port));
1721 LOG_DBG((LOG_POLICY, 80, "local_filter_proto == %s",
1722 local_filter_proto));
1723 LOG_DBG((LOG_POLICY, 80, "remote_id_type == %s",
1724 remote_id_type));
1725 LOG_DBG((LOG_POLICY, 80, "remote_id_addr_upper == %s",
1726 remote_id_addr_upper));
1727 LOG_DBG((LOG_POLICY, 80, "remote_id_addr_lower == %s",
1728 remote_id_addr_lower));
1729 LOG_DBG((LOG_POLICY, 80, "remote_id == %s",
1730 (remote_id ? remote_id : "")));
1731 LOG_DBG((LOG_POLICY, 80, "remote_id_port == %s",
1732 remote_id_port));
1733 LOG_DBG((LOG_POLICY, 80, "remote_id_proto == %s",
1734 remote_id_proto));
1735 LOG_DBG((LOG_POLICY, 80, "remote_negotiation_address == %s",
1736 remote_ike_address));
1737 LOG_DBG((LOG_POLICY, 80, "local_negotiation_address == %s",
1738 local_ike_address));
1739 LOG_DBG((LOG_POLICY, 80, "pfs == %s", pfs));
1740 LOG_DBG((LOG_POLICY, 80, "initiator == %s", initiator));
1741 LOG_DBG((LOG_POLICY, 80, "phase1_group_desc == %s",
1742 phase1_group));
1744 /* Unset dirty now. */
1745 dirty = 0;
1747 if (strcmp(name, "phase_1") == 0)
1748 return phase_1;
1750 if (strcmp(name, "GMTTimeOfDay") == 0) {
1751 tt = time((time_t)NULL);
1752 strftime(mytimeofday, 14, "%Y%m%d%H%M%S", gmtime(&tt));
1753 return mytimeofday;
1755 if (strcmp(name, "LocalTimeOfDay") == 0) {
1756 tt = time((time_t)NULL);
1757 strftime(mytimeofday, 14, "%Y%m%d%H%M%S", localtime(&tt));
1758 return mytimeofday;
1760 if (strcmp(name, "initiator") == 0)
1761 return initiator;
1763 if (strcmp(name, "pfs") == 0)
1764 return pfs;
1766 if (strcmp(name, "app_domain") == 0)
1767 return "IPsec policy";
1769 if (strcmp(name, "doi") == 0)
1770 return "ipsec";
1772 if (strcmp(name, "esp_present") == 0)
1773 return esp_present;
1775 if (strcmp(name, "ah_present") == 0)
1776 return ah_present;
1778 if (strcmp(name, "comp_present") == 0)
1779 return comp_present;
1781 if (strcmp(name, "ah_hash_alg") == 0)
1782 return ah_hash_alg;
1784 if (strcmp(name, "ah_auth_alg") == 0)
1785 return ah_auth_alg;
1787 if (strcmp(name, "esp_auth_alg") == 0)
1788 return esp_auth_alg;
1790 if (strcmp(name, "esp_enc_alg") == 0)
1791 return esp_enc_alg;
1793 if (strcmp(name, "comp_alg") == 0)
1794 return comp_alg;
1796 if (strcmp(name, "ah_life_kbytes") == 0)
1797 return ah_life_kbytes;
1799 if (strcmp(name, "ah_life_seconds") == 0)
1800 return ah_life_seconds;
1802 if (strcmp(name, "esp_life_kbytes") == 0)
1803 return esp_life_kbytes;
1805 if (strcmp(name, "esp_life_seconds") == 0)
1806 return esp_life_seconds;
1808 if (strcmp(name, "comp_life_kbytes") == 0)
1809 return comp_life_kbytes;
1811 if (strcmp(name, "comp_life_seconds") == 0)
1812 return comp_life_seconds;
1814 if (strcmp(name, "ah_encapsulation") == 0)
1815 return ah_encapsulation;
1817 if (strcmp(name, "esp_encapsulation") == 0)
1818 return esp_encapsulation;
1820 if (strcmp(name, "comp_encapsulation") == 0)
1821 return comp_encapsulation;
1823 if (strcmp(name, "ah_key_length") == 0)
1824 return ah_key_length;
1826 if (strcmp(name, "ah_key_rounds") == 0)
1827 return ah_key_rounds;
1829 if (strcmp(name, "esp_key_length") == 0)
1830 return esp_key_length;
1832 if (strcmp(name, "esp_key_rounds") == 0)
1833 return esp_key_rounds;
1835 if (strcmp(name, "comp_dict_size") == 0)
1836 return comp_dict_size;
1838 if (strcmp(name, "comp_private_alg") == 0)
1839 return comp_private_alg;
1841 if (strcmp(name, "remote_filter_type") == 0)
1842 return remote_filter_type;
1844 if (strcmp(name, "remote_filter") == 0)
1845 return (remote_filter ? remote_filter : "");
1847 if (strcmp(name, "remote_filter_addr_upper") == 0)
1848 return remote_filter_addr_upper;
1850 if (strcmp(name, "remote_filter_addr_lower") == 0)
1851 return remote_filter_addr_lower;
1853 if (strcmp(name, "remote_filter_port") == 0)
1854 return remote_filter_port;
1856 if (strcmp(name, "remote_filter_proto") == 0)
1857 return remote_filter_proto;
1859 if (strcmp(name, "local_filter_type") == 0)
1860 return local_filter_type;
1862 if (strcmp(name, "local_filter") == 0)
1863 return (local_filter ? local_filter : "");
1865 if (strcmp(name, "local_filter_addr_upper") == 0)
1866 return local_filter_addr_upper;
1868 if (strcmp(name, "local_filter_addr_lower") == 0)
1869 return local_filter_addr_lower;
1871 if (strcmp(name, "local_filter_port") == 0)
1872 return local_filter_port;
1874 if (strcmp(name, "local_filter_proto") == 0)
1875 return local_filter_proto;
1877 if (strcmp(name, "remote_ike_address") == 0)
1878 return remote_ike_address;
1880 if (strcmp(name, "remote_negotiation_address") == 0)
1881 return remote_ike_address;
1883 if (strcmp(name, "local_ike_address") == 0)
1884 return local_ike_address;
1886 if (strcmp(name, "local_negotiation_address") == 0)
1887 return local_ike_address;
1889 if (strcmp(name, "remote_id_type") == 0)
1890 return remote_id_type;
1892 if (strcmp(name, "remote_id") == 0)
1893 return (remote_id ? remote_id : "");
1895 if (strcmp(name, "remote_id_addr_upper") == 0)
1896 return remote_id_addr_upper;
1898 if (strcmp(name, "remote_id_addr_lower") == 0)
1899 return remote_id_addr_lower;
1901 if (strcmp(name, "remote_id_port") == 0)
1902 return remote_id_port;
1904 if (strcmp(name, "remote_id_proto") == 0)
1905 return remote_id_proto;
1907 if (strcmp(name, "phase1_group_desc") == 0)
1908 return phase1_group;
1910 if (strcmp(name, "esp_group_desc") == 0)
1911 return esp_group_desc;
1913 if (strcmp(name, "ah_group_desc") == 0)
1914 return ah_group_desc;
1916 if (strcmp(name, "comp_group_desc") == 0)
1917 return comp_group_desc;
1919 if (strcmp(name, "comp_ecn") == 0)
1920 return comp_ecn;
1922 if (strcmp(name, "ah_ecn") == 0)
1923 return ah_ecn;
1925 if (strcmp(name, "esp_ecn") == 0)
1926 return esp_ecn;
1928 return "";
1930 bad:
1931 policy_callback(KEYNOTE_CALLBACK_INITIALIZE);
1932 return "";
1935 void
1936 policy_init(void)
1938 char *ptr, *policy_file, *use_keynote;
1939 char **asserts;
1940 size_t sz, len;
1941 int fd, i;
1943 LOG_DBG((LOG_POLICY, 30, "policy_init: initializing"));
1945 /* Do we want to use the policy modules? */
1946 use_keynote = conf_get_str("General", "Use-Keynote");
1947 if (ignore_policy ||
1948 (use_keynote && strncmp("yes", use_keynote, 3)))
1949 return;
1951 /* Get policy file from configuration. */
1952 policy_file = conf_get_str("General", "Policy-file");
1953 if (!policy_file)
1954 policy_file = CONF_DFLT_POLICY_FILE;
1956 /* Open policy file. */
1957 fd = monitor_open(policy_file, O_RDONLY, 0);
1958 if (fd == -1)
1959 log_fatal("policy_init: open (\"%s\", O_RDONLY) failed",
1960 policy_file);
1962 /* Check file modes and collect file size */
1963 if (check_file_secrecy_fd(fd, policy_file, &sz)) {
1964 close(fd);
1965 log_fatal("policy_init: cannot read %s", policy_file);
1968 /* Allocate memory to keep policies. */
1969 ptr = calloc(sz + 1, sizeof(char));
1970 if (!ptr)
1971 log_fatal("policy_init: calloc (%lu, %lu) failed",
1972 (unsigned long)sz + 1, (unsigned long)sizeof(char));
1974 /* Just in case there are short reads... */
1975 for (len = 0; len < sz; len += i) {
1976 i = read(fd, ptr + len, sz - len);
1977 if (i == -1)
1978 log_fatal("policy_init: read (%d, %p, %lu) failed", fd,
1979 ptr + len, (unsigned long)(sz - len));
1982 /* We're done with this. */
1983 close(fd);
1985 /* Parse buffer, break up into individual policies. */
1986 asserts = kn_read_asserts(ptr, sz, &i);
1988 /* Begone! */
1989 free(ptr);
1991 if (asserts == (char **)NULL)
1992 log_print("policy_init: all policies flushed");
1994 /* Cleanup */
1995 if (policy_asserts) {
1996 for (fd = 0; fd < policy_asserts_num; fd++)
1997 if (policy_asserts && policy_asserts[fd])
1998 free(policy_asserts[fd]);
2000 free(policy_asserts);
2002 policy_asserts = asserts;
2003 policy_asserts_num = i;
2006 /* Nothing needed for initialization */
2008 keynote_cert_init(void)
2010 return 1;
2013 /* Just copy and return. */
2014 void *
2015 keynote_cert_get(u_int8_t *data, u_int32_t len)
2017 char *foo = malloc(len + 1);
2019 if (foo == NULL)
2020 return NULL;
2022 memcpy(foo, data, len);
2023 foo[len] = '\0';
2024 return foo;
2028 * We just verify the signature on the credentials.
2029 * On signature failure, just drop the whole payload.
2032 keynote_cert_validate(void *scert)
2034 char **foo;
2035 int num, i;
2037 if (scert == NULL)
2038 return 0;
2040 foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num);
2041 if (foo == NULL)
2042 return 0;
2044 for (i = 0; i < num; i++) {
2045 if (kn_verify_assertion(scert, strlen((char *)scert))
2046 != SIGRESULT_TRUE) {
2047 for (; i < num; i++)
2048 free(foo[i]);
2049 free(foo);
2050 return 0;
2052 free(foo[i]);
2055 free(foo);
2056 return 1;
2059 /* Add received credentials. */
2061 keynote_cert_insert(int sid, void *scert)
2063 char **foo;
2064 int num;
2066 if (scert == NULL)
2067 return 0;
2069 foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num);
2070 if (foo == NULL)
2071 return 0;
2073 while (num--)
2074 kn_add_assertion(sid, foo[num], strlen(foo[num]), 0);
2076 return 1;
2079 /* Just regular memory free. */
2080 void
2081 keynote_cert_free(void *cert)
2083 free(cert);
2086 /* Verify that the key given to us is valid. */
2088 keynote_certreq_validate(u_int8_t *data, u_int32_t len)
2090 struct keynote_deckey dc;
2091 int err = 1;
2092 char *dat;
2094 dat = calloc(len + 1, sizeof(char));
2095 if (!dat) {
2096 log_error("keynote_certreq_validate: calloc (%d, %lu) failed",
2097 len + 1, (unsigned long)sizeof(char));
2098 return 0;
2100 memcpy(dat, data, len);
2102 if (kn_decode_key(&dc, dat, KEYNOTE_PUBLIC_KEY) != 0)
2103 err = 0;
2104 else
2105 kn_free_key(&dc);
2107 free(dat);
2109 return err;
2112 /* Beats me what we should be doing with this. */
2113 void *
2114 keynote_certreq_decode(u_int8_t *data, u_int32_t len)
2116 /* XXX */
2117 return NULL;
2120 void
2121 keynote_free_aca(void *blob)
2123 /* XXX */
2127 keynote_cert_obtain(u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
2128 u_int32_t *certlen)
2130 char *dirname, *file, *addr_str;
2131 struct stat sb;
2132 size_t size;
2133 int idtype, fd, len;
2135 if (!id) {
2136 log_print("keynote_cert_obtain: ID is missing");
2137 return 0;
2139 /* Get type of ID. */
2140 idtype = id[0];
2141 id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
2142 id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
2144 dirname = conf_get_str("KeyNote", "Credential-directory");
2145 if (!dirname) {
2146 LOG_DBG((LOG_POLICY, 30,
2147 "keynote_cert_obtain: no Credential-directory"));
2148 return 0;
2150 len = strlen(dirname) + strlen(CREDENTIAL_FILE) + 3;
2152 switch (idtype) {
2153 case IPSEC_ID_IPV4_ADDR:
2154 case IPSEC_ID_IPV6_ADDR:
2155 util_ntoa(&addr_str, idtype == IPSEC_ID_IPV4_ADDR ?
2156 AF_INET : AF_INET6, id);
2157 if (addr_str == 0)
2158 return 0;
2160 file = calloc(len + strlen(addr_str), sizeof(char));
2161 if (file == NULL) {
2162 log_error("keynote_cert_obtain: failed to allocate "
2163 "%lu bytes", (unsigned long)len +
2164 strlen(addr_str));
2165 free(addr_str);
2166 return 0;
2168 snprintf(file, len + strlen(addr_str), "%s/%s/%s", dirname,
2169 addr_str, CREDENTIAL_FILE);
2170 free(addr_str);
2171 break;
2173 case IPSEC_ID_FQDN:
2174 case IPSEC_ID_USER_FQDN: {
2175 file = calloc(len + id_len, sizeof(char));
2176 if (file == NULL) {
2177 log_error("keynote_cert_obtain: "
2178 "failed to allocate %lu bytes",
2179 (unsigned long)len + id_len);
2180 return 0;
2182 snprintf(file, len + id_len, "%s/", dirname);
2183 memcpy(file + strlen(dirname) + 1, id, id_len);
2184 snprintf(file + strlen(dirname) + 1 + id_len,
2185 len - strlen(dirname) - 1, "/%s", CREDENTIAL_FILE);
2186 break;
2189 default:
2190 return 0;
2193 fd = monitor_open(file, O_RDONLY, 0);
2194 if (fd < 0) {
2195 LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: "
2196 "failed to open \"%s\"", file));
2197 free(file);
2198 return 0;
2201 if (fstat(fd, &sb) < 0) {
2202 LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: "
2203 "failed to stat \"%s\"", file));
2204 free(file);
2205 close(fd);
2206 return 0;
2208 size = (size_t)sb.st_size;
2210 *cert = calloc(size + 1, sizeof(char));
2211 if (*cert == NULL) {
2212 log_error("keynote_cert_obtain: failed to allocate %lu bytes",
2213 (unsigned long)size);
2214 free(file);
2215 return 0;
2218 if (read(fd, *cert, size) != (int)size) {
2219 LOG_DBG((LOG_POLICY, 30, "keynote_cert_obtain: "
2220 "failed to read %lu bytes from \"%s\"",
2221 (unsigned long)size, file));
2222 free(file);
2223 close(fd);
2224 return 0;
2226 close(fd);
2227 free(file);
2228 *certlen = size;
2229 return 1;
2232 /* This should never be called. */
2234 keynote_cert_get_subjects(void *scert, int *n, u_int8_t ***id,
2235 u_int32_t **id_len)
2237 return 0;
2240 /* Get the authorizer key. */
2242 keynote_cert_get_key(void *scert, void *keyp)
2244 struct keynote_keylist *kl;
2245 int sid, kid, num;
2246 char **foo;
2248 foo = kn_read_asserts((char *)scert, strlen((char *)scert), &num);
2249 if (foo == NULL || num == 0) {
2250 log_print("keynote_cert_get_key: "
2251 "failed to decompose credentials");
2252 return 0;
2254 kid = kn_init();
2255 if (kid == -1) {
2256 log_print("keynote_cert_get_key: "
2257 "failed to initialize new policy session");
2258 while (num--)
2259 free(foo[num]);
2260 free(foo);
2261 return 0;
2263 sid = kn_add_assertion(kid, foo[num - 1], strlen(foo[num - 1]), 0);
2264 while (num--)
2265 free(foo[num]);
2266 free(foo);
2268 if (sid == -1) {
2269 log_print("keynote_cert_get_key: failed to add assertion");
2270 kn_close(kid);
2271 return 0;
2273 *(RSA **)keyp = NULL;
2275 kl = kn_get_licensees(kid, sid);
2276 while (kl) {
2277 if (kl->key_alg == KEYNOTE_ALGORITHM_RSA ||
2278 kl->key_alg == KEYNOTE_ALGORITHM_X509) {
2279 *(RSA **)keyp = RSAPublicKey_dup(kl->key_key);
2280 break;
2282 kl = kl->key_next;
2285 kn_remove_assertion(kid, sid);
2286 kn_close(kid);
2287 return *(RSA **)keyp == NULL ? 0 : 1;
2290 void *
2291 keynote_cert_dup(void *cert)
2293 return strdup((char *)cert);
2296 void
2297 keynote_serialize(void *cert, u_int8_t **data, u_int32_t *datalen)
2299 *datalen = strlen((char *)cert) + 1;
2300 *data = (u_int8_t *)strdup(cert); /* i.e an extra character at
2301 * the end... */
2302 if (*data == NULL)
2303 log_error("keynote_serialize: malloc (%d) failed", *datalen);
2306 /* From cert to printable */
2307 char *
2308 keynote_printable(void *cert)
2310 return strdup((char *)cert);
2313 /* From printable to cert */
2314 void *
2315 keynote_from_printable(char *cert)
2317 return strdup(cert);