policy.c revision 1.2
1/*	$OpenBSD: policy.c,v 1.2 1999/08/26 22:31:09 niklas Exp $	*/
2/*	$EOM: policy.c,v 1.7 1999/08/26 11:21:47 niklas Exp $ */
3
4/*
5 * Copyright (c) 1999 Angelos D. Keromytis.  All rights reserved.
6 * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Ericsson Radio Systems.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * This code was written under funding by Ericsson Radio Systems.
36 */
37
38#include <sys/param.h>
39#include <sys/mman.h>
40#include <sys/queue.h>
41#include <sys/stat.h>
42#include <ctype.h>
43#include <fcntl.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <unistd.h>
48#include <keynote.h>
49#include <sys/socket.h>
50#include <netinet/in.h>
51#include <arpa/inet.h>
52#include <errno.h>
53
54#include "sysdep.h"
55
56#include "app.h"
57#include "conf.h"
58#include "connection.h"
59#include "cookie.h"
60#include "doi.h"
61#include "dyn.h"
62#include "exchange.h"
63#include "init.h"
64#include "ipsec.h"
65#include "isakmp_doi.h"
66#include "math_group.h"
67#include "sa.h"
68#include "timer.h"
69#include "transport.h"
70#include "udp.h"
71#include "log.h"
72#include "message.h"
73#include "ui.h"
74#include "util.h"
75#include "policy.h"
76
77#ifndef POLICY_FILE_DEFAULT
78#define POLICY_FILE_DEFAULT "/etc/isakmpd.policy"
79#endif /* POLICY_FILE_DEFAULT */
80
81#if defined (HAVE_DLOPEN) && !defined (USE_KEYNOTE)
82
83void *libkeynote = 0;
84
85/*
86 * These prototypes matches OpenBSD keynote.h 1.6.  If you use
87 * a different version than that, you are on your own.
88 */
89int *lk_keynote_errno;
90int (*lk_kn_add_action) (int, char *, char *, int);
91int (*lk_kn_add_assertion) (int, char *, int, int);
92int (*lk_kn_add_authorizer) (int, char *);
93int (*lk_kn_close) (int);
94int (*lk_kn_do_query) (int, char **, int);
95char *(*lk_kn_encode_key) (struct keynote_deckey *, int, int, int);
96int (*lk_kn_init) (void);
97char **(*lk_kn_read_asserts) (char *, int, int *);
98int (*lk_kn_remove_authorizer) (int, char *);
99#define SYMENTRY(x) { SYM, SYM (x), (void **)&lk_ ## x }
100
101static struct dynload_script libkeynote_script[] = {
102  { LOAD, "libc.so", &libkeynote },
103  { LOAD, "libcrypto.so", &libkeynote },
104  { LOAD, "libm.so", &libkeynote },
105  { LOAD, "libkeynote.so", &libkeynote },
106  SYMENTRY (keynote_errno),
107  SYMENTRY (kn_add_action),
108  SYMENTRY (kn_add_assertion),
109  SYMENTRY (kn_add_authorizer),
110  SYMENTRY (kn_close),
111  SYMENTRY (kn_do_query),
112  SYMENTRY (kn_encode_key),
113  SYMENTRY (kn_init),
114  SYMENTRY (kn_read_asserts),
115  SYMENTRY (kn_remove_authorizer),
116  { EOS }
117};
118#endif
119
120int keynote_sessid = -1;
121
122struct exchange *policy_exchange = 0;
123struct sa *policy_sa = 0;
124struct sa *policy_isakmp_sa = 0;
125
126/*
127 * Adaptation of Vixie's inet_ntop4 ()
128 */
129static const char *
130my_inet_ntop4 (const in_addr_t *src, char *dst, size_t size, int normalize)
131{
132  static const char fmt[] = "%03u.%03u.%03u.%03u";
133  char tmp[sizeof "255.255.255.255"];
134  in_addr_t src2;
135
136  if (normalize)
137    src2 = ntohl (*src);
138  else
139    src2 = *src;
140
141  if (sprintf (tmp, fmt, ((u_int8_t *) &src2)[0], ((u_int8_t *) &src2)[1],
142	       ((u_int8_t *) &src2)[2], ((u_int8_t *) &src2)[3]) > size)
143    {
144      errno = ENOSPC;
145      return 0;
146    }
147  strcpy (dst, tmp);
148  return dst;
149}
150
151static char *
152policy_callback (char *name)
153{
154  struct proto *proto;
155
156  u_int8_t *attr, *value, *id;
157  struct sockaddr_in *sin;
158  struct ipsec_exch *ie;
159  int fmt, lifetype = 0;
160  in_addr_t net, subnet;
161  u_int16_t len, type;
162  size_t id_sz;
163
164  /* We use all these as a cache.  */
165  static char *esp_present, *ah_present, *comp_present;
166  static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
167  static char *comp_alg, ah_life_kbytes[32], ah_life_seconds[32];
168  static char esp_life_kbytes[32], esp_life_seconds[32], comp_life_kbytes[32];
169  static char comp_life_seconds[32], *ah_encapsulation, *esp_encapsulation;
170  static char *comp_encapsulation, ah_key_length[32], esp_key_length[32];
171  static char ah_key_rounds[32], esp_key_rounds[32], comp_dict_size[32];
172  static char comp_private_alg[32], *remote_filter_type, *local_filter_type;
173  static char remote_filter_addr_upper[64], remote_filter_addr_lower[64];
174  static char local_filter_addr_upper[64], local_filter_addr_lower[64];
175  static char ah_group_desc[32], esp_group_desc[32], comp_group_desc[32];
176  static char remote_ike_address[64], local_ike_address[64];
177  static char *remote_id_type, remote_id_addr_upper[64];
178  static char remote_id_addr_lower[64], *remote_id_proto, remote_id_port[32];
179  static char remote_filter_port[32], local_filter_port[32];
180  static char *remote_filter_proto, *local_filter_proto;
181
182  /* Allocated.  */
183  static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
184
185  static int dirty = 1;
186
187  /* We only need to set dirty at initialization time really.  */
188  if (strcmp (name, KEYNOTE_CALLBACK_CLEANUP) == 0
189      || strcmp (name, KEYNOTE_CALLBACK_INITIALIZE) == 0)
190    {
191      esp_present = ah_present = comp_present = "no";
192      ah_hash_alg = ah_auth_alg = "";
193      esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
194      esp_encapsulation = comp_encapsulation = remote_filter_type = "";
195      local_filter_type = remote_id_type = "";
196      remote_filter_proto = local_filter_proto = remote_id_proto = "";
197
198      if (remote_filter != 0)
199        {
200	  free (remote_filter);
201	  remote_filter = 0;
202	}
203
204      if (local_filter != 0)
205        {
206	  free (local_filter);
207	  local_filter = 0;
208	}
209
210      if (remote_id != 0)
211        {
212	  free (remote_id);
213	  remote_id = 0;
214	}
215
216      memset (remote_ike_address, 0, sizeof remote_ike_address);
217      memset (local_ike_address, 0, sizeof local_ike_address);
218      memset (ah_life_kbytes, 0, sizeof ah_life_kbytes);
219      memset (ah_life_seconds, 0, sizeof ah_life_seconds);
220      memset (esp_life_kbytes, 0, sizeof esp_life_kbytes);
221      memset (esp_life_seconds, 0, sizeof esp_life_seconds);
222      memset (comp_life_kbytes, 0, sizeof comp_life_kbytes);
223      memset (comp_life_seconds, 0, sizeof comp_life_seconds);
224      memset (ah_key_length, 0, sizeof ah_key_length);
225      memset (ah_key_rounds, 0, sizeof ah_key_rounds);
226      memset (esp_key_length, 0, sizeof esp_key_length);
227      memset (esp_key_rounds, 0, sizeof esp_key_rounds);
228      memset (comp_dict_size, 0, sizeof comp_dict_size);
229      memset (comp_private_alg, 0, sizeof comp_private_alg);
230      memset (remote_filter_addr_upper, 0, sizeof remote_filter_addr_upper);
231      memset (remote_filter_addr_lower, 0, sizeof remote_filter_addr_lower);
232      memset (local_filter_addr_upper, 0, sizeof local_filter_addr_upper);
233      memset (local_filter_addr_lower, 0, sizeof local_filter_addr_lower);
234      memset (remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
235      memset (remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
236      memset (ah_group_desc, 0, sizeof ah_group_desc);
237      memset (esp_group_desc, 0, sizeof esp_group_desc);
238      memset (remote_id_port, 0, sizeof remote_id_port);
239      memset (remote_filter_port, 0, sizeof remote_filter_port);
240      memset (local_filter_port, 0, sizeof local_filter_port);
241
242      dirty = 1;
243      return "";
244    }
245
246  /*
247   * If dirty is set, this is the first request for an attribute, so
248   * populate our value cache.
249   */
250  if (dirty)
251    {
252      ie = policy_exchange->data;
253
254      for (proto = TAILQ_FIRST (&policy_sa->protos); proto;
255	   proto = TAILQ_NEXT (proto, link))
256	{
257	  switch (proto->proto)
258	    {
259	    case IPSEC_PROTO_IPSEC_AH:
260	      ah_present = "yes";
261	      switch (proto->id)
262		{
263		case IPSEC_AH_MD5:
264		  ah_hash_alg = "md5";
265		  break;
266
267		case IPSEC_AH_SHA:
268		  ah_hash_alg = "sha";
269		  break;
270
271		case IPSEC_AH_DES:
272		  ah_hash_alg = "des";
273		  break;
274		}
275
276	      break;
277
278	    case IPSEC_PROTO_IPSEC_ESP:
279	      esp_present = "yes";
280	      switch (proto->id)
281		{
282		case IPSEC_ESP_DES_IV64:
283		  esp_enc_alg = "des-iv64";
284		  break;
285
286		case IPSEC_ESP_DES:
287		  esp_enc_alg = "des";
288		  break;
289
290		case IPSEC_ESP_3DES:
291		  esp_enc_alg = "3des";
292		  break;
293
294		case IPSEC_ESP_RC5:
295		  esp_enc_alg = "rc5";
296		  break;
297
298		case IPSEC_ESP_IDEA:
299		  esp_enc_alg = "idea";
300		  break;
301
302		case IPSEC_ESP_CAST:
303		  esp_enc_alg = "cast";
304		  break;
305
306		case IPSEC_ESP_BLOWFISH:
307		  esp_enc_alg = "blowfish";
308		  break;
309
310		case IPSEC_ESP_3IDEA:
311		  esp_enc_alg = "3idea";
312		  break;
313
314		case IPSEC_ESP_DES_IV32:
315		  esp_enc_alg = "des-iv32";
316		  break;
317
318		case IPSEC_ESP_RC4:
319		  esp_enc_alg = "rc4";
320		  break;
321
322		case IPSEC_ESP_NULL:
323		  esp_enc_alg = "null";
324		  break;
325		}
326
327	      break;
328
329	    case IPSEC_PROTO_IPCOMP:
330	      comp_present = "yes";
331	      switch (proto->id)
332		{
333		case IPSEC_IPCOMP_OUI:
334		  comp_alg = "oui";
335		  break;
336
337		case IPSEC_IPCOMP_DEFLATE:
338		  comp_alg = "deflate";
339		  break;
340
341		case IPSEC_IPCOMP_LZS:
342		  comp_alg = "lzs";
343		  break;
344
345		case IPSEC_IPCOMP_V42BIS:
346		  comp_alg = "v42bis";
347		  break;
348		}
349
350	      break;
351	    }
352
353	  for (attr = proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
354	       attr
355		 < proto->chosen->p + GET_ISAKMP_GEN_LENGTH (proto->chosen->p);
356	       attr = value + len)
357	    {
358	      if (attr + ISAKMP_ATTR_VALUE_OFF
359		  > (proto->chosen->p
360		     + GET_ISAKMP_GEN_LENGTH (proto->chosen->p)))
361		return "";
362
363	      type = GET_ISAKMP_ATTR_TYPE (attr);
364	      fmt = ISAKMP_ATTR_FORMAT (type);
365	      type = ISAKMP_ATTR_TYPE (type);
366	      value = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF :
367			      ISAKMP_ATTR_VALUE_OFF);
368	      len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
369		     GET_ISAKMP_ATTR_LENGTH_VALUE (attr));
370
371	      if (value + len > proto->chosen->p +
372		  GET_ISAKMP_GEN_LENGTH (proto->chosen->p))
373		return "";
374
375	      switch (type)
376		{
377		case IPSEC_ATTR_SA_LIFE_TYPE:
378		  lifetype = decode_16 (value);
379		  break;
380
381		case IPSEC_ATTR_SA_LIFE_DURATION:
382		  switch (proto->proto)
383		    {
384		    case IPSEC_PROTO_IPSEC_AH:
385		      if (lifetype == IPSEC_DURATION_SECONDS)
386			{
387			  if (len == 2)
388			    sprintf (ah_life_seconds, "%d",
389				     decode_16 (value));
390			  else
391			    sprintf (ah_life_seconds, "%d",
392				     decode_32 (value));
393			}
394		      else
395			{
396			  if (len == 2)
397			    sprintf (ah_life_kbytes, "%d",
398				     decode_16 (value));
399			  else
400			    sprintf (ah_life_kbytes, "%d",
401				     decode_32 (value));
402			}
403
404		      break;
405
406		    case IPSEC_PROTO_IPSEC_ESP:
407		      if (lifetype == IPSEC_DURATION_SECONDS)
408			{
409			  if (len == 2)
410			    sprintf (esp_life_seconds, "%d",
411				     decode_16 (value));
412			  else
413			    sprintf (esp_life_seconds, "%d",
414				     decode_32 (value));
415			}
416		      else
417			{
418			  if (len == 2)
419			    sprintf (esp_life_kbytes, "%d",
420				     decode_16 (value));
421			  else
422			    sprintf (esp_life_kbytes, "%d",
423				     decode_32 (value));
424			}
425
426		      break;
427
428		    case IPSEC_PROTO_IPCOMP:
429		      if (lifetype == IPSEC_DURATION_SECONDS)
430			{
431			  if (len == 2)
432			    sprintf (comp_life_seconds, "%d",
433				     decode_16 (value));
434			  else
435			    sprintf (comp_life_seconds, "%d",
436				     decode_32 (value));
437			}
438		      else
439			{
440			  if (len == 2)
441			    sprintf (comp_life_kbytes, "%d",
442				     decode_16 (value));
443			  else
444			    sprintf (comp_life_kbytes, "%d",
445				     decode_32 (value));
446			}
447
448		      break;
449		    }
450		  break;
451
452		case IPSEC_ATTR_GROUP_DESCRIPTION:
453		  switch (proto->proto)
454		    {
455		    case IPSEC_PROTO_IPSEC_AH:
456		      sprintf (ah_group_desc, "%d", decode_16 (value));
457		      break;
458
459		    case IPSEC_PROTO_IPSEC_ESP:
460		      sprintf (esp_group_desc, "%d",
461			       decode_16 (value));
462		      break;
463
464		    case IPSEC_PROTO_IPCOMP:
465		      sprintf (comp_group_desc, "%d",
466			       decode_16 (value));
467		      break;
468		    }
469		  break;
470
471		case IPSEC_ATTR_ENCAPSULATION_MODE:
472		  if (decode_16 (value) == IPSEC_ENCAP_TUNNEL)
473		    switch (proto->proto)
474		      {
475		      case IPSEC_PROTO_IPSEC_AH:
476			ah_encapsulation = "tunnel";
477			break;
478
479		      case IPSEC_PROTO_IPSEC_ESP:
480			esp_encapsulation = "tunnel";
481			break;
482
483		      case IPSEC_PROTO_IPCOMP:
484			comp_encapsulation = "tunnel";
485			break;
486		      }
487		  else
488		    switch (proto->proto)
489		      {
490		      case IPSEC_PROTO_IPSEC_AH:
491			ah_encapsulation = "transport";
492			break;
493
494		      case IPSEC_PROTO_IPSEC_ESP:
495			esp_encapsulation = "transport";
496			break;
497
498		      case IPSEC_PROTO_IPCOMP:
499			comp_encapsulation = "transport";
500			break;
501		      }
502		  break;
503
504		case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
505		  switch (proto->proto)
506		    {
507		    case IPSEC_PROTO_IPSEC_AH:
508		      switch (decode_16 (value))
509			{
510			case IPSEC_AUTH_HMAC_MD5:
511			  ah_auth_alg = "hmac-md5";
512			  break;
513
514			case IPSEC_AUTH_HMAC_SHA:
515			  ah_auth_alg = "hmac-sha";
516			  break;
517
518			case IPSEC_AUTH_DES_MAC:
519			  ah_auth_alg = "des-mac";
520			  break;
521
522			case IPSEC_AUTH_KPDK:
523			  ah_auth_alg = "kpdk";
524			  break;
525			}
526		      break;
527
528		    case IPSEC_PROTO_IPSEC_ESP:
529		      switch (decode_16 (value))
530			{
531			case IPSEC_AUTH_HMAC_MD5:
532			  esp_auth_alg = "hmac-md5";
533			  break;
534
535			case IPSEC_AUTH_HMAC_SHA:
536			  esp_auth_alg = "hmac-sha";
537			  break;
538
539			case IPSEC_AUTH_DES_MAC:
540			  esp_auth_alg = "des-mac";
541			  break;
542
543			case IPSEC_AUTH_KPDK:
544			  esp_auth_alg = "kpdk";
545			  break;
546			}
547		      break;
548		    }
549		  break;
550
551		case IPSEC_ATTR_KEY_LENGTH:
552		  switch (proto->proto)
553		    {
554		    case IPSEC_PROTO_IPSEC_AH:
555		      sprintf (ah_key_length, "%d", decode_16 (value));
556		      break;
557
558		    case IPSEC_PROTO_IPSEC_ESP:
559		      sprintf (esp_key_length, "%d",
560			       decode_16 (value));
561		      break;
562		    }
563		  break;
564
565		case IPSEC_ATTR_KEY_ROUNDS:
566		  switch (proto->proto)
567		    {
568		    case IPSEC_PROTO_IPSEC_AH:
569		      sprintf (ah_key_rounds, "%d", decode_16 (value));
570		      break;
571
572		    case IPSEC_PROTO_IPSEC_ESP:
573		      sprintf (esp_key_rounds, "%d",
574			       decode_16 (value));
575		      break;
576		    }
577		  break;
578
579		case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
580		  sprintf (comp_dict_size, "%d", decode_16 (value));
581		  break;
582
583		case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
584		  sprintf (comp_private_alg, "%d", decode_16 (value));
585		  break;
586		}
587	    }
588	}
589
590      /* XXX IPv4-specific.  */
591      policy_sa->transport->vtbl->get_src (policy_sa->transport,
592					   (struct sockaddr **) &sin, &fmt);
593      my_inet_ntop4 (&(sin->sin_addr.s_addr), local_ike_address,
594		     sizeof local_ike_address - 1, 0);
595
596      policy_sa->transport->vtbl->get_dst (policy_sa->transport,
597					   (struct sockaddr **) &sin, &fmt);
598      my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_ike_address,
599		     sizeof remote_ike_address - 1, 0);
600
601      if (policy_isakmp_sa->initiator)
602        {
603	  id = policy_isakmp_sa->id_r;
604	  id_sz = policy_isakmp_sa->id_r_len;
605	}
606      else
607        {
608	  id = policy_isakmp_sa->id_i;
609	  id_sz = policy_isakmp_sa->id_i_len;
610	}
611
612      switch (id[0])
613        {
614	case IPSEC_ID_IPV4_ADDR:
615	  remote_id_type = "IPv4 address";
616
617	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
618	  my_inet_ntop4 (&net, remote_id_addr_upper,
619			 sizeof remote_id_addr_upper - 1, 1);
620	  my_inet_ntop4 (&net, remote_id_addr_lower,
621			 sizeof remote_id_addr_lower - 1, 1);
622	  remote_id = strdup (remote_id_addr_upper);
623	  if (!remote_id)
624	    log_fatal ("policy_callback: strdup (\"%s\") failed",
625		       remote_id_addr_upper);
626	  break;
627
628	case IPSEC_ID_IPV4_RANGE:
629	  remote_id_type = "IPv4 range";
630
631	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
632	  my_inet_ntop4 (&net, remote_id_addr_lower,
633			 sizeof remote_id_addr_lower - 1, 1);
634	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
635	  my_inet_ntop4 (&net, remote_id_addr_upper,
636			 sizeof remote_id_addr_upper - 1, 1);
637	  remote_id = calloc (strlen (remote_id_addr_upper)
638			      + strlen (remote_id_addr_lower) + 2,
639			      sizeof (char));
640	  if (!remote_id)
641	    log_fatal ("policy_callback: calloc (%d, %d) failed",
642		       strlen (remote_id_addr_upper)
643		       + strlen (remote_id_addr_lower) + 2,
644		       sizeof (char));
645
646	  strcpy (remote_id, remote_id_addr_lower);
647	  remote_id[strlen (remote_id_addr_lower)] = '-';
648	  strcpy (remote_id + strlen (remote_id_addr_lower) + 1,
649		  remote_id_addr_upper);
650	  break;
651
652	case IPSEC_ID_IPV4_ADDR_SUBNET:
653	  remote_id_type = "IPv4 subnet";
654
655	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
656	  subnet = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
657	  net &= subnet;
658	  my_inet_ntop4 (&net, remote_id_addr_lower,
659			 sizeof remote_id_addr_lower - 1, 1);
660	  net |= ~subnet;
661	  my_inet_ntop4 (&net, remote_id_addr_upper,
662			 sizeof remote_id_addr_upper - 1, 1);
663	  remote_id = calloc (strlen (remote_id_addr_upper)
664			      + strlen (remote_id_addr_lower) + 2,
665			      sizeof (char));
666	  if (!remote_id)
667	    log_fatal ("policy_callback: calloc (%d, %d) failed",
668		       strlen (remote_id_addr_upper)
669		       + strlen (remote_id_addr_lower) + 2,
670		       sizeof (char));
671
672	  strcpy (remote_id, remote_id_addr_lower);
673	  remote_id[strlen (remote_id_addr_lower)] = '-';
674	  strcpy (remote_id + strlen (remote_id_addr_lower) + 1,
675		  remote_id_addr_upper);
676	  break;
677
678	case IPSEC_ID_IPV6_ADDR: /* XXX we need decode_128 ().  */
679	  remote_id_type = "IPv6 address";
680	  break;
681
682	case IPSEC_ID_IPV6_RANGE: /* XXX we need decode_128 ().  */
683	  remote_id_type = "IPv6 range";
684	  break;
685
686	case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX we need decode_128 ().  */
687	  remote_id_type = "IPv6 address";
688	  break;
689
690	case IPSEC_ID_FQDN:
691	  remote_id_type = "FQDN";
692	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 1,
693			      sizeof (char));
694	  if (!remote_id)
695	    log_fatal ("policy_callback: calloc (%d, %d) failed",
696		       id_sz - ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 1,
697		       sizeof (char));
698	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, id_sz);
699	  break;
700
701	case IPSEC_ID_USER_FQDN:
702	  remote_id_type = "User FQDN";
703	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 1,
704			      sizeof (char));
705	  if (!remote_id)
706	    log_fatal ("policy_callback: calloc (%d, %d) failed",
707		       id_sz - ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 1,
708		       sizeof (char));
709	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, id_sz);
710	  break;
711
712	case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
713	  remote_id_type = "ASN1 DN";
714	  break;
715
716	case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
717	  remote_id_type = "ASN1 GN";
718	  break;
719
720	case IPSEC_ID_KEY_ID: /* XXX -- hex-encode this.  */
721	  remote_id_type = "Key ID";
722	  break;
723
724	default:
725	  log_print ("policy_callback: unknown remote ID type %d", id[0]);
726	  return "";
727	}
728
729      switch (id[1])
730        {
731	case IPPROTO_TCP:
732	  remote_id_proto = "tcp";
733	  break;
734
735	case IPPROTO_UDP:
736	  remote_id_proto = "udp";
737	  break;
738	}
739
740      snprintf (remote_id_port, sizeof remote_id_port - 1, "%d",
741		decode_16 (id + 2));
742
743      /* Initialize the ID variables.  */
744      if (ie->id_ci)
745        {
746	  switch (GET_ISAKMP_ID_TYPE (ie->id_ci))
747	    {
748	    case IPSEC_ID_IPV4_ADDR:
749	      remote_filter_type = "IPv4 address";
750
751	      net = decode_32 (ie->id_ci + ISAKMP_ID_DATA_OFF);
752	      my_inet_ntop4 (&net, remote_filter_addr_upper,
753			     sizeof remote_filter_addr_upper - 1, 1);
754	      my_inet_ntop4 (&net, remote_filter_addr_lower,
755			     sizeof (remote_filter_addr_lower) - 1, 1);
756	      remote_filter = strdup (remote_filter_addr_upper);
757	      if (!remote_filter)
758		log_fatal ("policy_callback: strdup (\"%s\") failed",
759			   remote_filter_addr_upper);
760	      break;
761
762	    case IPSEC_ID_IPV4_RANGE:
763	      remote_filter_type = "IPv4 range";
764
765	      net = decode_32 (ie->id_ci + ISAKMP_ID_DATA_OFF);
766	      my_inet_ntop4 (&net, remote_filter_addr_lower,
767			     sizeof remote_filter_addr_lower - 1, 1);
768	      net = decode_32 (ie->id_ci + ISAKMP_ID_DATA_OFF + 4);
769	      my_inet_ntop4 (&net, remote_filter_addr_upper,
770			     sizeof remote_filter_addr_upper - 1, 1);
771	      remote_filter = calloc (strlen (remote_filter_addr_upper)
772				      + strlen (remote_filter_addr_lower) + 2,
773				      sizeof (char));
774	      if (!remote_filter)
775		log_fatal ("policy_callback: calloc (%d, %d) failed",
776			   strlen (remote_filter_addr_upper)
777			   + strlen (remote_filter_addr_lower) + 2,
778			   sizeof (char));
779	      strcpy (remote_filter, remote_filter_addr_lower);
780	      remote_filter[strlen (remote_filter_addr_lower)] = '-';
781	      strcpy (remote_filter + strlen (remote_filter_addr_lower) + 1,
782		      remote_filter_addr_upper);
783	      break;
784
785	    case IPSEC_ID_IPV4_ADDR_SUBNET:
786	      remote_filter_type = "IPv4 subnet";
787
788	      net = decode_32 (ie->id_ci + ISAKMP_ID_DATA_OFF);
789	      subnet = decode_32 (ie->id_ci + ISAKMP_ID_DATA_OFF + 4);
790	      net &= subnet;
791	      my_inet_ntop4 (&net, remote_filter_addr_lower,
792			     sizeof remote_filter_addr_lower - 1, 1);
793	      net |= ~subnet;
794	      my_inet_ntop4 (&net, remote_filter_addr_upper,
795			     sizeof remote_filter_addr_upper - 1, 1);
796	      remote_filter = calloc (strlen (remote_filter_addr_upper)
797				      + strlen (remote_filter_addr_lower) + 2,
798				      sizeof (char));
799	      if (!remote_filter)
800		log_fatal ("policy_callback: calloc (%d, %d) failed",
801			   strlen (remote_filter_addr_upper)
802			   + strlen (remote_filter_addr_lower) + 2,
803			   sizeof (char));
804	      strcpy (remote_filter, remote_filter_addr_lower);
805	      remote_filter[strlen (remote_filter_addr_lower)] = '-';
806	      strcpy (remote_filter + strlen (remote_filter_addr_lower) + 1,
807		      remote_filter_addr_upper);
808	      break;
809
810	    case IPSEC_ID_IPV6_ADDR: /* XXX we need decode_128 (). */
811	      remote_filter_type = "IPv6 address";
812	      break;
813
814	    case IPSEC_ID_IPV6_RANGE: /* XXX we need decode_128 ().  */
815	      remote_filter_type = "IPv6 range";
816	      break;
817
818	    case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX we need decode_128 ().  */
819	      remote_filter_type = "IPv6 address";
820	      break;
821
822	    case IPSEC_ID_FQDN:
823	      remote_filter_type = "FQDN";
824	      remote_filter = calloc (ie->id_ci_sz - ISAKMP_ID_DATA_OFF + 1,
825				      sizeof (char));
826	      if (!remote_filter)
827		log_fatal ("policy_callback: calloc (%d, %d) failed",
828			   ie->id_ci_sz - ISAKMP_ID_DATA_OFF + 1,
829			   sizeof (char));
830	      memcpy (remote_filter, ie->id_ci + ISAKMP_ID_DATA_OFF,
831		      ie->id_ci_sz);
832	      break;
833
834	    case IPSEC_ID_USER_FQDN:
835	      remote_filter_type = "User FQDN";
836	      remote_filter = calloc (ie->id_ci_sz - ISAKMP_ID_DATA_OFF + 1,
837				      sizeof (char));
838	      if (!remote_filter)
839		log_fatal ("policy_callback: calloc (%d, %d) failed",
840			   ie->id_ci_sz - ISAKMP_ID_DATA_OFF + 1,
841			   sizeof (char));
842	      memcpy (remote_filter, ie->id_ci + ISAKMP_ID_DATA_OFF,
843		      ie->id_ci_sz);
844	      break;
845
846	    case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
847	      remote_filter_type = "ASN1 DN";
848	      break;
849
850	    case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
851	      remote_filter_type = "ASN1 GN";
852	      break;
853
854	    case IPSEC_ID_KEY_ID: /* XXX -- hex-encode this.  */
855	      remote_filter_type = "Key ID";
856	      break;
857
858	    default:
859	      log_print ("policy_callback: unknown initiator ID type %d",
860			 GET_ISAKMP_ID_TYPE (ie->id_ci));
861	      return "";
862	    }
863
864	  switch (ie->id_ci[ISAKMP_GEN_SZ + 1])
865	    {
866	    case IPPROTO_TCP:
867	      remote_filter_proto = "tcp";
868	      break;
869
870	    case IPPROTO_UDP:
871	      remote_filter_proto = "udp";
872	      break;
873	    }
874
875	  snprintf (remote_filter_port, sizeof remote_filter_port - 1,
876		    "%d", decode_16 (ie->id_ci + ISAKMP_GEN_SZ + 2));
877	}
878      else
879        {
880	  policy_sa->transport->vtbl->get_src (policy_sa->transport,
881					       (struct sockaddr **) &sin,
882					       &fmt);
883	  remote_filter_type = "IPv4 address";
884
885	  my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_filter_addr_upper,
886			 sizeof remote_filter_addr_upper - 1, 0);
887	  my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_filter_addr_lower,
888			 sizeof remote_filter_addr_lower - 1, 1);
889	  remote_filter = strdup (remote_filter_addr_upper);
890	  if (!remote_filter)
891	    log_fatal ("policy_callback: strdup (\"%s\") failed",
892		       remote_filter_addr_upper);
893	}
894
895      if (ie->id_cr)
896        {
897	  switch (GET_ISAKMP_ID_TYPE (ie->id_cr))
898	    {
899	    case IPSEC_ID_IPV4_ADDR:
900	      local_filter_type = "IPv4 address";
901
902	      net = decode_32 (ie->id_cr + ISAKMP_ID_DATA_OFF);
903	      my_inet_ntop4 (&net, local_filter_addr_upper,
904			     sizeof local_filter_addr_upper - 1, 1);
905	      my_inet_ntop4 (&net, local_filter_addr_lower,
906			     sizeof local_filter_addr_upper - 1, 1);
907	      local_filter = strdup (local_filter_addr_upper);
908	      if (!local_filter)
909		log_fatal ("policy_callback: strdup (\"%s\") failed",
910			   local_filter_addr_upper);
911	      break;
912
913	    case IPSEC_ID_IPV4_RANGE:
914	      local_filter_type = "IPv4 range";
915
916	      net = decode_32 (ie->id_cr + ISAKMP_ID_DATA_OFF);
917	      my_inet_ntop4 (&net, local_filter_addr_lower,
918			     sizeof local_filter_addr_lower - 1, 1);
919	      net = decode_32 (ie->id_cr + ISAKMP_ID_DATA_OFF + 4);
920	      my_inet_ntop4 (&net, local_filter_addr_upper,
921			     sizeof local_filter_addr_upper - 1, 1);
922	      local_filter = calloc (strlen (local_filter_addr_upper)
923				     + strlen (local_filter_addr_lower) + 2,
924				     sizeof (char));
925	      if (!local_filter)
926		log_fatal ("policy_callback: calloc (%d, %d) failed",
927			   strlen (local_filter_addr_upper)
928			   + strlen (local_filter_addr_lower) + 2,
929			   sizeof (char));
930	      strcpy (local_filter, local_filter_addr_lower);
931	      local_filter[strlen (local_filter_addr_lower)] = '-';
932	      strcpy (local_filter + strlen (local_filter_addr_lower) + 1,
933		      local_filter_addr_upper);
934	      break;
935
936	    case IPSEC_ID_IPV4_ADDR_SUBNET:
937	      local_filter_type = "IPv4 subnet";
938
939	      net = decode_32 (ie->id_cr + ISAKMP_ID_DATA_OFF);
940	      subnet = decode_32 (ie->id_cr + ISAKMP_ID_DATA_OFF + 4);
941	      net &= subnet;
942	      my_inet_ntop4 (&net, local_filter_addr_lower,
943			     sizeof local_filter_addr_lower - 1, 1);
944	      net |= ~subnet;
945	      my_inet_ntop4 (&net, local_filter_addr_upper,
946			     sizeof local_filter_addr_upper - 1, 1);
947	      local_filter = calloc (strlen (local_filter_addr_upper)
948				     + strlen (local_filter_addr_lower) + 2,
949				     sizeof (char));
950	      if (!local_filter)
951		log_fatal ("policy_callback: calloc (%d, %d) failed",
952			   strlen (local_filter_addr_upper)
953			   + strlen (local_filter_addr_lower) + 2,
954			   sizeof (char));
955	      strcpy (local_filter, local_filter_addr_lower);
956	      local_filter[strlen (local_filter_addr_lower)] = '-';
957	      strcpy (local_filter + strlen (local_filter_addr_lower) + 1,
958		      local_filter_addr_upper);
959	      break;
960
961	    case IPSEC_ID_IPV6_ADDR: /* XXX we need decode_128 ().  */
962	      local_filter_type = "IPv6 address";
963	      break;
964
965	    case IPSEC_ID_IPV6_RANGE: /* XXX we need decode_128 ().  */
966	      local_filter_type = "IPv6 range";
967	      break;
968
969	    case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX we need decode_128 ().  */
970	      local_filter_type = "IPv6 address";
971	      break;
972
973	    case IPSEC_ID_FQDN:
974	      local_filter_type = "FQDN";
975	      local_filter = calloc (ie->id_cr_sz - ISAKMP_ID_DATA_OFF + 1,
976				     sizeof (char));
977	      if (!local_filter)
978		log_fatal ("policy_callback: calloc (%d, %d) failed",
979			   ie->id_cr_sz - ISAKMP_ID_DATA_OFF + 1,
980			   sizeof (char));
981	      memcpy (local_filter, ie->id_cr + ISAKMP_ID_DATA_OFF,
982		      ie->id_cr_sz);
983	      break;
984
985	    case IPSEC_ID_USER_FQDN:
986	      local_filter_type = "User FQDN";
987	      local_filter = calloc (ie->id_cr_sz - ISAKMP_ID_DATA_OFF + 1,
988				     sizeof (char));
989	      if (!local_filter)
990		log_fatal ("policy_callback: calloc (%d, %d) failed",
991			   ie->id_cr_sz - ISAKMP_ID_DATA_OFF + 1,
992			   sizeof (char));
993	      memcpy (local_filter, ie->id_cr + ISAKMP_ID_DATA_OFF,
994		      ie->id_cr_sz);
995	      break;
996
997	    case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
998	      local_filter_type = "ASN1 DN";
999	      break;
1000
1001	    case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
1002	      local_filter_type = "ASN1 GN";
1003	      break;
1004
1005	    case IPSEC_ID_KEY_ID: /* XXX -- hex-encode this.  */
1006	      local_filter_type = "Key ID";
1007	      break;
1008
1009	    default:
1010	      log_print ("policy_callback: unknown responder ID type %d",
1011			 GET_ISAKMP_ID_TYPE (ie->id_cr));
1012	      return "";
1013	    }
1014
1015	  switch (ie->id_cr[ISAKMP_GEN_SZ + 1])
1016	    {
1017	    case IPPROTO_TCP:
1018	      local_filter_proto = "tcp";
1019	      break;
1020
1021	    case IPPROTO_UDP:
1022	      local_filter_proto = "udp";
1023	      break;
1024	    }
1025
1026	  snprintf (local_filter_port, sizeof local_filter_port - 1,
1027		    "%d", decode_16 (ie->id_cr + ISAKMP_GEN_SZ + 2));
1028	}
1029      else
1030        {
1031	  policy_sa->transport->vtbl->get_dst (policy_sa->transport,
1032					       (struct sockaddr **) &sin,
1033					       &fmt);
1034	  local_filter_type = "IPv4 address";
1035
1036	  my_inet_ntop4 (&(sin->sin_addr.s_addr), local_filter_addr_upper,
1037			 sizeof local_filter_addr_upper - 1, 0);
1038	  my_inet_ntop4 (&(sin->sin_addr.s_addr), local_filter_addr_lower,
1039			 sizeof local_filter_addr_lower - 1, 1);
1040	  local_filter = strdup (local_filter_addr_upper);
1041	  if (!local_filter)
1042		log_fatal ("policy_callback: strdup (\"%s\") failed",
1043			   local_filter_addr_upper);
1044        }
1045
1046#if 0
1047      printf ("esp_present == %s\n", esp_present);
1048      printf ("ah_present == %s\n", ah_present);
1049      printf ("comp_present == %s\n", comp_present);
1050      printf ("ah_hash_alg == %s\n", ah_hash_alg);
1051      printf ("esp_enc_alg == %s\n", esp_enc_alg);
1052      printf ("comp_alg == %s\n", comp_alg);
1053      printf ("ah_auth_alg == %s\n", ah_auth_alg);
1054      printf ("esp_auth_alg == %s\n", esp_auth_alg);
1055      printf ("ah_life_seconds == %s\n", ah_life_seconds);
1056      printf ("ah_life_kbytes == %s\n", ah_life_kbytes);
1057      printf ("esp_life_seconds == %s\n", esp_life_seconds);
1058      printf ("esp_life_kbytes == %s\n", esp_life_kbytes);
1059      printf ("comp_life_seconds == %s\n", comp_life_seconds);
1060      printf ("comp_life_kbytes == %s\n", comp_life_kbytes);
1061      printf ("ah_encapsulation == %s\n", ah_encapsulation);
1062      printf ("esp_encapsulation == %s\n", esp_encapsulation);
1063      printf ("comp_encapsulation == %s\n", comp_encapsulation);
1064      printf ("comp_dict_size == %s\n", comp_dict_size);
1065      printf ("comp_private_alg == %s\n", comp_private_alg);
1066      printf ("ah_key_length == %s\n", ah_key_length);
1067      printf ("ah_key_rounds == %s\n", ah_key_rounds);
1068      printf ("esp_key_length == %s\n", esp_key_length);
1069      printf ("esp_key_rounds == %s\n", esp_key_rounds);
1070      printf ("ah_group_desc == %s\n", ah_group_desc);
1071      printf ("esp_group_desc == %s\n", esp_group_desc);
1072      printf ("comp_group_desc == %s\n", comp_group_desc);
1073      printf ("remote_filter_type == %s\n", remote_filter_type);
1074      printf ("remote_filter_addr_upper == %s\n", remote_filter_addr_upper);
1075      printf ("remote_filter_addr_lower == %s\n", remote_filter_addr_lower);
1076      printf ("remote_filter == %s\n", remote_filter);
1077      printf ("remote_filter_port == %s\n", remote_filter_port);
1078      printf ("remote_filter_proto == %s\n", remote_filter_proto);
1079      printf ("local_filter_type == %s\n", local_filter_type);
1080      printf ("local_filter_addr_upper == %s\n", local_filter_addr_upper);
1081      printf ("local_filter_addr_lower == %s\n", local_filter_addr_lower);
1082      printf ("local_filter == %s\n", local_filter);
1083      printf ("local_filter_port == %s\n", local_filter_port);
1084      printf ("local_filter_proto == %s\n", local_filter_proto);
1085      printf ("remote_id_type == %s\n", remote_id_type);
1086      printf ("remote_id_addr_upper == %s\n", remote_id_addr_upper);
1087      printf ("remote_id_addr_lower == %s\n", remote_id_addr_lower);
1088      printf ("remote_id == %s\n", remote_id);
1089      printf ("remote_id_port == %s\n", remote_id_port);
1090      printf ("remote_id_proto == %s\n", remote_id_proto);
1091      printf ("remote_ike_address == %s\n", remote_ike_address);
1092      printf ("local_ike_address == %s\n", local_ike_address);
1093#endif /* 0 */
1094
1095      /* Unset dirty now.  */
1096      dirty = 0;
1097    }
1098
1099  if (strcmp (name, "app_domain") == 0)
1100    return "IPsec policy";
1101
1102  if (strcmp (name, "doi") == 0)
1103    return "ipsec";
1104
1105  if (strcmp (name, "esp_present") == 0)
1106    return esp_present;
1107
1108  if (strcmp (name, "ah_present") == 0)
1109    return ah_present;
1110
1111  if (strcmp (name, "comp_present") == 0)
1112    return comp_present;
1113
1114  if (strcmp (name, "ah_hash_alg") == 0)
1115    return ah_hash_alg;
1116
1117  if (strcmp (name, "ah_auth_alg") == 0)
1118    return ah_auth_alg;
1119
1120  if (strcmp (name, "esp_auth_alg") == 0)
1121    return esp_auth_alg;
1122
1123  if (strcmp (name, "esp_enc_alg") == 0)
1124    return esp_enc_alg;
1125
1126  if (strcmp (name, "comp_alg") == 0)
1127    return comp_alg;
1128
1129  if (strcmp (name, "ah_life_kbytes") == 0)
1130    return ah_life_kbytes;
1131
1132  if (strcmp (name, "ah_life_seconds") == 0)
1133    return ah_life_seconds;
1134
1135  if (strcmp (name, "esp_life_kbytes") == 0)
1136    return ah_life_kbytes;
1137
1138  if (strcmp (name, "esp_life_seconds") == 0)
1139    return ah_life_seconds;
1140
1141  if (strcmp (name, "comp_life_kbytes") == 0)
1142    return comp_life_kbytes;
1143
1144  if (strcmp (name, "comp_life_seconds") == 0)
1145    return comp_life_seconds;
1146
1147  if (strcmp (name, "ah_encapsulation") == 0)
1148    return ah_encapsulation;
1149
1150  if (strcmp (name, "esp_encapsulation") == 0)
1151    return esp_encapsulation;
1152
1153  if (strcmp (name, "comp_encapsulation") == 0)
1154    return comp_encapsulation;
1155
1156  if (strcmp (name, "ah_key_length") == 0)
1157    return ah_key_length;
1158
1159  if (strcmp (name, "ah_key_rounds") == 0)
1160    return ah_key_rounds;
1161
1162  if (strcmp (name, "esp_key_length") == 0)
1163    return esp_key_length;
1164
1165  if (strcmp (name, "esp_key_rounds") == 0)
1166    return esp_key_rounds;
1167
1168  if (strcmp (name, "comp_dict_size") == 0)
1169    return comp_dict_size;
1170
1171  if (strcmp (name, "comp_private_alg") == 0)
1172    return comp_private_alg;
1173
1174  if (strcmp (name, "remote_filter_type") == 0)
1175    return remote_filter_type;
1176
1177  if (strcmp (name, "remote_filter") == 0)
1178    return remote_filter;
1179
1180  if (strcmp (name, "remote_filter_addr_upper") == 0)
1181    return remote_filter_addr_upper;
1182
1183  if (strcmp (name, "remote_filter_addr_lower") == 0)
1184    return remote_filter_addr_lower;
1185
1186  if (strcmp (name, "remote_filter_port") == 0)
1187    return remote_filter_port;
1188
1189  if (strcmp (name, "remote_filter_proto") == 0)
1190    return remote_filter_proto;
1191
1192  if (strcmp (name, "local_filter_type") == 0)
1193    return local_filter_type;
1194
1195  if (strcmp (name, "local_filter") == 0)
1196    return local_filter;
1197
1198  if (strcmp (name, "local_filter_addr_upper") == 0)
1199    return local_filter_addr_upper;
1200
1201  if (strcmp (name, "local_filter_addr_lower") == 0)
1202    return local_filter_addr_lower;
1203
1204  if (strcmp (name, "local_filter_port") == 0)
1205    return local_filter_port;
1206
1207  if (strcmp (name, "local_filter_proto") == 0)
1208    return local_filter_proto;
1209
1210  if (strcmp (name, "remote_ike_address") == 0)
1211    return remote_ike_address;
1212
1213  if (strcmp (name, "local_ike_address") == 0)
1214    return local_ike_address;
1215
1216  if (strcmp (name, "remote_id_type") == 0)
1217    return remote_id_type;
1218
1219  if (strcmp (name, "remote_id") == 0)
1220    return remote_id;
1221
1222  if (strcmp (name, "remote_id_addr_upper") == 0)
1223    return remote_id_addr_upper;
1224
1225  if (strcmp (name, "remote_id_addr_lower") == 0)
1226    return remote_id_addr_lower;
1227
1228  if (strcmp (name, "remote_id_port") == 0)
1229    return remote_id_port;
1230
1231  if (strcmp (name, "remote_id_proto") == 0)
1232    return remote_id_proto;
1233
1234  return "";
1235}
1236
1237void
1238policy_init (void)
1239{
1240  char *ptr, *policy_file;
1241  char **asserts;
1242  struct stat st;
1243  int fd, len, i;
1244
1245  log_debug (LOG_MISC, 50, "policy_init: initializing");
1246
1247#if defined (HAVE_DLOPEN) && !defined (USE_KEYNOTE)
1248  if (!dyn_load (libkeynote_script))
1249    return;
1250#endif
1251
1252  /* If there exists a session already, release all its resources.  */
1253  if (keynote_sessid != -1)
1254    LK (kn_close, (keynote_sessid));
1255
1256  /* Initialize a session.  */
1257  keynote_sessid = LK (kn_init, ());
1258  if (keynote_sessid == -1)
1259    log_fatal ("policy_init: kn_init () failed");
1260
1261  /* Get policy file from configuration.  */
1262  policy_file = conf_get_str ("General", "policy-file");
1263  if (!policy_file)
1264    policy_file = POLICY_FILE_DEFAULT;
1265
1266  /* Open policy file.  */
1267  fd = open (policy_file, O_RDONLY);
1268  if (fd == -1)
1269    log_fatal ("policy_init: open (\"%s\", O_RDONLY) failed", policy_file);
1270
1271  /* Get size.  */
1272  if (fstat (fd, &st) == -1)
1273    log_fatal ("policy_init: fstat (%d, &st) failed", fd);
1274
1275  /* Allocate memory to keep policies.  */
1276  ptr = calloc (st.st_size + 1, sizeof (char));
1277  if (!ptr)
1278    log_fatal ("policy_init: calloc (%d, %d) failed", st.st_size,
1279	       sizeof (char));
1280
1281  /* Just in case there are short reads... */
1282  for (len = 0; len < st.st_size; len += i)
1283    {
1284      i = read (fd, ptr + len, st.st_size - len);
1285      if (i == -1)
1286	log_fatal ("policy_init: read (%d, %p, %d) failed", fd, ptr + len,
1287		   st.st_size - len);
1288    }
1289
1290  /* We're done with this.  */
1291  close (fd);
1292
1293  /* Parse buffer, break up into individual policies.  */
1294  asserts = LK (kn_read_asserts, (ptr, st.st_size, &i));
1295
1296  /* Begone!  */
1297  free (ptr);
1298
1299  /* Add each individual policy in the session.  */
1300  for (fd = 0; fd < i; fd++)
1301    {
1302      if (LK (kn_add_assertion, (keynote_sessid, asserts[fd],
1303				 strlen (asserts[fd]), ASSERT_FLAG_LOCAL))
1304	  == -1)
1305        log_print ("policy_init: "
1306		   "kn_add_assertion (%d, %p, %d, ASSERT_FLAG_LOCAL) failed",
1307                   keynote_sessid, asserts[fd], strlen (asserts[fd]));
1308
1309      free (asserts[fd]);
1310    }
1311
1312  if (asserts)
1313    free (asserts);
1314
1315  /* Add the callback that will handle attributes.  */
1316  if (LK (kn_add_action, (keynote_sessid, ".*", (char *) policy_callback,
1317			  ENVIRONMENT_FLAG_FUNC | ENVIRONMENT_FLAG_REGEX))
1318      == -1)
1319    log_fatal ("policy_init: "
1320	       "kn_add_action (%d, \".*\", %p, FUNC | REGEX) failed",
1321	       keynote_sessid, policy_callback);
1322}
1323