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