policy.c revision 1.57
1/*	$OpenBSD: policy.c,v 1.57 2002/11/14 16:38:05 ho Exp $	*/
2/*	$EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
3
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.
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. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by Ericsson Radio Systems.
20 * 4. The name of the author may not be used to endorse or promote products
21 *    derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * This code was written under funding by Ericsson Radio Systems.
37 */
38
39#include <sys/types.h>
40#include <sys/param.h>
41#include <sys/mman.h>
42#include <sys/queue.h>
43#include <sys/stat.h>
44#include <regex.h>
45#include <ctype.h>
46#include <fcntl.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <unistd.h>
51#include <keynote.h>
52#include <sys/socket.h>
53#include <netinet/in.h>
54#include <arpa/inet.h>
55#include <errno.h>
56#include <openssl/ssl.h>
57#include <netdb.h>
58
59#include "sysdep.h"
60
61#include "conf.h"
62#include "exchange.h"
63#include "ipsec.h"
64#include "isakmp_doi.h"
65#include "sa.h"
66#include "transport.h"
67#include "log.h"
68#include "message.h"
69#include "util.h"
70#include "policy.h"
71#include "x509.h"
72
73char **keynote_policy_asserts = NULL;
74int keynote_policy_asserts_num = 0;
75struct exchange *policy_exchange = 0;
76struct sa *policy_sa = 0;
77struct sa *policy_isakmp_sa = 0;
78
79static const char hextab[] = {
80  '0', '1', '2', '3', '4', '5', '6', '7',
81  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
82};
83
84/*
85 * Adaptation of Vixie's inet_ntop4 ()
86 */
87static const char *
88my_inet_ntop4 (const in_addr_t *src, char *dst, size_t size, int normalize)
89{
90  static const char fmt[] = "%03u.%03u.%03u.%03u";
91  char tmp[sizeof "255.255.255.255"];
92  in_addr_t src2;
93
94  if (normalize)
95    src2 = ntohl (*src);
96  else
97    src2 = *src;
98
99  if (snprintf (tmp, sizeof tmp, fmt, ((u_int8_t *) &src2)[0],
100		((u_int8_t *) &src2)[1], ((u_int8_t *) &src2)[2],
101		((u_int8_t *) &src2)[3]) > size)
102    {
103      errno = ENOSPC;
104      return 0;
105    }
106  strlcpy (dst, tmp, size);
107  return dst;
108}
109
110static const char *
111my_inet_ntop6 (const unsigned char *src, char *dst, size_t size)
112{
113  static const char fmt[] = "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x";
114  char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
115
116  if (snprintf (tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3], src[4],
117		src[5], src[6], src[7], src[8], src[9], src[10], src[11],
118		src[12], src[13], src[14], src[15]) > size)
119    {
120      errno = ENOSPC;
121      return 0;
122    }
123  strlcpy (dst, tmp, size);
124  return dst;
125}
126
127char *
128policy_callback (char *name)
129{
130  struct proto *proto;
131
132  u_int8_t *attr, *value, *id, *idlocal, *idremote;
133  size_t id_sz, idlocalsz, idremotesz;
134  struct sockaddr *sin;
135  struct ipsec_exch *ie;
136  struct ipsec_sa *is;
137  int fmt, i, lifetype = 0;
138  in_addr_t net, subnet;
139  u_int16_t len, type;
140  time_t tt;
141  char *addr;
142  static char mytimeofday[15];
143
144  /* We use all these as a cache.  */
145#define PMAX 32
146  static char *esp_present, *ah_present, *comp_present;
147  static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
148  static char *comp_alg, ah_life_kbytes[PMAX], ah_life_seconds[PMAX];
149  static char esp_life_kbytes[PMAX], esp_life_seconds[PMAX];
150  static char comp_life_kbytes[PMAX];
151  static char *ah_ecn, *esp_ecn, *comp_ecn;
152  static char comp_life_seconds[PMAX], *ah_encapsulation, *esp_encapsulation;
153  static char *comp_encapsulation, ah_key_length[PMAX], esp_key_length[PMAX];
154  static char ah_key_rounds[PMAX], esp_key_rounds[PMAX], comp_dict_size[PMAX];
155  static char comp_private_alg[PMAX], *remote_filter_type, *local_filter_type;
156  static char remote_filter_addr_upper[NI_MAXHOST];
157  static char remote_filter_addr_lower[NI_MAXHOST];
158  static char local_filter_addr_upper[NI_MAXHOST];
159  static char local_filter_addr_lower[NI_MAXHOST];
160  static char ah_group_desc[PMAX], esp_group_desc[PMAX], comp_group_desc[PMAX];
161  static char remote_ike_address[NI_MAXHOST];
162  static char local_ike_address[NI_MAXHOST];
163  static char *remote_id_type, remote_id_addr_upper[NI_MAXHOST], *phase_1;
164  static char remote_id_addr_lower[NI_MAXHOST];
165  static char *remote_id_proto, remote_id_port[PMAX];
166  static char remote_filter_port[PMAX], local_filter_port[PMAX];
167  static char *remote_filter_proto, *local_filter_proto, *pfs, *initiator;
168  static char remote_filter_proto_num[3], local_filter_proto_num[3];
169  static char remote_id_proto_num[3];
170  static char phase1_group[PMAX];
171
172  /* Allocated.  */
173  static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
174
175  static int dirty = 1;
176
177  /* We only need to set dirty at initialization time really.  */
178  if (strcmp (name, KEYNOTE_CALLBACK_CLEANUP) == 0
179      || strcmp (name, KEYNOTE_CALLBACK_INITIALIZE) == 0)
180    {
181      esp_present = ah_present = comp_present = pfs = "no";
182      ah_hash_alg = ah_auth_alg = phase_1 = "";
183      esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
184      ah_ecn = esp_ecn = comp_ecn = "no";
185      esp_encapsulation = comp_encapsulation = remote_filter_type = "";
186      local_filter_type = remote_id_type = initiator = "";
187      remote_filter_proto = local_filter_proto = remote_id_proto = "";
188
189      if (remote_filter != 0)
190        {
191	  free (remote_filter);
192	  remote_filter = 0;
193	}
194
195      if (local_filter != 0)
196        {
197	  free (local_filter);
198	  local_filter = 0;
199	}
200
201      if (remote_id != 0)
202        {
203	  free (remote_id);
204	  remote_id = 0;
205	}
206
207      memset (remote_ike_address, 0, sizeof remote_ike_address);
208      memset (local_ike_address, 0, sizeof local_ike_address);
209      memset (ah_life_kbytes, 0, sizeof ah_life_kbytes);
210      memset (ah_life_seconds, 0, sizeof ah_life_seconds);
211      memset (esp_life_kbytes, 0, sizeof esp_life_kbytes);
212      memset (esp_life_seconds, 0, sizeof esp_life_seconds);
213      memset (comp_life_kbytes, 0, sizeof comp_life_kbytes);
214      memset (comp_life_seconds, 0, sizeof comp_life_seconds);
215      memset (ah_key_length, 0, sizeof ah_key_length);
216      memset (ah_key_rounds, 0, sizeof ah_key_rounds);
217      memset (esp_key_length, 0, sizeof esp_key_length);
218      memset (esp_key_rounds, 0, sizeof esp_key_rounds);
219      memset (comp_dict_size, 0, sizeof comp_dict_size);
220      memset (comp_private_alg, 0, sizeof comp_private_alg);
221      memset (remote_filter_addr_upper, 0, sizeof remote_filter_addr_upper);
222      memset (remote_filter_addr_lower, 0, sizeof remote_filter_addr_lower);
223      memset (local_filter_addr_upper, 0, sizeof local_filter_addr_upper);
224      memset (local_filter_addr_lower, 0, sizeof local_filter_addr_lower);
225      memset (remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
226      memset (remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
227      memset (ah_group_desc, 0, sizeof ah_group_desc);
228      memset (esp_group_desc, 0, sizeof esp_group_desc);
229      memset (remote_id_port, 0, sizeof remote_id_port);
230      memset (remote_filter_port, 0, sizeof remote_filter_port);
231      memset (local_filter_port, 0, sizeof local_filter_port);
232      memset (phase1_group, 0, sizeof phase1_group);
233
234      dirty = 1;
235      return "";
236    }
237
238  /*
239   * If dirty is set, this is the first request for an attribute, so
240   * populate our value cache.
241   */
242  if (dirty)
243    {
244      ie = policy_exchange->data;
245
246      if (ie->pfs)
247	pfs = "yes";
248
249      is = policy_isakmp_sa->data;
250      snprintf (phase1_group, PMAX, "%u", is->group_desc);
251
252      for (proto = TAILQ_FIRST (&policy_sa->protos); proto;
253	   proto = TAILQ_NEXT (proto, link))
254	{
255	  switch (proto->proto)
256	    {
257	    case IPSEC_PROTO_IPSEC_AH:
258	      ah_present = "yes";
259	      switch (proto->id)
260		{
261		case IPSEC_AH_MD5:
262		  ah_hash_alg = "md5";
263		  break;
264
265		case IPSEC_AH_SHA:
266		  ah_hash_alg = "sha";
267		  break;
268
269		case IPSEC_AH_RIPEMD:
270		  ah_hash_alg = "ripemd";
271		  break;
272
273		case IPSEC_AH_DES:
274		  ah_hash_alg = "des";
275		  break;
276		}
277
278	      break;
279
280	    case IPSEC_PROTO_IPSEC_ESP:
281	      esp_present = "yes";
282	      switch (proto->id)
283		{
284		case IPSEC_ESP_DES_IV64:
285		  esp_enc_alg = "des-iv64";
286		  break;
287
288		case IPSEC_ESP_DES:
289		  esp_enc_alg = "des";
290		  break;
291
292		case IPSEC_ESP_3DES:
293		  esp_enc_alg = "3des";
294		  break;
295
296		case IPSEC_ESP_AES:
297		  esp_enc_alg = "aes";
298		  break;
299
300		case IPSEC_ESP_RC5:
301		  esp_enc_alg = "rc5";
302		  break;
303
304		case IPSEC_ESP_IDEA:
305		  esp_enc_alg = "idea";
306		  break;
307
308		case IPSEC_ESP_CAST:
309		  esp_enc_alg = "cast";
310		  break;
311
312		case IPSEC_ESP_BLOWFISH:
313		  esp_enc_alg = "blowfish";
314		  break;
315
316		case IPSEC_ESP_3IDEA:
317		  esp_enc_alg = "3idea";
318		  break;
319
320		case IPSEC_ESP_DES_IV32:
321		  esp_enc_alg = "des-iv32";
322		  break;
323
324		case IPSEC_ESP_RC4:
325		  esp_enc_alg = "rc4";
326		  break;
327
328		case IPSEC_ESP_NULL:
329		  esp_enc_alg = "null";
330		  break;
331		}
332
333	      break;
334
335	    case IPSEC_PROTO_IPCOMP:
336	      comp_present = "yes";
337	      switch (proto->id)
338		{
339		case IPSEC_IPCOMP_OUI:
340		  comp_alg = "oui";
341		  break;
342
343		case IPSEC_IPCOMP_DEFLATE:
344		  comp_alg = "deflate";
345		  break;
346
347		case IPSEC_IPCOMP_LZS:
348		  comp_alg = "lzs";
349		  break;
350
351		case IPSEC_IPCOMP_V42BIS:
352		  comp_alg = "v42bis";
353		  break;
354		}
355
356	      break;
357	    }
358
359	  for (attr = proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
360	       attr
361		 < proto->chosen->p + GET_ISAKMP_GEN_LENGTH (proto->chosen->p);
362	       attr = value + len)
363	    {
364	      if (attr + ISAKMP_ATTR_VALUE_OFF
365		  > (proto->chosen->p
366		     + GET_ISAKMP_GEN_LENGTH (proto->chosen->p)))
367		return "";
368
369	      type = GET_ISAKMP_ATTR_TYPE (attr);
370	      fmt = ISAKMP_ATTR_FORMAT (type);
371	      type = ISAKMP_ATTR_TYPE (type);
372	      value = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF :
373			      ISAKMP_ATTR_VALUE_OFF);
374	      len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
375		     GET_ISAKMP_ATTR_LENGTH_VALUE (attr));
376
377	      if (value + len > proto->chosen->p +
378		  GET_ISAKMP_GEN_LENGTH (proto->chosen->p))
379		return "";
380
381	      switch (type)
382		{
383		case IPSEC_ATTR_SA_LIFE_TYPE:
384		  lifetype = decode_16 (value);
385		  break;
386
387		case IPSEC_ATTR_SA_LIFE_DURATION:
388		  switch (proto->proto)
389		    {
390		    case IPSEC_PROTO_IPSEC_AH:
391		      if (lifetype == IPSEC_DURATION_SECONDS)
392			{
393			  if (len == 2)
394			    snprintf (ah_life_seconds, PMAX, "%u",
395				      decode_16 (value));
396			  else
397			    snprintf (ah_life_seconds, PMAX, "%u",
398				      decode_32 (value));
399			}
400		      else
401			{
402			  if (len == 2)
403			    snprintf (ah_life_kbytes, PMAX, "%u",
404				      decode_16 (value));
405			  else
406			    snprintf (ah_life_kbytes, PMAX, "%u",
407				      decode_32 (value));
408			}
409
410		      break;
411
412		    case IPSEC_PROTO_IPSEC_ESP:
413		      if (lifetype == IPSEC_DURATION_SECONDS)
414			{
415			  if (len == 2)
416			    snprintf (esp_life_seconds, PMAX, "%u",
417				      decode_16 (value));
418			  else
419			    snprintf (esp_life_seconds, PMAX, "%u",
420				      decode_32 (value));
421			}
422		      else
423			{
424			  if (len == 2)
425			    snprintf (esp_life_kbytes, PMAX, "%u",
426				      decode_16 (value));
427			  else
428			    snprintf (esp_life_kbytes, PMAX, "%u",
429				      decode_32 (value));
430			}
431
432		      break;
433
434		    case IPSEC_PROTO_IPCOMP:
435		      if (lifetype == IPSEC_DURATION_SECONDS)
436			{
437			  if (len == 2)
438			    snprintf (comp_life_seconds, PMAX, "%u",
439				      decode_16 (value));
440			  else
441			    snprintf (comp_life_seconds, PMAX, "%u",
442				      decode_32 (value));
443			}
444		      else
445			{
446			  if (len == 2)
447			    snprintf (comp_life_kbytes, PMAX, "%u",
448				      decode_16 (value));
449			  else
450			    snprintf (comp_life_kbytes, PMAX, "%u",
451				      decode_32 (value));
452			}
453
454		      break;
455		    }
456		  break;
457
458		case IPSEC_ATTR_GROUP_DESCRIPTION:
459		  switch (proto->proto)
460		    {
461		    case IPSEC_PROTO_IPSEC_AH:
462		      snprintf (ah_group_desc, PMAX, "%u", decode_16 (value));
463		      break;
464
465		    case IPSEC_PROTO_IPSEC_ESP:
466		      snprintf (esp_group_desc, PMAX, "%u",
467			       decode_16 (value));
468		      break;
469
470		    case IPSEC_PROTO_IPCOMP:
471		      snprintf (comp_group_desc, PMAX, "%u",
472			       decode_16 (value));
473		      break;
474		    }
475		  break;
476
477		case IPSEC_ATTR_ECN_TUNNEL:
478		  if (decode_16 (value))
479		    switch (proto->proto)
480		      {
481		      case IPSEC_PROTO_IPSEC_AH:
482			ah_ecn = "yes";
483			break;
484
485		      case IPSEC_PROTO_IPSEC_ESP:
486			esp_ecn = "yes";
487			break;
488
489		      case IPSEC_PROTO_IPCOMP:
490			comp_ecn = "yes";
491			break;
492		      }
493
494		case IPSEC_ATTR_ENCAPSULATION_MODE:
495		  if (decode_16 (value) == IPSEC_ENCAP_TUNNEL)
496		    switch (proto->proto)
497		      {
498		      case IPSEC_PROTO_IPSEC_AH:
499			ah_encapsulation = "tunnel";
500			break;
501
502		      case IPSEC_PROTO_IPSEC_ESP:
503			esp_encapsulation = "tunnel";
504			break;
505
506		      case IPSEC_PROTO_IPCOMP:
507			comp_encapsulation = "tunnel";
508			break;
509		      }
510		  else
511		    switch (proto->proto)
512		      {
513		      case IPSEC_PROTO_IPSEC_AH:
514			ah_encapsulation = "transport";
515			break;
516
517		      case IPSEC_PROTO_IPSEC_ESP:
518			esp_encapsulation = "transport";
519			break;
520
521		      case IPSEC_PROTO_IPCOMP:
522			comp_encapsulation = "transport";
523			break;
524		      }
525		  break;
526
527		case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
528		  switch (proto->proto)
529		    {
530		    case IPSEC_PROTO_IPSEC_AH:
531		      switch (decode_16 (value))
532			{
533			case IPSEC_AUTH_HMAC_MD5:
534			  ah_auth_alg = "hmac-md5";
535			  break;
536
537			case IPSEC_AUTH_HMAC_SHA:
538			  ah_auth_alg = "hmac-sha";
539			  break;
540
541			case IPSEC_AUTH_HMAC_RIPEMD:
542			  ah_auth_alg = "hmac-ripemd";
543			  break;
544
545			case IPSEC_AUTH_DES_MAC:
546			  ah_auth_alg = "des-mac";
547			  break;
548
549			case IPSEC_AUTH_KPDK:
550			  ah_auth_alg = "kpdk";
551			  break;
552			}
553		      break;
554
555		    case IPSEC_PROTO_IPSEC_ESP:
556		      switch (decode_16 (value))
557			{
558			case IPSEC_AUTH_HMAC_MD5:
559			  esp_auth_alg = "hmac-md5";
560			  break;
561
562			case IPSEC_AUTH_HMAC_SHA:
563			  esp_auth_alg = "hmac-sha";
564			  break;
565
566			case IPSEC_AUTH_HMAC_RIPEMD:
567			  esp_auth_alg = "hmac-ripemd";
568			  break;
569
570			case IPSEC_AUTH_DES_MAC:
571			  esp_auth_alg = "des-mac";
572			  break;
573
574			case IPSEC_AUTH_KPDK:
575			  esp_auth_alg = "kpdk";
576			  break;
577			}
578		      break;
579		    }
580		  break;
581
582		case IPSEC_ATTR_KEY_LENGTH:
583		  switch (proto->proto)
584		    {
585		    case IPSEC_PROTO_IPSEC_AH:
586		      snprintf (ah_key_length, PMAX, "%u", decode_16 (value));
587		      break;
588
589		    case IPSEC_PROTO_IPSEC_ESP:
590		      snprintf (esp_key_length, PMAX, "%u",
591			       decode_16 (value));
592		      break;
593		    }
594		  break;
595
596		case IPSEC_ATTR_KEY_ROUNDS:
597		  switch (proto->proto)
598		    {
599		    case IPSEC_PROTO_IPSEC_AH:
600		      snprintf (ah_key_rounds, PMAX, "%u", decode_16 (value));
601		      break;
602
603		    case IPSEC_PROTO_IPSEC_ESP:
604		      snprintf (esp_key_rounds, PMAX, "%u",
605			       decode_16 (value));
606		      break;
607		    }
608		  break;
609
610		case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
611		  snprintf (comp_dict_size, PMAX, "%u", decode_16 (value));
612		  break;
613
614		case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
615		  snprintf (comp_private_alg, PMAX, "%u", decode_16 (value));
616		  break;
617		}
618	    }
619	}
620
621      policy_sa->transport->vtbl->get_src (policy_sa->transport, &sin);
622      if (sockaddr2text (sin, &addr, 1))
623	{
624	  log_error ("policy_callback: sockaddr2text failed");
625	  goto bad;
626	}
627      strlcpy (local_ike_address, addr, sizeof local_ike_address);
628      free (addr);
629
630      policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
631      if (sockaddr2text (sin, &addr, 1))
632	{
633	  log_error ("policy_callback: sockaddr2text failed");
634	  goto bad;
635	}
636      strlcpy (remote_ike_address, addr, sizeof remote_ike_address);
637      free (addr);
638
639      switch (policy_isakmp_sa->exch_type)
640	{
641	case ISAKMP_EXCH_AGGRESSIVE:
642	  phase_1 = "aggressive";
643	  break;
644
645	case ISAKMP_EXCH_ID_PROT:
646	  phase_1 = "main";
647	  break;
648	}
649
650      if (policy_isakmp_sa->initiator)
651        {
652	  id = policy_isakmp_sa->id_r;
653	  id_sz = policy_isakmp_sa->id_r_len;
654	}
655      else
656        {
657	  id = policy_isakmp_sa->id_i;
658	  id_sz = policy_isakmp_sa->id_i_len;
659	}
660
661      switch (id[0])
662        {
663	case IPSEC_ID_IPV4_ADDR:
664	  remote_id_type = "IPv4 address";
665
666	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
667	  my_inet_ntop4 (&net, remote_id_addr_upper,
668			 sizeof remote_id_addr_upper - 1, 1);
669	  my_inet_ntop4 (&net, remote_id_addr_lower,
670			 sizeof remote_id_addr_lower - 1, 1);
671	  remote_id = strdup (remote_id_addr_upper);
672	  if (!remote_id)
673  	    {
674	      log_error ("policy_callback: strdup (\"%s\") failed",
675			 remote_id_addr_upper);
676	      goto bad;
677	    }
678	  break;
679
680	case IPSEC_ID_IPV4_RANGE:
681	  remote_id_type = "IPv4 range";
682
683	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
684	  my_inet_ntop4 (&net, remote_id_addr_lower,
685			 sizeof remote_id_addr_lower - 1, 1);
686	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
687	  my_inet_ntop4 (&net, remote_id_addr_upper,
688			 sizeof remote_id_addr_upper - 1, 1);
689	  len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
690	    + 2;
691	  remote_id = calloc (len, sizeof (char));
692	  if (!remote_id)
693	    {
694	      log_error ("policy_callback: calloc (%d, %lu) failed", len,
695			 (unsigned long)sizeof (char));
696	      goto bad;
697	    }
698
699	  strlcpy (remote_id, remote_id_addr_lower, len);
700	  strlcat (remote_id, "-", len);
701	  strlcat (remote_id, remote_id_addr_upper, len);
702	  break;
703
704	case IPSEC_ID_IPV4_ADDR_SUBNET:
705	  remote_id_type = "IPv4 subnet";
706
707	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
708	  subnet = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
709	  net &= subnet;
710	  my_inet_ntop4 (&net, remote_id_addr_lower,
711			 sizeof remote_id_addr_lower - 1, 1);
712	  net |= ~subnet;
713	  my_inet_ntop4 (&net, remote_id_addr_upper,
714			 sizeof remote_id_addr_upper - 1, 1);
715	  len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
716	    + 2;
717	  remote_id = calloc (len, sizeof (char));
718	  if (!remote_id)
719	    {
720	      log_error ("policy_callback: calloc (%d, %lu) failed", len,
721			 (unsigned long)sizeof (char));
722	      goto bad;
723	    }
724
725	  strlcpy (remote_id, remote_id_addr_lower, len);
726	  strlcat (remote_id, "-", len);
727	  strlcat (remote_id, remote_id_addr_upper, len);
728	  break;
729
730	case IPSEC_ID_IPV6_ADDR:
731	  remote_id_type = "IPv6 address";
732	  my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
733			 remote_id_addr_upper, sizeof remote_id_addr_upper);
734	  strlcpy (remote_id_addr_lower, remote_id_addr_upper,
735		   sizeof remote_id_addr_lower);
736	  remote_id = strdup (remote_id_addr_upper);
737	  if (!remote_id)
738  	    {
739	      log_error ("policy_callback: strdup (\"%s\") failed",
740			 remote_id_addr_upper);
741	      goto bad;
742	    }
743	  break;
744
745	case IPSEC_ID_IPV6_RANGE:
746	  remote_id_type = "IPv6 range";
747
748	  my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
749			 remote_id_addr_lower,
750			 sizeof remote_id_addr_lower - 1);
751
752	  my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16,
753			 remote_id_addr_upper,
754			 sizeof remote_id_addr_upper - 1);
755
756	  len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
757	    + 2;
758	  remote_id = calloc (len, sizeof (char));
759	  if (!remote_id)
760	    {
761	      log_error ("policy_callback: calloc (%d, %lu) failed", len,
762			 (unsigned long)sizeof (char));
763	      goto bad;
764	    }
765
766	  strlcpy (remote_id, remote_id_addr_lower, len);
767	  strlcat (remote_id, "-", len);
768	  strlcat (remote_id, remote_id_addr_upper, len);
769	  break;
770
771	case IPSEC_ID_IPV6_ADDR_SUBNET:
772	{
773	  struct in6_addr net, mask;
774
775	  remote_id_type = "IPv6 subnet";
776
777	  bcopy (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, &net, sizeof (net));
778	  bcopy (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 16, &mask,
779		 sizeof (mask));
780
781	  for (i = 0; i < 16; i++)
782	    net.s6_addr[i] &= mask.s6_addr[i];
783
784	  my_inet_ntop6 ((unsigned char *) &net, remote_id_addr_lower,
785			 sizeof remote_id_addr_lower - 1);
786
787	  for (i = 0; i < 16; i++)
788	    net.s6_addr[i] |= ~mask.s6_addr[i];
789
790	  my_inet_ntop6 ((unsigned char *) &net, remote_id_addr_upper,
791			 sizeof remote_id_addr_upper - 1);
792
793	  len = strlen (remote_id_addr_upper) + strlen (remote_id_addr_lower)
794	    + 2;
795	  remote_id = calloc (len, sizeof (char));
796	  if (!remote_id)
797	    {
798	      log_error ("policy_callback: calloc (%d, %lu) failed", len,
799			 (unsigned long)sizeof (char));
800	      goto bad;
801	    }
802
803	  strlcpy (remote_id, remote_id_addr_lower, len);
804	  strlcat (remote_id, "-", len);
805	  strlcat (remote_id, remote_id_addr_upper, len);
806	  break;
807	}
808
809	case IPSEC_ID_FQDN:
810	  remote_id_type = "FQDN";
811	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
812			      sizeof (char));
813	  if (!remote_id)
814	    {
815	      log_error ("policy_callback: calloc (%lu, %lu) failed",
816		 (unsigned long)id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
817		 (unsigned long)sizeof (char));
818	      goto bad;
819	    }
820	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
821		  id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
822	  break;
823
824	case IPSEC_ID_USER_FQDN:
825	  remote_id_type = "User FQDN";
826	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
827			      sizeof (char));
828	  if (!remote_id)
829	    {
830	      log_error ("policy_callback: calloc (%lu, %lu) failed",
831		 (unsigned long)id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
832		 (unsigned long)sizeof (char));
833	      goto bad;
834	    }
835	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
836		  id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
837	  break;
838
839	case IPSEC_ID_DER_ASN1_DN:
840	  remote_id_type = "ASN1 DN";
841
842	  remote_id = x509_DN_string (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
843				      id_sz - ISAKMP_ID_DATA_OFF
844				      + ISAKMP_GEN_SZ);
845	  if (!remote_id)
846	    {
847	      LOG_DBG ((LOG_POLICY, 50,
848			"policy_callback: failed to decode name"));
849	      goto bad;
850	    }
851	  break;
852
853	case IPSEC_ID_DER_ASN1_GN: /* XXX */
854	  remote_id_type = "ASN1 GN";
855	  break;
856
857	case IPSEC_ID_KEY_ID:
858	  remote_id_type = "Key ID";
859	  remote_id
860	    = calloc (2 * (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
861		      sizeof (char));
862	  if (!remote_id)
863	    {
864	      log_error ("policy_callback: calloc (%lu, %lu) failed",
865		 2 * ((unsigned long)id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
866		 (unsigned long)sizeof (char));
867	      goto bad;
868	    }
869	  /* Does it contain any non-printable characters ? */
870	  for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
871	    if (!isprint (*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + i)))
872	      break;
873	  if (i >= id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ)
874	    {
875	      memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
876		      id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
877	      break;
878	    }
879	  /* Non-printable characters, convert to hex */
880          for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
881	    {
882	      remote_id[2 * i]
883		= hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4];
884	      remote_id[2 * i + 1]
885		= hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF];
886	    }
887	  break;
888
889	default:
890	  log_print ("policy_callback: unknown remote ID type %u", id[0]);
891	  goto bad;
892	}
893
894      switch (id[1])
895        {
896	case IPPROTO_TCP:
897	  remote_id_proto = "tcp";
898	  break;
899
900	case IPPROTO_UDP:
901	  remote_id_proto = "udp";
902	  break;
903
904#ifdef IPPROTO_ETHERIP
905	case IPPROTO_ETHERIP:
906	  remote_id_proto = "etherip";
907	  break;
908#endif
909
910 	default:
911	  snprintf (remote_id_proto_num, 3, "%d", id[1]);
912	  remote_id_proto = remote_id_proto_num;
913	  break;
914	}
915
916      snprintf (remote_id_port, sizeof remote_id_port - 1, "%u",
917		decode_16 (id + 2));
918
919      if (policy_exchange->initiator)
920        {
921	  initiator = "yes";
922	  idlocal = ie->id_ci;
923	  idremote = ie->id_cr;
924	  idlocalsz = ie->id_ci_sz;
925	  idremotesz = ie->id_cr_sz;
926        }
927      else
928        {
929	  initiator = "no";
930	  idlocal = ie->id_cr;
931	  idremote = ie->id_ci;
932	  idlocalsz = ie->id_cr_sz;
933	  idremotesz = ie->id_ci_sz;
934	}
935
936      /* Initialize the ID variables.  */
937      if (idremote)
938        {
939	  switch (GET_ISAKMP_ID_TYPE (idremote))
940	    {
941	    case IPSEC_ID_IPV4_ADDR:
942	      remote_filter_type = "IPv4 address";
943
944	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
945	      my_inet_ntop4 (&net, remote_filter_addr_upper,
946			     sizeof remote_filter_addr_upper - 1, 1);
947	      my_inet_ntop4 (&net, remote_filter_addr_lower,
948			     sizeof remote_filter_addr_lower - 1, 1);
949	      remote_filter = strdup (remote_filter_addr_upper);
950	      if (!remote_filter)
951	        {
952		  log_error ("policy_callback: strdup (\"%s\") failed",
953			     remote_filter_addr_upper);
954		  goto bad;
955		}
956	      break;
957
958	    case IPSEC_ID_IPV4_RANGE:
959	      remote_filter_type = "IPv4 range";
960
961	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
962	      my_inet_ntop4 (&net, remote_filter_addr_lower,
963			     sizeof remote_filter_addr_lower - 1, 1);
964	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
965	      my_inet_ntop4 (&net, remote_filter_addr_upper,
966			     sizeof remote_filter_addr_upper - 1, 1);
967	      len = strlen (remote_filter_addr_upper)
968		+ strlen (remote_filter_addr_lower) + 2;
969	      remote_filter = calloc (len, sizeof (char));
970	      if (!remote_filter)
971	        {
972		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
973			     (unsigned long)sizeof (char));
974		  goto bad;
975		}
976
977	      strlcpy (remote_filter, remote_filter_addr_lower, len);
978	      strlcat (remote_filter, "-", len);
979	      strlcat (remote_filter, remote_filter_addr_upper, len);
980	      break;
981
982	    case IPSEC_ID_IPV4_ADDR_SUBNET:
983	      remote_filter_type = "IPv4 subnet";
984
985	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
986	      subnet = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
987	      net &= subnet;
988	      my_inet_ntop4 (&net, remote_filter_addr_lower,
989			     sizeof remote_filter_addr_lower - 1, 1);
990	      net |= ~subnet;
991	      my_inet_ntop4 (&net, remote_filter_addr_upper,
992			     sizeof remote_filter_addr_upper - 1, 1);
993	      len = strlen (remote_filter_addr_upper)
994		+ strlen (remote_filter_addr_lower) + 2;
995	      remote_filter = calloc (len, sizeof (char));
996	      if (!remote_filter)
997	        {
998		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
999			     (unsigned long)sizeof (char));
1000		  goto bad;
1001		}
1002	      strlcpy (remote_filter, remote_filter_addr_lower, len);
1003	      strlcat (remote_filter, "-", len);
1004	      strlcat (remote_filter, remote_filter_addr_upper, len);
1005	      break;
1006
1007	    case IPSEC_ID_IPV6_ADDR:
1008	      remote_filter_type = "IPv6 address";
1009	      my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF,
1010			     remote_filter_addr_upper,
1011			     sizeof remote_filter_addr_upper - 1);
1012	      strlcpy (remote_filter_addr_lower, remote_filter_addr_upper,
1013		       sizeof remote_filter_addr_lower);
1014	      remote_filter = strdup (remote_filter_addr_upper);
1015	      if (!remote_filter)
1016	        {
1017		  log_error ("policy_callback: strdup (\"%s\") failed",
1018			     remote_filter_addr_upper);
1019		  goto bad;
1020		}
1021	      break;
1022
1023	    case IPSEC_ID_IPV6_RANGE:
1024	      remote_filter_type = "IPv6 range";
1025
1026	      my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF,
1027			     remote_filter_addr_lower,
1028			     sizeof remote_filter_addr_lower - 1);
1029
1030	      my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF + 16,
1031			     remote_filter_addr_upper,
1032			     sizeof remote_filter_addr_upper - 1);
1033
1034	      len = strlen (remote_filter_addr_upper)
1035		+ strlen (remote_filter_addr_lower) + 2;
1036	      remote_filter = calloc (len, sizeof (char));
1037	      if (!remote_filter)
1038		{
1039		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1040			     (unsigned long)sizeof (char));
1041		  goto bad;
1042		}
1043
1044	      strlcpy (remote_filter, remote_filter_addr_lower, len);
1045	      strlcat (remote_filter, "-", len);
1046	      strlcat (remote_filter, remote_filter_addr_upper, len);
1047	      break;
1048
1049	    case IPSEC_ID_IPV6_ADDR_SUBNET:
1050	    {
1051	      struct in6_addr net, mask;
1052
1053	      remote_filter_type = "IPv6 subnet";
1054
1055	      bcopy (idremote + ISAKMP_ID_DATA_OFF, &net, sizeof (net));
1056	      bcopy (idremote + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof (mask));
1057
1058	      for (i = 0; i < 16; i++)
1059		net.s6_addr[i] &= mask.s6_addr[i];
1060
1061	      my_inet_ntop6 ((unsigned char *) &net, remote_filter_addr_lower,
1062			     sizeof remote_filter_addr_lower - 1);
1063
1064	      for (i = 0; i < 16; i++)
1065		net.s6_addr[i] |= ~mask.s6_addr[i];
1066
1067	      my_inet_ntop6 ((unsigned char *) &net, remote_filter_addr_upper,
1068			     sizeof remote_filter_addr_upper - 1);
1069
1070	      len = strlen (remote_filter_addr_upper)
1071		+ strlen (remote_filter_addr_lower) + 2;
1072	      remote_filter = calloc (len, sizeof (char));
1073	      if (!remote_filter)
1074		{
1075		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1076			     (unsigned long)sizeof (char));
1077		  goto bad;
1078		}
1079
1080	      strlcpy (remote_filter, remote_filter_addr_lower, len);
1081	      strlcat (remote_filter, "-", len);
1082	      strlcat (remote_filter, remote_filter_addr_upper, len);
1083	      break;
1084	    }
1085
1086	    case IPSEC_ID_FQDN:
1087	      remote_filter_type = "FQDN";
1088	      remote_filter = malloc (idremotesz - ISAKMP_ID_DATA_OFF + 1);
1089	      if (!remote_filter)
1090	        {
1091		  log_error ("policy_callback: malloc (%lu) failed",
1092			     (unsigned long)idremotesz - ISAKMP_ID_DATA_OFF + 1);
1093		  goto bad;
1094		}
1095	      memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
1096		      idremotesz - ISAKMP_ID_DATA_OFF);
1097	      remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
1098	      break;
1099
1100	    case IPSEC_ID_USER_FQDN:
1101	      remote_filter_type = "User FQDN";
1102	      remote_filter = malloc (idremotesz - ISAKMP_ID_DATA_OFF + 1);
1103	      if (!remote_filter)
1104	        {
1105		  log_error ("policy_callback: malloc (%lu) failed",
1106			     (unsigned long)idremotesz - ISAKMP_ID_DATA_OFF + 1);
1107		  goto bad;
1108		}
1109	      memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
1110		      idremotesz - ISAKMP_ID_DATA_OFF);
1111	      remote_filter[idremotesz - ISAKMP_ID_DATA_OFF] = '\0';
1112	      break;
1113
1114	    case IPSEC_ID_DER_ASN1_DN:
1115	      remote_filter_type = "ASN1 DN";
1116
1117	      remote_filter = x509_DN_string (idremote + ISAKMP_ID_DATA_OFF,
1118					      idremotesz - ISAKMP_ID_DATA_OFF);
1119	      if (!remote_filter)
1120	        {
1121		  LOG_DBG ((LOG_POLICY, 50,
1122			    "policy_callback: failed to decode name"));
1123		  goto bad;
1124		}
1125	      break;
1126
1127	    case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
1128	      remote_filter_type = "ASN1 GN";
1129	      break;
1130
1131	    case IPSEC_ID_KEY_ID:
1132	      remote_filter_type = "Key ID";
1133	      remote_filter
1134		= calloc (2 * (idremotesz - ISAKMP_ID_DATA_OFF) + 1,
1135			  sizeof (char));
1136	      if (!remote_filter)
1137	        {
1138		  log_error ("policy_callback: calloc (%lu, %lu) failed",
1139		     2 * ((unsigned long)idremotesz - ISAKMP_ID_DATA_OFF) + 1,
1140		     (unsigned long)sizeof (char));
1141		  goto bad;
1142	        }
1143	      /* Does it contain any non-printable characters ? */
1144	      for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
1145		if (!isprint (*(idremote + ISAKMP_ID_DATA_OFF + i)))
1146		  break;
1147	      if (i >= idremotesz - ISAKMP_ID_DATA_OFF)
1148	        {
1149		  memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
1150			  idremotesz - ISAKMP_ID_DATA_OFF);
1151		  break;
1152		}
1153	      /* Non-printable characters, convert to hex */
1154              for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
1155	        {
1156		  remote_filter[2 * i]
1157		    = hextab[*(idremote + ISAKMP_ID_DATA_OFF) >> 4];
1158		  remote_filter[2 * i + 1]
1159		    = hextab[*(idremote + ISAKMP_ID_DATA_OFF) & 0xF];
1160	        }
1161	      break;
1162
1163	    default:
1164	      log_print ("policy_callback: unknown Remote ID type %u",
1165			 GET_ISAKMP_ID_TYPE (idremote));
1166	      goto bad;
1167	    }
1168
1169	  switch (idremote[ISAKMP_GEN_SZ + 1])
1170	    {
1171	    case IPPROTO_TCP:
1172	      remote_filter_proto = "tcp";
1173	      break;
1174
1175	    case IPPROTO_UDP:
1176	      remote_filter_proto = "udp";
1177	      break;
1178
1179#ifdef IPPROTO_ETHERIP
1180	    case IPPROTO_ETHERIP:
1181	      remote_filter_proto = "etherip";
1182	      break;
1183#endif
1184
1185 	    default:
1186	      snprintf (remote_filter_proto_num, 3, "%d",
1187		       idremote[ISAKMP_GEN_SZ + 1]);
1188	      remote_filter_proto = remote_filter_proto_num;
1189	      break;
1190	    }
1191
1192	  snprintf (remote_filter_port, sizeof remote_filter_port - 1,
1193		    "%u", decode_16 (idremote + ISAKMP_GEN_SZ + 2));
1194	}
1195      else
1196        {
1197	  policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
1198	  switch (sin->sa_family)
1199	    {
1200	    case AF_INET:
1201	      remote_filter_type = "IPv4 address";
1202	      break;
1203	    case AF_INET6:
1204	      remote_filter_type = "IPv6 address";
1205	      break;
1206	    default:
1207	      log_print ("policy_callback: unsupported protocol family %d",
1208			 sin->sa_family);
1209	      goto bad;
1210	    }
1211	  if (sockaddr2text (sin, &addr, 1))
1212	    {
1213	      log_error ("policy_callback: sockaddr2text failed");
1214	      goto bad;
1215	    }
1216	  memcpy (remote_filter_addr_upper, addr,
1217		  sizeof remote_filter_addr_upper);
1218	  memcpy (remote_filter_addr_lower, addr,
1219		  sizeof remote_filter_addr_lower);
1220	  free (addr);
1221	  remote_filter = strdup (remote_filter_addr_upper);
1222	  if (!remote_filter)
1223	    {
1224	      log_error ("policy_callback: strdup (\"%s\") failed",
1225			 remote_filter_addr_upper);
1226	      goto bad;
1227	    }
1228	}
1229
1230      if (idlocal)
1231        {
1232	  switch (GET_ISAKMP_ID_TYPE (idlocal))
1233	    {
1234	    case IPSEC_ID_IPV4_ADDR:
1235	      local_filter_type = "IPv4 address";
1236
1237	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1238	      my_inet_ntop4 (&net, local_filter_addr_upper,
1239			     sizeof local_filter_addr_upper - 1, 1);
1240	      my_inet_ntop4 (&net, local_filter_addr_lower,
1241			     sizeof local_filter_addr_upper - 1, 1);
1242	      local_filter = strdup (local_filter_addr_upper);
1243	      if (!local_filter)
1244	        {
1245		  log_error ("policy_callback: strdup (\"%s\") failed",
1246			     local_filter_addr_upper);
1247		  goto bad;
1248		}
1249	      break;
1250
1251	    case IPSEC_ID_IPV4_RANGE:
1252	      local_filter_type = "IPv4 range";
1253
1254	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1255	      my_inet_ntop4 (&net, local_filter_addr_lower,
1256			     sizeof local_filter_addr_lower - 1, 1);
1257	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
1258	      my_inet_ntop4 (&net, local_filter_addr_upper,
1259			     sizeof local_filter_addr_upper - 1, 1);
1260	      len = strlen (local_filter_addr_upper)
1261		+ strlen (local_filter_addr_lower) + 2;
1262	      local_filter = calloc (len, sizeof (char));
1263	      if (!local_filter)
1264	        {
1265		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1266			     (unsigned long)sizeof (char));
1267		  goto bad;
1268		}
1269	      strlcpy (local_filter, local_filter_addr_lower, len);
1270	      strlcat (local_filter, "-", len);
1271	      strlcat (local_filter, local_filter_addr_upper, len);
1272	      break;
1273
1274	    case IPSEC_ID_IPV4_ADDR_SUBNET:
1275	      local_filter_type = "IPv4 subnet";
1276
1277	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1278	      subnet = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
1279	      net &= subnet;
1280	      my_inet_ntop4 (&net, local_filter_addr_lower,
1281			     sizeof local_filter_addr_lower - 1, 1);
1282	      net |= ~subnet;
1283	      my_inet_ntop4 (&net, local_filter_addr_upper,
1284			     sizeof local_filter_addr_upper - 1, 1);
1285	      len = strlen (local_filter_addr_upper)
1286		+ strlen (local_filter_addr_lower) + 2;
1287	      local_filter = calloc (len, sizeof (char));
1288	      if (!local_filter)
1289	        {
1290		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1291			     (unsigned long)sizeof (char));
1292		  goto bad;
1293		}
1294	      strlcpy (local_filter, local_filter_addr_lower, len);
1295	      strlcat (local_filter, "-", len);
1296	      strlcat (local_filter, local_filter_addr_upper, len);
1297	      break;
1298
1299	    case IPSEC_ID_IPV6_ADDR:
1300	      local_filter_type = "IPv6 address";
1301	      my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF,
1302			     local_filter_addr_upper,
1303			     sizeof local_filter_addr_upper - 1);
1304	      strlcpy (local_filter_addr_lower, local_filter_addr_upper,
1305		       sizeof local_filter_addr_lower);
1306	      local_filter = strdup (local_filter_addr_upper);
1307	      if (!local_filter)
1308	        {
1309		  log_error ("policy_callback: strdup (\"%s\") failed",
1310			     local_filter_addr_upper);
1311		  goto bad;
1312		}
1313	      break;
1314
1315	    case IPSEC_ID_IPV6_RANGE:
1316	      local_filter_type = "IPv6 range";
1317
1318	      my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF,
1319			     local_filter_addr_lower,
1320			     sizeof local_filter_addr_lower - 1);
1321
1322	      my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF + 16,
1323			     local_filter_addr_upper,
1324			     sizeof local_filter_addr_upper - 1);
1325
1326	      len = strlen (local_filter_addr_upper)
1327		+ strlen (local_filter_addr_lower) + 2;
1328	      local_filter = calloc (len, sizeof (char));
1329	      if (!local_filter)
1330		{
1331		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1332			     (unsigned long)sizeof (char));
1333		  goto bad;
1334		}
1335
1336	      strlcpy (local_filter, local_filter_addr_lower, len);
1337	      strlcat (local_filter, "-", len);
1338	      strlcat (local_filter, local_filter_addr_upper, len);
1339	      break;
1340
1341	    case IPSEC_ID_IPV6_ADDR_SUBNET:
1342	    {
1343	      struct in6_addr net, mask;
1344
1345	      local_filter_type = "IPv6 subnet";
1346
1347	      bcopy (idlocal + ISAKMP_ID_DATA_OFF, &net, sizeof (net));
1348	      bcopy (idlocal + ISAKMP_ID_DATA_OFF + 16, &mask, sizeof (mask));
1349
1350	      for (i = 0; i < 16; i++)
1351		net.s6_addr[i] &= mask.s6_addr[i];
1352
1353	      my_inet_ntop6 ((unsigned char *) &net, local_filter_addr_lower,
1354			     sizeof local_filter_addr_lower - 1);
1355
1356	      for (i = 0; i < 16; i++)
1357		net.s6_addr[i] |= ~mask.s6_addr[i];
1358
1359	      my_inet_ntop6 ((unsigned char *) &net, local_filter_addr_upper,
1360			     sizeof local_filter_addr_upper - 1);
1361
1362	      len = strlen (local_filter_addr_upper)
1363		+ strlen (local_filter_addr_lower) + 2;
1364	      local_filter = calloc (len, sizeof (char));
1365	      if (!local_filter)
1366		{
1367		  log_error ("policy_callback: calloc (%d, %lu) failed", len,
1368			     (unsigned long)sizeof (char));
1369		  goto bad;
1370		}
1371
1372	      strlcpy (local_filter, local_filter_addr_lower, len);
1373	      strlcat (local_filter, "-", len);
1374	      strlcat (local_filter, local_filter_addr_upper, len);
1375	      break;
1376	    }
1377
1378	    case IPSEC_ID_FQDN:
1379	      local_filter_type = "FQDN";
1380	      local_filter = malloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1);
1381	      if (!local_filter)
1382	        {
1383		  log_error ("policy_callback: malloc (%lu) failed",
1384			     (unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF + 1);
1385		  goto bad;
1386		}
1387	      memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
1388		      idlocalsz - ISAKMP_ID_DATA_OFF);
1389	      local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
1390	      break;
1391
1392	    case IPSEC_ID_USER_FQDN:
1393	      local_filter_type = "User FQDN";
1394	      local_filter = malloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1);
1395	      if (!local_filter)
1396	        {
1397		  log_error ("policy_callback: malloc (%lu) failed",
1398			     (unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF + 1);
1399		  goto bad;
1400		}
1401	      memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
1402		      idlocalsz - ISAKMP_ID_DATA_OFF);
1403	      local_filter[idlocalsz - ISAKMP_ID_DATA_OFF] = '\0';
1404	      break;
1405
1406	    case IPSEC_ID_DER_ASN1_DN:
1407	      local_filter_type = "ASN1 DN";
1408
1409	      local_filter = x509_DN_string (idlocal + ISAKMP_ID_DATA_OFF,
1410					     idlocalsz - ISAKMP_ID_DATA_OFF);
1411	      if (!local_filter)
1412	        {
1413		  LOG_DBG ((LOG_POLICY, 50,
1414			    "policy_callback: failed to decode name"));
1415		  goto bad;
1416		}
1417	      break;
1418
1419	    case IPSEC_ID_DER_ASN1_GN:
1420	      /* XXX -- not sure what's in this.  */
1421	      local_filter_type = "ASN1 GN";
1422	      break;
1423
1424	    case IPSEC_ID_KEY_ID:
1425	      local_filter_type = "Key ID";
1426	      local_filter = calloc (2 * (idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
1427				     sizeof (char));
1428	      if (!local_filter)
1429	        {
1430		  log_error ("policy_callback: calloc (%lu, %lu) failed",
1431		     2 * ((unsigned long)idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
1432		     (unsigned long)sizeof (char));
1433		  goto bad;
1434	        }
1435	      /* Does it contain any non-printable characters ? */
1436	      for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
1437		if (!isprint (*(idlocal + ISAKMP_ID_DATA_OFF + i)))
1438		  break;
1439	      if (i >= idlocalsz - ISAKMP_ID_DATA_OFF)
1440	        {
1441		  memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
1442			  idlocalsz - ISAKMP_ID_DATA_OFF);
1443		  break;
1444		}
1445	      /* Non-printable characters, convert to hex */
1446              for (i = 0; i < idlocalsz - ISAKMP_ID_DATA_OFF; i++)
1447	        {
1448		  local_filter[2 * i]
1449		    = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) >> 4];
1450		  local_filter[2 * i + 1]
1451		    = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) & 0xF];
1452	        }
1453	      break;
1454
1455	    default:
1456	      log_print ("policy_callback: unknown Local ID type %u",
1457			 GET_ISAKMP_ID_TYPE (idlocal));
1458	      goto bad;
1459	    }
1460
1461	  switch (idlocal[ISAKMP_GEN_SZ + 1])
1462	    {
1463	    case IPPROTO_TCP:
1464	      local_filter_proto = "tcp";
1465	      break;
1466
1467	    case IPPROTO_UDP:
1468	      local_filter_proto = "udp";
1469	      break;
1470
1471#ifdef IPPROTO_ETHERIP
1472	    case IPPROTO_ETHERIP:
1473	      local_filter_proto = "etherip";
1474	      break;
1475#endif
1476
1477 	    default:
1478	      snprintf (local_filter_proto_num, 3, "%d",
1479		       idlocal[ISAKMP_GEN_SZ + 1]);
1480	      local_filter_proto = local_filter_proto_num;
1481	      break;
1482	    }
1483
1484	  snprintf (local_filter_port, sizeof local_filter_port - 1,
1485		    "%u", decode_16 (idlocal + ISAKMP_GEN_SZ + 2));
1486	}
1487      else
1488        {
1489	  policy_sa->transport->vtbl->get_src (policy_sa->transport,
1490					       (struct sockaddr **)&sin);
1491	  switch (sin->sa_family)
1492	    {
1493	    case AF_INET:
1494	      local_filter_type = "IPv4 address";
1495	      break;
1496	    case AF_INET6:
1497	      local_filter_type = "IPv6 address";
1498	      break;
1499	    default:
1500	      log_print ("policy_callback: unsupported protocol family %d",
1501			 sin->sa_family);
1502	      goto bad;
1503	    }
1504
1505	  if (sockaddr2text (sin, &addr, 1))
1506	    {
1507	      log_error ("policy_callback: sockaddr2text failed");
1508	      goto bad;
1509	    }
1510	  memcpy (local_filter_addr_upper, addr,
1511		  sizeof local_filter_addr_upper);
1512	  memcpy (local_filter_addr_lower, addr,
1513		  sizeof local_filter_addr_lower);
1514	  free (addr);
1515	  local_filter = strdup (local_filter_addr_upper);
1516	  if (!local_filter)
1517	    {
1518	      log_error ("policy_callback: strdup (\"%s\") failed",
1519			 local_filter_addr_upper);
1520	      goto bad;
1521	    }
1522        }
1523
1524      LOG_DBG ((LOG_POLICY, 80, "Policy context (action attributes):"));
1525      LOG_DBG ((LOG_POLICY, 80, "esp_present == %s", esp_present));
1526      LOG_DBG ((LOG_POLICY, 80, "ah_present == %s", ah_present));
1527      LOG_DBG ((LOG_POLICY, 80, "comp_present == %s", comp_present));
1528      LOG_DBG ((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg));
1529      LOG_DBG ((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg));
1530      LOG_DBG ((LOG_POLICY, 80, "comp_alg == %s", comp_alg));
1531      LOG_DBG ((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg));
1532      LOG_DBG ((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg));
1533      LOG_DBG ((LOG_POLICY, 80, "ah_life_seconds == %s", ah_life_seconds));
1534      LOG_DBG ((LOG_POLICY, 80, "ah_life_kbytes == %s", ah_life_kbytes));
1535      LOG_DBG ((LOG_POLICY, 80, "esp_life_seconds == %s", esp_life_seconds));
1536      LOG_DBG ((LOG_POLICY, 80, "esp_life_kbytes == %s", esp_life_kbytes));
1537      LOG_DBG ((LOG_POLICY, 80, "comp_life_seconds == %s", comp_life_seconds));
1538      LOG_DBG ((LOG_POLICY, 80, "comp_life_kbytes == %s", comp_life_kbytes));
1539      LOG_DBG ((LOG_POLICY, 80, "ah_encapsulation == %s", ah_encapsulation));
1540      LOG_DBG ((LOG_POLICY, 80, "esp_encapsulation == %s", esp_encapsulation));
1541      LOG_DBG ((LOG_POLICY, 80, "comp_encapsulation == %s",
1542		comp_encapsulation));
1543      LOG_DBG ((LOG_POLICY, 80, "comp_dict_size == %s", comp_dict_size));
1544      LOG_DBG ((LOG_POLICY, 80, "comp_private_alg == %s", comp_private_alg));
1545      LOG_DBG ((LOG_POLICY, 80, "ah_key_length == %s", ah_key_length));
1546      LOG_DBG ((LOG_POLICY, 80, "ah_key_rounds == %s", ah_key_rounds));
1547      LOG_DBG ((LOG_POLICY, 80, "esp_key_length == %s", esp_key_length));
1548      LOG_DBG ((LOG_POLICY, 80, "esp_key_rounds == %s", esp_key_rounds));
1549      LOG_DBG ((LOG_POLICY, 80, "ah_group_desc == %s", ah_group_desc));
1550      LOG_DBG ((LOG_POLICY, 80, "esp_group_desc == %s", esp_group_desc));
1551      LOG_DBG ((LOG_POLICY, 80, "comp_group_desc == %s", comp_group_desc));
1552      LOG_DBG ((LOG_POLICY, 80, "ah_ecn == %s", ah_ecn));
1553      LOG_DBG ((LOG_POLICY, 80, "esp_ecn == %s", esp_ecn));
1554      LOG_DBG ((LOG_POLICY, 80, "comp_ecn == %s", comp_ecn));
1555      LOG_DBG ((LOG_POLICY, 80, "remote_filter_type == %s",
1556		remote_filter_type));
1557      LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_upper == %s",
1558		remote_filter_addr_upper));
1559      LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_lower == %s",
1560		remote_filter_addr_lower));
1561      LOG_DBG ((LOG_POLICY, 80, "remote_filter == %s",
1562		(remote_filter ? remote_filter : "")));
1563      LOG_DBG ((LOG_POLICY, 80, "remote_filter_port == %s",
1564		remote_filter_port));
1565      LOG_DBG ((LOG_POLICY, 80, "remote_filter_proto == %s",
1566		remote_filter_proto));
1567      LOG_DBG ((LOG_POLICY, 80, "local_filter_type == %s", local_filter_type));
1568      LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_upper == %s",
1569		local_filter_addr_upper));
1570      LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_lower == %s",
1571		local_filter_addr_lower));
1572      LOG_DBG ((LOG_POLICY, 80, "local_filter == %s",
1573		(local_filter ? local_filter : "")));
1574      LOG_DBG ((LOG_POLICY, 80, "local_filter_port == %s", local_filter_port));
1575      LOG_DBG ((LOG_POLICY, 80, "local_filter_proto == %s",
1576		local_filter_proto));
1577      LOG_DBG ((LOG_POLICY, 80, "remote_id_type == %s", remote_id_type));
1578      LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_upper == %s",
1579		remote_id_addr_upper));
1580      LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_lower == %s",
1581		remote_id_addr_lower));
1582      LOG_DBG ((LOG_POLICY, 80, "remote_id == %s",
1583		(remote_id ? remote_id : "")));
1584      LOG_DBG ((LOG_POLICY, 80, "remote_id_port == %s", remote_id_port));
1585      LOG_DBG ((LOG_POLICY, 80, "remote_id_proto == %s", remote_id_proto));
1586      LOG_DBG ((LOG_POLICY, 80, "remote_negotiation_address == %s",
1587		remote_ike_address));
1588      LOG_DBG ((LOG_POLICY, 80, "local_negotiation_address == %s",
1589		local_ike_address));
1590      LOG_DBG ((LOG_POLICY, 80, "pfs == %s", pfs));
1591      LOG_DBG ((LOG_POLICY, 80, "initiator == %s", initiator));
1592      LOG_DBG ((LOG_POLICY, 80, "phase1_group_desc == %s", phase1_group));
1593
1594      /* Unset dirty now.  */
1595      dirty = 0;
1596    }
1597
1598  if (strcmp (name, "phase_1") == 0)
1599    return phase_1;
1600
1601  if (strcmp (name, "GMTTimeOfDay") == 0)
1602    {
1603      tt = time ((time_t) NULL);
1604      strftime (mytimeofday, 14, "%Y%m%d%H%M%S", gmtime (&tt));
1605      return mytimeofday;
1606    }
1607
1608  if (strcmp (name, "LocalTimeOfDay") == 0)
1609    {
1610      tt = time ((time_t) NULL);
1611      strftime (mytimeofday, 14, "%Y%m%d%H%M%S", localtime (&tt));
1612      return mytimeofday;
1613    }
1614
1615  if (strcmp (name, "initiator") == 0)
1616    return initiator;
1617
1618  if (strcmp (name, "pfs") == 0)
1619    return pfs;
1620
1621  if (strcmp (name, "app_domain") == 0)
1622    return "IPsec policy";
1623
1624  if (strcmp (name, "doi") == 0)
1625    return "ipsec";
1626
1627  if (strcmp (name, "esp_present") == 0)
1628    return esp_present;
1629
1630  if (strcmp (name, "ah_present") == 0)
1631    return ah_present;
1632
1633  if (strcmp (name, "comp_present") == 0)
1634    return comp_present;
1635
1636  if (strcmp (name, "ah_hash_alg") == 0)
1637    return ah_hash_alg;
1638
1639  if (strcmp (name, "ah_auth_alg") == 0)
1640    return ah_auth_alg;
1641
1642  if (strcmp (name, "esp_auth_alg") == 0)
1643    return esp_auth_alg;
1644
1645  if (strcmp (name, "esp_enc_alg") == 0)
1646    return esp_enc_alg;
1647
1648  if (strcmp (name, "comp_alg") == 0)
1649    return comp_alg;
1650
1651  if (strcmp (name, "ah_life_kbytes") == 0)
1652    return ah_life_kbytes;
1653
1654  if (strcmp (name, "ah_life_seconds") == 0)
1655    return ah_life_seconds;
1656
1657  if (strcmp (name, "esp_life_kbytes") == 0)
1658    return esp_life_kbytes;
1659
1660  if (strcmp (name, "esp_life_seconds") == 0)
1661    return esp_life_seconds;
1662
1663  if (strcmp (name, "comp_life_kbytes") == 0)
1664    return comp_life_kbytes;
1665
1666  if (strcmp (name, "comp_life_seconds") == 0)
1667    return comp_life_seconds;
1668
1669  if (strcmp (name, "ah_encapsulation") == 0)
1670    return ah_encapsulation;
1671
1672  if (strcmp (name, "esp_encapsulation") == 0)
1673    return esp_encapsulation;
1674
1675  if (strcmp (name, "comp_encapsulation") == 0)
1676    return comp_encapsulation;
1677
1678  if (strcmp (name, "ah_key_length") == 0)
1679    return ah_key_length;
1680
1681  if (strcmp (name, "ah_key_rounds") == 0)
1682    return ah_key_rounds;
1683
1684  if (strcmp (name, "esp_key_length") == 0)
1685    return esp_key_length;
1686
1687  if (strcmp (name, "esp_key_rounds") == 0)
1688    return esp_key_rounds;
1689
1690  if (strcmp (name, "comp_dict_size") == 0)
1691    return comp_dict_size;
1692
1693  if (strcmp (name, "comp_private_alg") == 0)
1694    return comp_private_alg;
1695
1696  if (strcmp (name, "remote_filter_type") == 0)
1697    return remote_filter_type;
1698
1699  if (strcmp (name, "remote_filter") == 0)
1700    return (remote_filter ? remote_filter : "");
1701
1702  if (strcmp (name, "remote_filter_addr_upper") == 0)
1703    return remote_filter_addr_upper;
1704
1705  if (strcmp (name, "remote_filter_addr_lower") == 0)
1706    return remote_filter_addr_lower;
1707
1708  if (strcmp (name, "remote_filter_port") == 0)
1709    return remote_filter_port;
1710
1711  if (strcmp (name, "remote_filter_proto") == 0)
1712    return remote_filter_proto;
1713
1714  if (strcmp (name, "local_filter_type") == 0)
1715    return local_filter_type;
1716
1717  if (strcmp (name, "local_filter") == 0)
1718    return (local_filter ? local_filter : "");
1719
1720  if (strcmp (name, "local_filter_addr_upper") == 0)
1721    return local_filter_addr_upper;
1722
1723  if (strcmp (name, "local_filter_addr_lower") == 0)
1724    return local_filter_addr_lower;
1725
1726  if (strcmp (name, "local_filter_port") == 0)
1727    return local_filter_port;
1728
1729  if (strcmp (name, "local_filter_proto") == 0)
1730    return local_filter_proto;
1731
1732  if (strcmp (name, "remote_ike_address") == 0)
1733    return remote_ike_address;
1734
1735  if (strcmp (name, "remote_negotiation_address") == 0)
1736    return remote_ike_address;
1737
1738  if (strcmp (name, "local_ike_address") == 0)
1739    return local_ike_address;
1740
1741  if (strcmp (name, "local_negotiation_address") == 0)
1742    return local_ike_address;
1743
1744  if (strcmp (name, "remote_id_type") == 0)
1745    return remote_id_type;
1746
1747  if (strcmp (name, "remote_id") == 0)
1748    return (remote_id ? remote_id : "");
1749
1750  if (strcmp (name, "remote_id_addr_upper") == 0)
1751    return remote_id_addr_upper;
1752
1753  if (strcmp (name, "remote_id_addr_lower") == 0)
1754    return remote_id_addr_lower;
1755
1756  if (strcmp (name, "remote_id_port") == 0)
1757    return remote_id_port;
1758
1759  if (strcmp (name, "remote_id_proto") == 0)
1760    return remote_id_proto;
1761
1762  if (strcmp (name, "phase1_group_desc") == 0)
1763    return phase1_group;
1764
1765  if (strcmp (name, "esp_group_desc") == 0)
1766    return esp_group_desc;
1767
1768  if (strcmp (name, "ah_group_desc") == 0)
1769    return ah_group_desc;
1770
1771  if (strcmp (name, "comp_group_desc") == 0)
1772    return comp_group_desc;
1773
1774  if (strcmp (name, "comp_ecn") == 0)
1775    return comp_ecn;
1776
1777  if (strcmp (name, "ah_ecn") == 0)
1778    return ah_ecn;
1779
1780  if (strcmp (name, "esp_ecn") == 0)
1781    return esp_ecn;
1782
1783  return "";
1784
1785 bad:
1786  policy_callback (KEYNOTE_CALLBACK_INITIALIZE);
1787  return "";
1788}
1789
1790void
1791policy_init (void)
1792{
1793  char *ptr, *policy_file;
1794  char **asserts;
1795  size_t sz;
1796  int fd, len, i;
1797
1798  LOG_DBG ((LOG_POLICY, 30, "policy_init: initializing"));
1799
1800  /* Get policy file from configuration.  */
1801  policy_file = conf_get_str ("General", "Policy-file");
1802  if (!policy_file)
1803    policy_file = POLICY_FILE_DEFAULT;
1804
1805  /* Check file modes and collect file size */
1806  if (check_file_secrecy (policy_file, &sz))
1807    log_fatal ("policy_init: cannot read %s", policy_file);
1808
1809  /* Open policy file.  */
1810  fd = open (policy_file, O_RDONLY);
1811  if (fd == -1)
1812    log_fatal ("policy_init: open (\"%s\", O_RDONLY) failed", policy_file);
1813
1814  /* Allocate memory to keep policies.  */
1815  ptr = calloc (sz + 1, sizeof (char));
1816  if (!ptr)
1817    log_fatal ("policy_init: calloc (%lu, %lu) failed", (unsigned long)sz + 1,
1818	       (unsigned long)sizeof (char));
1819
1820  /* Just in case there are short reads...  */
1821  for (len = 0; len < sz; len += i)
1822    {
1823      i = read (fd, ptr + len, sz - len);
1824      if (i == -1)
1825	log_fatal ("policy_init: read (%d, %p, %lu) failed", fd, ptr + len,
1826		   (unsigned long)(sz - len));
1827    }
1828
1829  /* We're done with this.  */
1830  close (fd);
1831
1832  /* Parse buffer, break up into individual policies.  */
1833  asserts = kn_read_asserts (ptr, sz, &i);
1834
1835  /* Begone!  */
1836  free (ptr);
1837
1838  if (asserts == (char **) NULL)
1839    log_print ("policy_init: all policies flushed");
1840
1841  /* Cleanup */
1842  if (keynote_policy_asserts)
1843    {
1844      for (fd = 0; fd < keynote_policy_asserts_num; fd++)
1845        if (keynote_policy_asserts && keynote_policy_asserts[fd])
1846          free (keynote_policy_asserts[fd]);
1847
1848      free (keynote_policy_asserts);
1849    }
1850
1851  keynote_policy_asserts = asserts;
1852  keynote_policy_asserts_num = i;
1853}
1854
1855/* Nothing needed for initialization */
1856int
1857keynote_cert_init (void)
1858{
1859  return 1;
1860}
1861
1862/* Just copy and return.  */
1863void *
1864keynote_cert_get (u_int8_t *data, u_int32_t len)
1865{
1866  char *foo = malloc (len + 1);
1867
1868  if (foo == NULL)
1869    return NULL;
1870
1871  memcpy (foo, data, len);
1872  foo[len] = '\0';
1873  return foo;
1874}
1875
1876/*
1877 * We just verify the signature on the credentials.
1878 * On signature failure, just drop the whole payload.
1879 */
1880int
1881keynote_cert_validate (void *scert)
1882{
1883  char **foo;
1884  int num, i;
1885
1886  if (scert == NULL)
1887    return 0;
1888
1889  foo = kn_read_asserts ((char *) scert, strlen ((char *) scert), &num);
1890  if (foo == NULL)
1891    return 0;
1892
1893  for (i = 0; i < num; i++)
1894    {
1895      if (kn_verify_assertion (scert, strlen ((char *) scert))
1896	  != SIGRESULT_TRUE)
1897        {
1898	  for (; i < num; i++)
1899	    free (foo[i]);
1900	  free (foo);
1901	  return 0;
1902	}
1903
1904      free (foo[i]);
1905    }
1906
1907  free (foo);
1908  return 1;
1909}
1910
1911/* Add received credentials.  */
1912int
1913keynote_cert_insert (int sid, void *scert)
1914{
1915  char **foo;
1916  int num;
1917
1918  if (scert == NULL)
1919    return 0;
1920
1921  foo = kn_read_asserts ((char *) scert, strlen ((char *) scert), &num);
1922  if (foo == NULL)
1923    return 0;
1924
1925  while (num--)
1926    kn_add_assertion (sid, foo[num], strlen (foo[num]), 0);
1927
1928  return 1;
1929}
1930
1931/* Just regular memory free.  */
1932void
1933keynote_cert_free (void *cert)
1934{
1935  free (cert);
1936}
1937
1938/* Verify that the key given to us is valid.  */
1939int
1940keynote_certreq_validate (u_int8_t *data, u_int32_t len)
1941{
1942  struct keynote_deckey dc;
1943  int err = 1;
1944  char *dat;
1945
1946  dat = calloc (len + 1, sizeof (char));
1947  if (!dat)
1948    {
1949      log_error ("keynote_certreq_validate: calloc (%d, %lu) failed", len + 1,
1950		 (unsigned long)sizeof (char));
1951	return 0;
1952    }
1953
1954  memcpy (dat, data, len);
1955
1956  if (kn_decode_key (&dc, dat, KEYNOTE_PUBLIC_KEY) != 0)
1957    err = 0;
1958  else
1959    kn_free_key (&dc);
1960
1961  free (dat);
1962
1963  return err;
1964}
1965
1966/* Beats me what we should be doing with this.  */
1967void *
1968keynote_certreq_decode (u_int8_t *data, u_int32_t len)
1969{
1970  /* XXX */
1971  return NULL;
1972}
1973
1974void
1975keynote_free_aca (void *blob)
1976{
1977  /* XXX */
1978}
1979
1980int
1981keynote_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
1982		     u_int32_t *certlen)
1983{
1984  char *dirname, *file, *addr_str;
1985  struct stat sb;
1986  size_t size;
1987  int idtype, fd, len;
1988
1989  if (!id)
1990    {
1991      log_print ("keynote_cert_obtain: ID is missing");
1992      return 0;
1993    }
1994
1995  /* Get type of ID.  */
1996  idtype = id[0];
1997  id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
1998  id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
1999
2000  dirname = conf_get_str ("KeyNote", "Credential-directory");
2001  if (!dirname)
2002    {
2003      LOG_DBG ((LOG_POLICY, 30,
2004		"keynote_cert_obtain: no Credential-directory"));
2005      return 0;
2006    }
2007
2008  len = strlen (dirname) + strlen (CREDENTIAL_FILE) + 3;
2009
2010  switch (idtype)
2011    {
2012    case IPSEC_ID_IPV4_ADDR:
2013    case IPSEC_ID_IPV6_ADDR:
2014      util_ntoa (&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
2015		 id);
2016      if (addr_str == 0)
2017	return 0;
2018
2019      file = calloc (len + strlen (addr_str), sizeof (char));
2020      if (file == NULL)
2021	{
2022	  log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
2023		     (unsigned long)len + strlen (addr_str));
2024	  free (addr_str);
2025	  return 0;
2026	}
2027
2028      snprintf (file, len + strlen (addr_str), "%s/%s/%s", dirname, addr_str,
2029		CREDENTIAL_FILE);
2030      free (addr_str);
2031      break;
2032
2033    case IPSEC_ID_FQDN:
2034    case IPSEC_ID_USER_FQDN:
2035      {
2036        file = calloc (len + id_len, sizeof (char));
2037	if (file == NULL)
2038	  {
2039	    log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
2040		       (unsigned long)len + id_len);
2041	    return 0;
2042	  }
2043
2044	snprintf (file, len + id_len, "%s/", dirname);
2045	memcpy (file + strlen (dirname) + 1, id, id_len);
2046	snprintf (file + strlen (dirname) + 1 + id_len,
2047		  len - strlen (dirname) - 1, "/%s", CREDENTIAL_FILE);
2048	break;
2049      }
2050
2051    default:
2052      return 0;
2053    }
2054
2055  if (stat (file, &sb) < 0)
2056    {
2057      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to stat \"%s\"",
2058		file));
2059      free (file);
2060      return 0;
2061    }
2062  size = (size_t)sb.st_size;
2063
2064  *cert = calloc (size + 1, sizeof (char));
2065  if (*cert == NULL)
2066    {
2067      log_error ("keynote_cert_obtain: failed to allocate %lu bytes",
2068		 (unsigned long)size);
2069      free (file);
2070      return 0;
2071    }
2072
2073  fd = open (file, O_RDONLY, 0);
2074  if (fd < 0)
2075    {
2076      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to open \"%s\"",
2077		file));
2078      free (file);
2079      return 0;
2080    }
2081
2082  if (read (fd, *cert, size) != size)
2083    {
2084      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to read %lu "
2085		"bytes from \"%s\"", (unsigned long)size, file));
2086      free (file);
2087      close (fd);
2088      return 0;
2089    }
2090
2091  close (fd);
2092  free (file);
2093  *certlen = size;
2094  return 1;
2095}
2096
2097/* This should never be called.  */
2098int
2099keynote_cert_get_subjects (void *scert, int *n, u_int8_t ***id,
2100			   u_int32_t **id_len)
2101{
2102  return 0;
2103}
2104
2105/* Get the authorizer key.  */
2106int
2107keynote_cert_get_key (void *scert, void *keyp)
2108{
2109  struct keynote_keylist *kl;
2110  int sid, kid, num;
2111  char **foo;
2112
2113  foo = kn_read_asserts ((char *)scert, strlen ((char *)scert), &num);
2114  if (foo == NULL || num == 0)
2115    {
2116      log_print ("keynote_cert_get_key: failed to decompose credentials");
2117      return 0;
2118    }
2119
2120  kid = kn_init ();
2121  if (kid == -1)
2122    {
2123      log_print ("keynote_cert_get_key: failed to initialize new policy "
2124		 "session");
2125      while (num--)
2126	free (foo[num]);
2127      free (foo);
2128      return 0;
2129    }
2130
2131  sid = kn_add_assertion (kid, foo[num - 1], strlen (foo[num - 1]), 0);
2132  while (num--)
2133    free (foo[num]);
2134  free (foo);
2135
2136  if (sid == -1)
2137    {
2138      log_print ("keynote_cert_get_key: failed to add assertion");
2139      kn_close (kid);
2140      return 0;
2141    }
2142
2143  *(RSA **)keyp = NULL;
2144
2145  kl = kn_get_licensees (kid, sid);
2146  while (kl)
2147    {
2148      if (kl->key_alg == KEYNOTE_ALGORITHM_RSA)
2149	{
2150	  *(RSA **)keyp = RSAPublicKey_dup (kl->key_key);
2151	  break;
2152	}
2153
2154      kl = kl->key_next;
2155    }
2156
2157  kn_remove_assertion (kid, sid);
2158  kn_close (kid);
2159  return *(RSA **)keyp == NULL ? 0 : 1;
2160}
2161
2162void *
2163keynote_cert_dup (void *cert)
2164{
2165  return strdup((char *)cert);
2166}
2167
2168void
2169keynote_serialize (void *cert, u_int8_t **data, u_int32_t *datalen)
2170{
2171  *datalen = strlen ((char *)cert) + 1;
2172  *data = (u_int8_t *)strdup (cert); /* i.e an extra character at the end... */
2173  if (*data == NULL)
2174    log_error ("keynote_serialize: malloc (%d) failed", *datalen);
2175}
2176
2177/* From cert to printable */
2178char *
2179keynote_printable (void *cert)
2180{
2181  return strdup ((char *)cert);
2182}
2183
2184/* From printable to cert */
2185void *
2186keynote_from_printable (char *cert)
2187{
2188  return strdup (cert);
2189}
2190