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