1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * NOTE:I'm trying to use "struct sadb_foo" instead of "sadb_foo_t" 27 * as a maximal PF_KEY portability test. 28 * 29 * Also, this is a deliberately single-threaded app, also for portability 30 * to systems without POSIX threads. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <sys/socket.h> 36 #include <sys/sysmacros.h> 37 #include <sys/fcntl.h> 38 #include <net/pfkeyv2.h> 39 #include <arpa/inet.h> 40 #include <netinet/in.h> 41 #include <sys/uio.h> 42 43 #include <syslog.h> 44 #include <signal.h> 45 #include <unistd.h> 46 #include <limits.h> 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <stdarg.h> 50 #include <netdb.h> 51 #include <pwd.h> 52 #include <errno.h> 53 #include <libintl.h> 54 #include <locale.h> 55 #include <fcntl.h> 56 #include <strings.h> 57 #include <ctype.h> 58 #include <sys/cladm.h> 59 60 #include <ipsec_util.h> 61 62 static int keysock; 63 static int cluster_socket; 64 static uint32_t seq; 65 static pid_t mypid; 66 static boolean_t vflag = B_FALSE; /* Verbose? */ 67 static boolean_t cflag = B_FALSE; /* Check Only */ 68 69 char *my_fmri = NULL; 70 FILE *debugfile = stdout; 71 static struct sockaddr_in cli_addr; 72 static boolean_t in_cluster_mode = B_FALSE; 73 74 #define MAX_GET_SIZE 1024 75 /* 76 * WARN() and ERROR() do the same thing really, with ERROR() the function 77 * that prints the error buffer needs to be called at the end of a code block 78 * This will print out all accumulated errors before bailing. The WARN() 79 * macro calls handle_errors() in such a way that it prints the message 80 * then continues. 81 * If the FATAL() macro used call handle_errors() immediately. 82 */ 83 #define ERROR(x, y, z) x = record_error(x, y, z) 84 #define ERROR1(w, x, y, z) w = record_error(w, x, y, z) 85 #define ERROR2(v, w, x, y, z) v = record_error(v, w, x, y, z) 86 #define WARN(x, y, z) ERROR(x, y, z);\ 87 handle_errors(x, NULL, B_FALSE, B_FALSE); x = NULL 88 #define WARN1(w, x, y, z) ERROR1(w, x, y, z);\ 89 handle_errors(w, NULL, B_FALSE, B_FALSE); w = NULL 90 #define WARN2(v, w, x, y, z) ERROR2(v, w, x, y, z);\ 91 handle_errors(v, NULL, B_FALSE, B_FALSE); v = NULL 92 #define FATAL(x, y, z) ERROR(x, y, z);\ 93 handle_errors(x, y, B_TRUE, B_TRUE) 94 #define FATAL1(w, x, y, z) ERROR1(w, x, y, z);\ 95 handle_errors(w, x, B_TRUE, B_TRUE) 96 97 /* Defined as a uint64_t array for alignment purposes. */ 98 static uint64_t get_buffer[MAX_GET_SIZE]; 99 100 /* 101 * Disable default TAB completion for now (until some brave soul tackles it). 102 */ 103 /* ARGSUSED */ 104 static 105 CPL_MATCH_FN(no_match) 106 { 107 return (0); 108 } 109 110 /* 111 * Create/Grow a buffer large enough to hold error messages. If *ebuf 112 * is not NULL then it will contain a copy of the command line that 113 * triggered the error/warning, copy this into a new buffer or 114 * append new messages to the existing buffer. 115 */ 116 /*PRINTFLIKE1*/ 117 char * 118 record_error(char *ep, char *ebuf, char *fmt, ...) 119 { 120 char *err_ptr; 121 char tmp_buff[1024]; 122 va_list ap; 123 int length = 0; 124 err_ptr = ep; 125 126 va_start(ap, fmt); 127 length = vsnprintf(tmp_buff, sizeof (tmp_buff), fmt, ap); 128 va_end(ap); 129 130 /* There is a new line character */ 131 length++; 132 133 if (ep == NULL) { 134 if (ebuf != NULL) 135 length += strlen(ebuf); 136 } else { 137 length += strlen(ep); 138 } 139 140 if (err_ptr == NULL) 141 err_ptr = calloc(length, sizeof (char)); 142 else 143 err_ptr = realloc(err_ptr, length); 144 145 if (err_ptr == NULL) 146 Bail("realloc() failure"); 147 148 /* 149 * If (ep == NULL) then this is the first error to record, 150 * copy in the command line that triggered this error/warning. 151 */ 152 if (ep == NULL && ebuf != NULL) 153 (void) strlcpy(err_ptr, ebuf, length); 154 155 /* 156 * Now the actual error. 157 */ 158 (void) strlcat(err_ptr, tmp_buff, length); 159 return (err_ptr); 160 } 161 162 /* 163 * If not in interactive mode print usage message and exit. 164 */ 165 static void 166 usage(void) 167 { 168 if (!interactive) { 169 (void) fprintf(stderr, gettext("Usage:\t" 170 "ipseckey [ -nvp ] | cmd [sa_type] [extfield value]*\n")); 171 (void) fprintf(stderr, 172 gettext("\tipseckey [ -nvp ] -f infile\n")); 173 (void) fprintf(stderr, 174 gettext("\tipseckey [ -nvp ] -s outfile\n")); 175 EXIT_FATAL(NULL); 176 } else { 177 (void) fprintf(stderr, 178 gettext("Type help or ? for usage info\n")); 179 } 180 } 181 182 183 /* 184 * Print out any errors, tidy up as required. 185 * error pointer ep will be free()'d 186 */ 187 void 188 handle_errors(char *ep, char *ebuf, boolean_t fatal, boolean_t done) 189 { 190 if (ep != NULL) { 191 if (my_fmri == NULL) { 192 /* 193 * For now suppress the errors when run from smf(5) 194 * because potentially sensitive information could 195 * end up in a publicly readable logfile. 196 */ 197 (void) fprintf(stdout, "%s\n", ep); 198 (void) fflush(stdout); 199 } 200 free(ep); 201 if (fatal) { 202 if (ebuf != NULL) { 203 free(ebuf); 204 } 205 /* reset command buffer */ 206 if (interactive) 207 longjmp(env, 1); 208 } else { 209 return; 210 } 211 } else { 212 /* 213 * No errors, if this is the last time that this function 214 * is called, free(ebuf) and reset command buffer. 215 */ 216 if (done) { 217 if (ebuf != NULL) { 218 free(ebuf); 219 } 220 /* reset command buffer */ 221 if (interactive) 222 longjmp(env, 1); 223 } 224 return; 225 } 226 EXIT_FATAL(NULL); 227 } 228 229 /* 230 * Initialize a PF_KEY base message. 231 */ 232 static void 233 msg_init(struct sadb_msg *msg, uint8_t type, uint8_t satype) 234 { 235 msg->sadb_msg_version = PF_KEY_V2; 236 msg->sadb_msg_type = type; 237 msg->sadb_msg_errno = 0; 238 msg->sadb_msg_satype = satype; 239 /* For starters... */ 240 msg->sadb_msg_len = SADB_8TO64(sizeof (*msg)); 241 msg->sadb_msg_reserved = 0; 242 msg->sadb_msg_seq = ++seq; 243 msg->sadb_msg_pid = mypid; 244 } 245 246 /* 247 * parseXXX and rparseXXX commands parse input and convert them to PF_KEY 248 * field values, or do the reverse for the purposes of saving the SA tables. 249 * (See the save_XXX functions.) 250 */ 251 252 #define CMD_NONE 0 253 #define CMD_UPDATE 2 254 #define CMD_UPDATE_PAIR 3 255 #define CMD_ADD 4 256 #define CMD_DELETE 5 257 #define CMD_DELETE_PAIR 6 258 #define CMD_GET 7 259 #define CMD_FLUSH 9 260 #define CMD_DUMP 10 261 #define CMD_MONITOR 11 262 #define CMD_PMONITOR 12 263 #define CMD_QUIT 13 264 #define CMD_SAVE 14 265 #define CMD_HELP 15 266 267 /* 268 * Parse the command. 269 */ 270 static int 271 parsecmd(char *cmdstr) 272 { 273 static struct cmdtable { 274 char *cmd; 275 int token; 276 } table[] = { 277 /* 278 * Q: Do we want to do GETSPI? 279 * A: No, it's for automated key mgmt. only. Either that, 280 * or it isn't relevant until we support non IPsec SA types. 281 */ 282 {"update", CMD_UPDATE}, 283 {"update-pair", CMD_UPDATE_PAIR}, 284 {"add", CMD_ADD}, 285 {"delete", CMD_DELETE}, 286 {"delete-pair", CMD_DELETE_PAIR}, 287 {"get", CMD_GET}, 288 /* 289 * Q: And ACQUIRE and REGISTER and EXPIRE? 290 * A: not until we support non IPsec SA types. 291 */ 292 {"flush", CMD_FLUSH}, 293 {"dump", CMD_DUMP}, 294 {"monitor", CMD_MONITOR}, 295 {"passive_monitor", CMD_PMONITOR}, 296 {"pmonitor", CMD_PMONITOR}, 297 {"quit", CMD_QUIT}, 298 {"exit", CMD_QUIT}, 299 {"save", CMD_SAVE}, 300 {"help", CMD_HELP}, 301 {"?", CMD_HELP}, 302 {NULL, CMD_NONE} 303 }; 304 struct cmdtable *ct = table; 305 306 while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0) 307 ct++; 308 return (ct->token); 309 } 310 311 /* 312 * Convert a number from a command line. I picked "u_longlong_t" for the 313 * number because we need the largest number available. Also, the strto<num> 314 * calls don't deal in units of uintNN_t. 315 */ 316 static u_longlong_t 317 parsenum(char *num, boolean_t bail, char *ebuf) 318 { 319 u_longlong_t rc = 0; 320 char *end = NULL; 321 char *ep = NULL; 322 323 if (num == NULL) { 324 FATAL(ep, ebuf, gettext("Unexpected end of command line," 325 " was expecting a number.\n")); 326 /* NOTREACHED */ 327 } 328 329 errno = 0; 330 rc = strtoull(num, &end, 0); 331 if (errno != 0 || end == num || *end != '\0') { 332 if (bail) { 333 FATAL1(ep, ebuf, gettext( 334 "Expecting a number, not \"%s\"!\n"), num); 335 } else { 336 /* 337 * -1, while not optimal, is sufficiently out of range 338 * for most of this function's applications when 339 * we don't just bail. 340 */ 341 return ((u_longlong_t)-1); 342 } 343 } 344 handle_errors(ep, NULL, B_FALSE, B_FALSE); 345 return (rc); 346 } 347 348 /* 349 * Parse and reverse parse a specific SA type (AH, ESP, etc.). 350 */ 351 static struct typetable { 352 char *type; 353 int token; 354 } type_table[] = { 355 {"all", SADB_SATYPE_UNSPEC}, 356 {"ah", SADB_SATYPE_AH}, 357 {"esp", SADB_SATYPE_ESP}, 358 /* PF_KEY NOTE: More to come if net/pfkeyv2.h gets updated. */ 359 {NULL, 0} /* Token value is irrelevant for this entry. */ 360 }; 361 362 363 static int 364 parsesatype(char *type, char *ebuf) 365 { 366 struct typetable *tt = type_table; 367 char *ep = NULL; 368 369 if (type == NULL) 370 return (SADB_SATYPE_UNSPEC); 371 372 while (tt->type != NULL && strcasecmp(tt->type, type) != 0) 373 tt++; 374 375 /* 376 * New SA types (including ones keysock maintains for user-land 377 * protocols) may be added, so parse a numeric value if possible. 378 */ 379 if (tt->type == NULL) { 380 tt->token = (int)parsenum(type, B_FALSE, ebuf); 381 if (tt->token == -1) { 382 ERROR1(ep, ebuf, gettext( 383 "Unknown SA type (%s).\n"), type); 384 tt->token = SADB_SATYPE_UNSPEC; 385 } 386 } 387 handle_errors(ep, NULL, interactive ? B_TRUE : B_FALSE, B_FALSE); 388 return (tt->token); 389 } 390 391 #define NEXTEOF 0 392 #define NEXTNONE 1 393 #define NEXTNUM 2 394 #define NEXTSTR 3 395 #define NEXTNUMSTR 4 396 #define NEXTADDR 5 397 #define NEXTHEX 6 398 #define NEXTIDENT 7 399 #define NEXTADDR4 8 400 #define NEXTADDR6 9 401 #define NEXTLABEL 10 402 403 #define TOK_EOF 0 404 #define TOK_UNKNOWN 1 405 #define TOK_SPI 2 406 #define TOK_REPLAY 3 407 #define TOK_STATE 4 408 #define TOK_AUTHALG 5 409 #define TOK_ENCRALG 6 410 #define TOK_FLAGS 7 411 #define TOK_SOFT_ALLOC 8 412 #define TOK_SOFT_BYTES 9 413 #define TOK_SOFT_ADDTIME 10 414 #define TOK_SOFT_USETIME 11 415 #define TOK_HARD_ALLOC 12 416 #define TOK_HARD_BYTES 13 417 #define TOK_HARD_ADDTIME 14 418 #define TOK_HARD_USETIME 15 419 #define TOK_CURRENT_ALLOC 16 420 #define TOK_CURRENT_BYTES 17 421 #define TOK_CURRENT_ADDTIME 18 422 #define TOK_CURRENT_USETIME 19 423 #define TOK_SRCADDR 20 424 #define TOK_DSTADDR 21 425 #define TOK_PROXYADDR 22 426 #define TOK_AUTHKEY 23 427 #define TOK_ENCRKEY 24 428 #define TOK_SRCIDTYPE 25 429 #define TOK_DSTIDTYPE 26 430 #define TOK_DPD 27 431 #define TOK_SENS_LEVEL 28 432 #define TOK_SENS_MAP 29 433 #define TOK_INTEG_LEVEL 30 434 #define TOK_INTEG_MAP 31 435 #define TOK_SRCADDR6 32 436 #define TOK_DSTADDR6 33 437 #define TOK_PROXYADDR6 34 438 #define TOK_SRCPORT 35 439 #define TOK_DSTPORT 36 440 #define TOK_PROTO 37 441 #define TOK_ENCAP 38 442 #define TOK_NATLOC 39 443 #define TOK_NATREM 40 444 #define TOK_NATLPORT 41 445 #define TOK_NATRPORT 42 446 #define TOK_IPROTO 43 447 #define TOK_IDSTADDR 44 448 #define TOK_IDSTADDR6 45 449 #define TOK_ISRCPORT 46 450 #define TOK_IDSTPORT 47 451 #define TOK_PAIR_SPI 48 452 #define TOK_FLAG_INBOUND 49 453 #define TOK_FLAG_OUTBOUND 50 454 #define TOK_REPLAY_VALUE 51 455 #define TOK_IDLE_ADDTIME 52 456 #define TOK_IDLE_USETIME 53 457 #define TOK_RESERVED 54 458 #define TOK_LABEL 55 459 #define TOK_OLABEL 56 460 #define TOK_IMPLABEL 57 461 462 463 static struct toktable { 464 char *string; 465 int token; 466 int next; 467 } tokens[] = { 468 /* "String", token value, next arg is */ 469 {"spi", TOK_SPI, NEXTNUM}, 470 {"pair-spi", TOK_PAIR_SPI, NEXTNUM}, 471 {"replay", TOK_REPLAY, NEXTNUM}, 472 {"state", TOK_STATE, NEXTNUMSTR}, 473 {"auth_alg", TOK_AUTHALG, NEXTNUMSTR}, 474 {"authalg", TOK_AUTHALG, NEXTNUMSTR}, 475 {"encr_alg", TOK_ENCRALG, NEXTNUMSTR}, 476 {"encralg", TOK_ENCRALG, NEXTNUMSTR}, 477 {"flags", TOK_FLAGS, NEXTNUM}, 478 {"soft_alloc", TOK_SOFT_ALLOC, NEXTNUM}, 479 {"soft_bytes", TOK_SOFT_BYTES, NEXTNUM}, 480 {"soft_addtime", TOK_SOFT_ADDTIME, NEXTNUM}, 481 {"soft_usetime", TOK_SOFT_USETIME, NEXTNUM}, 482 {"hard_alloc", TOK_HARD_ALLOC, NEXTNUM}, 483 {"hard_bytes", TOK_HARD_BYTES, NEXTNUM}, 484 {"hard_addtime", TOK_HARD_ADDTIME, NEXTNUM}, 485 {"hard_usetime", TOK_HARD_USETIME, NEXTNUM}, 486 {"current_alloc", TOK_CURRENT_ALLOC, NEXTNUM}, 487 {"current_bytes", TOK_CURRENT_BYTES, NEXTNUM}, 488 {"current_addtime", TOK_CURRENT_ADDTIME, NEXTNUM}, 489 {"current_usetime", TOK_CURRENT_USETIME, NEXTNUM}, 490 491 {"saddr", TOK_SRCADDR, NEXTADDR}, 492 {"srcaddr", TOK_SRCADDR, NEXTADDR}, 493 {"src", TOK_SRCADDR, NEXTADDR}, 494 {"daddr", TOK_DSTADDR, NEXTADDR}, 495 {"dstaddr", TOK_DSTADDR, NEXTADDR}, 496 {"dst", TOK_DSTADDR, NEXTADDR}, 497 {"proxyaddr", TOK_PROXYADDR, NEXTADDR}, 498 {"proxy", TOK_PROXYADDR, NEXTADDR}, 499 {"innersrc", TOK_PROXYADDR, NEXTADDR}, 500 {"isrc", TOK_PROXYADDR, NEXTADDR}, 501 {"innerdst", TOK_IDSTADDR, NEXTADDR}, 502 {"idst", TOK_IDSTADDR, NEXTADDR}, 503 504 {"sport", TOK_SRCPORT, NEXTNUM}, 505 {"dport", TOK_DSTPORT, NEXTNUM}, 506 {"innersport", TOK_ISRCPORT, NEXTNUM}, 507 {"isport", TOK_ISRCPORT, NEXTNUM}, 508 {"innerdport", TOK_IDSTPORT, NEXTNUM}, 509 {"idport", TOK_IDSTPORT, NEXTNUM}, 510 {"proto", TOK_PROTO, NEXTNUM}, 511 {"ulp", TOK_PROTO, NEXTNUM}, 512 {"iproto", TOK_IPROTO, NEXTNUM}, 513 {"iulp", TOK_IPROTO, NEXTNUM}, 514 515 {"saddr6", TOK_SRCADDR6, NEXTADDR}, 516 {"srcaddr6", TOK_SRCADDR6, NEXTADDR}, 517 {"src6", TOK_SRCADDR6, NEXTADDR}, 518 {"daddr6", TOK_DSTADDR6, NEXTADDR}, 519 {"dstaddr6", TOK_DSTADDR6, NEXTADDR}, 520 {"dst6", TOK_DSTADDR6, NEXTADDR}, 521 {"proxyaddr6", TOK_PROXYADDR6, NEXTADDR}, 522 {"proxy6", TOK_PROXYADDR6, NEXTADDR}, 523 {"innersrc6", TOK_PROXYADDR6, NEXTADDR}, 524 {"isrc6", TOK_PROXYADDR6, NEXTADDR}, 525 {"innerdst6", TOK_IDSTADDR6, NEXTADDR}, 526 {"idst6", TOK_IDSTADDR6, NEXTADDR}, 527 528 {"authkey", TOK_AUTHKEY, NEXTHEX}, 529 {"encrkey", TOK_ENCRKEY, NEXTHEX}, 530 {"srcidtype", TOK_SRCIDTYPE, NEXTIDENT}, 531 {"dstidtype", TOK_DSTIDTYPE, NEXTIDENT}, 532 {"dpd", TOK_DPD, NEXTNUM}, 533 {"sens_level", TOK_SENS_LEVEL, NEXTNUM}, 534 {"sens_map", TOK_SENS_MAP, NEXTHEX}, 535 {"integ_level", TOK_INTEG_LEVEL, NEXTNUM}, 536 {"integ_map", TOK_INTEG_MAP, NEXTHEX}, 537 {"nat_loc", TOK_NATLOC, NEXTADDR}, 538 {"nat_rem", TOK_NATREM, NEXTADDR}, 539 {"nat_lport", TOK_NATLPORT, NEXTNUM}, 540 {"nat_rport", TOK_NATRPORT, NEXTNUM}, 541 {"encap", TOK_ENCAP, NEXTNUMSTR}, 542 543 {"outbound", TOK_FLAG_OUTBOUND, NULL}, 544 {"inbound", TOK_FLAG_INBOUND, NULL}, 545 546 {"reserved_bits", TOK_RESERVED, NEXTNUM}, 547 {"replay_value", TOK_REPLAY_VALUE, NEXTNUM}, 548 {"idle_addtime", TOK_IDLE_ADDTIME, NEXTNUM}, 549 {"idle_usetime", TOK_IDLE_USETIME, NEXTNUM}, 550 551 {"label", TOK_LABEL, NEXTLABEL}, 552 {"outer-label", TOK_OLABEL, NEXTLABEL}, 553 {"implicit-label", TOK_IMPLABEL, NEXTLABEL}, 554 555 {NULL, TOK_UNKNOWN, NEXTEOF} 556 }; 557 558 /* 559 * Q: Do I need stuff for proposals, combinations, supported algorithms, 560 * or SPI ranges? 561 * 562 * A: Probably not, but you never know. 563 * 564 * Parse out extension header type values. 565 */ 566 static int 567 parseextval(char *value, int *next) 568 { 569 struct toktable *tp; 570 571 if (value == NULL) 572 return (TOK_EOF); 573 574 for (tp = tokens; tp->string != NULL; tp++) 575 if (strcmp(value, tp->string) == 0) 576 break; 577 578 /* 579 * Since the OS controls what extensions are available, we don't have 580 * to parse numeric values here. 581 */ 582 583 *next = tp->next; 584 return (tp->token); 585 } 586 587 /* 588 * Parse possible state values. 589 */ 590 static uint8_t 591 parsestate(char *state, char *ebuf) 592 { 593 struct states { 594 char *state; 595 uint8_t retval; 596 } states[] = { 597 {"larval", SADB_SASTATE_LARVAL}, 598 {"mature", SADB_SASTATE_MATURE}, 599 {"dying", SADB_SASTATE_DYING}, 600 {"dead", SADB_SASTATE_DEAD}, 601 {NULL, 0} 602 }; 603 struct states *sp; 604 char *ep = NULL; 605 606 if (state == NULL) { 607 FATAL(ep, ebuf, "Unexpected end of command line " 608 "was expecting a state.\n"); 609 } 610 611 for (sp = states; sp->state != NULL; sp++) { 612 if (strcmp(sp->state, state) == 0) 613 return (sp->retval); 614 } 615 ERROR1(ep, ebuf, gettext("Unknown state type \"%s\"\n"), state); 616 handle_errors(ep, NULL, B_FALSE, B_FALSE); 617 return (0); 618 } 619 620 /* 621 * Return the numerical algorithm identifier corresponding to the specified 622 * algorithm name. 623 */ 624 static uint8_t 625 parsealg(char *alg, int proto_num, char *ebuf) 626 { 627 u_longlong_t invalue; 628 struct ipsecalgent *algent; 629 char *ep = NULL; 630 631 if (alg == NULL) { 632 FATAL(ep, ebuf, gettext("Unexpected end of command line, " 633 "was expecting an algorithm name.\n")); 634 } 635 636 algent = getipsecalgbyname(alg, proto_num, NULL); 637 if (algent != NULL) { 638 uint8_t alg_num; 639 640 alg_num = algent->a_alg_num; 641 if (ALG_FLAG_COUNTERMODE & algent->a_alg_flags) 642 WARN1(ep, ebuf, gettext( 643 "Using manual keying with a Counter mode algorithm " 644 "such as \"%s\" may be insecure!\n"), 645 algent->a_names[0]); 646 freeipsecalgent(algent); 647 648 return (alg_num); 649 } 650 651 /* 652 * Since algorithms can be loaded during kernel run-time, check for 653 * numeric algorithm values too. PF_KEY can catch bad ones with EINVAL. 654 */ 655 invalue = parsenum(alg, B_FALSE, ebuf); 656 if (invalue != (u_longlong_t)-1 && 657 (u_longlong_t)(invalue & (u_longlong_t)0xff) == invalue) 658 return ((uint8_t)invalue); 659 660 if (proto_num == IPSEC_PROTO_ESP) { 661 ERROR1(ep, ebuf, gettext( 662 "Unknown encryption algorithm type \"%s\"\n"), alg); 663 } else { 664 ERROR1(ep, ebuf, gettext( 665 "Unknown authentication algorithm type \"%s\"\n"), alg); 666 } 667 handle_errors(ep, NULL, B_FALSE, B_FALSE); 668 return (0); 669 } 670 671 /* 672 * Parse and reverse parse out a source/destination ID type. 673 */ 674 static struct idtypes { 675 char *idtype; 676 uint8_t retval; 677 } idtypes[] = { 678 {"prefix", SADB_IDENTTYPE_PREFIX}, 679 {"fqdn", SADB_IDENTTYPE_FQDN}, 680 {"domain", SADB_IDENTTYPE_FQDN}, 681 {"domainname", SADB_IDENTTYPE_FQDN}, 682 {"user_fqdn", SADB_IDENTTYPE_USER_FQDN}, 683 {"mailbox", SADB_IDENTTYPE_USER_FQDN}, 684 {"der_dn", SADB_X_IDENTTYPE_DN}, 685 {"der_gn", SADB_X_IDENTTYPE_GN}, 686 {NULL, 0} 687 }; 688 689 static uint16_t 690 parseidtype(char *type, char *ebuf) 691 { 692 struct idtypes *idp; 693 u_longlong_t invalue; 694 char *ep = NULL; 695 696 if (type == NULL) { 697 /* Shouldn't reach here, see callers for why. */ 698 FATAL(ep, ebuf, gettext("Unexpected end of command line, " 699 "was expecting a type.\n")); 700 } 701 702 for (idp = idtypes; idp->idtype != NULL; idp++) { 703 if (strcasecmp(idp->idtype, type) == 0) 704 return (idp->retval); 705 } 706 /* 707 * Since identity types are almost arbitrary, check for numeric 708 * algorithm values too. PF_KEY can catch bad ones with EINVAL. 709 */ 710 invalue = parsenum(type, B_FALSE, ebuf); 711 if (invalue != (u_longlong_t)-1 && 712 (u_longlong_t)(invalue & (u_longlong_t)0xffff) == invalue) 713 return ((uint16_t)invalue); 714 715 716 ERROR1(ep, ebuf, gettext("Unknown identity type \"%s\"\n"), type); 717 718 handle_errors(ep, NULL, B_FALSE, B_FALSE); 719 return (0); 720 } 721 722 /* 723 * Parse an address off the command line. Return length of sockaddr, 724 * and either return a hostent pointer (caller frees). The new 725 * getipnodebyname() call does the Right Thing (TM), even with 726 * raw addresses (colon-separated IPv6 or dotted decimal IPv4). 727 */ 728 729 static struct { 730 struct hostent he; 731 char *addtl[2]; 732 } dummy; 733 static union { 734 struct in6_addr ipv6; 735 struct in_addr ipv4; 736 uint64_t aligner; 737 } addr1; 738 739 static int 740 parseaddr(char *addr, struct hostent **hpp, boolean_t v6only, char *ebuf) 741 { 742 int hp_errno; 743 struct hostent *hp = NULL; 744 char *ep = NULL; 745 746 if (addr == NULL) { 747 FATAL(ep, ebuf, gettext("Unexpected end of command line, " 748 "was expecting an address.\n")); 749 } 750 751 if (!nflag) { 752 /* 753 * Try name->address first. Assume AF_INET6, and 754 * get IPv4's, plus IPv6's if and only if IPv6 is configured. 755 * This means to add IPv6 SAs, you must have IPv6 756 * up-and-running. (AI_DEFAULT works here.) 757 */ 758 hp = getipnodebyname(addr, AF_INET6, 759 (v6only ? AI_ADDRCONFIG : (AI_DEFAULT | AI_ALL)), 760 &hp_errno); 761 } else { 762 /* 763 * Try a normal address conversion only. Use "dummy" 764 * to construct a fake hostent. Caller will know not 765 * to free this one. 766 */ 767 if (inet_pton(AF_INET6, addr, &addr1) == 1) { 768 dummy.he.h_addr_list = dummy.addtl; 769 dummy.addtl[0] = (char *)&addr1; 770 dummy.addtl[1] = NULL; 771 hp = &dummy.he; 772 dummy.he.h_addrtype = AF_INET6; 773 dummy.he.h_length = sizeof (struct in6_addr); 774 } else if (inet_pton(AF_INET, addr, &addr1) == 1) { 775 /* 776 * Remap to AF_INET6 anyway. 777 */ 778 dummy.he.h_addr_list = dummy.addtl; 779 dummy.addtl[0] = (char *)&addr1; 780 dummy.addtl[1] = NULL; 781 hp = &dummy.he; 782 dummy.he.h_addrtype = AF_INET6; 783 dummy.he.h_length = sizeof (struct in6_addr); 784 /* 785 * NOTE: If macro changes to disallow in-place 786 * conversion, rewhack this. 787 */ 788 IN6_INADDR_TO_V4MAPPED(&addr1.ipv4, &addr1.ipv6); 789 } else { 790 hp = NULL; 791 } 792 } 793 794 if (hp == NULL) 795 WARN1(ep, ebuf, gettext("Unknown address %s."), addr); 796 797 *hpp = hp; 798 /* Always return sockaddr_in6 for now. */ 799 handle_errors(ep, NULL, B_FALSE, B_FALSE); 800 return (sizeof (struct sockaddr_in6)); 801 } 802 803 /* 804 * Parse a hex character for a key. A string will take the form: 805 * xxxxxxxxx/nn 806 * where 807 * xxxxxxxxx == a string of hex characters ([0-9][a-f][A-F]) 808 * nn == an optional decimal "mask". If it is not present, it 809 * is assumed that the hex string will be rounded to the nearest 810 * byte, where odd nibbles, like 123 will become 0x0123. 811 * 812 * NOTE:Unlike the expression of IP addresses, I will not allow an 813 * excessive "mask". For example 2112/50 is very illegal. 814 * NOTE2: This key should be in canonical order. Consult your man 815 * pages per algorithm about said order. 816 */ 817 818 #define hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \ 819 (((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10))) 820 821 static struct sadb_key * 822 parsekey(char *input, char *ebuf, uint_t reserved_bits) 823 { 824 struct sadb_key *retval; 825 uint_t i, hexlen = 0, bits, alloclen; 826 uint8_t *key; 827 char *ep = NULL; 828 829 if (input == NULL) { 830 FATAL(ep, ebuf, gettext("Unexpected end of command line, " 831 "was expecting a key.\n")); 832 } 833 /* Allow hex values prepended with 0x convention */ 834 if ((strnlen(input, sizeof (hexlen)) > 2) && 835 (strncasecmp(input, "0x", 2) == 0)) 836 input += 2; 837 838 for (i = 0; input[i] != '\0' && input[i] != '/'; i++) 839 hexlen++; 840 841 if (input[i] == '\0') { 842 bits = 0; 843 } else { 844 /* Have /nn. */ 845 input[i] = '\0'; 846 if (sscanf((input + i + 1), "%u", &bits) != 1) { 847 FATAL1(ep, ebuf, gettext( 848 "\"%s\" is not a bit specifier.\n"), 849 (input + i + 1)); 850 } 851 /* hexlen in nibbles */ 852 if (((bits + 3) >> 2) > hexlen) { 853 ERROR2(ep, ebuf, gettext( 854 "bit length %d is too big for %s.\n"), bits, input); 855 } 856 /* 857 * Adjust hexlen down if user gave us too small of a bit 858 * count. 859 */ 860 if ((hexlen << 2) > bits + 3) { 861 WARN2(ep, ebuf, gettext( 862 "WARNING: Lower bits will be truncated " 863 "for:\n\t%s/%d.\n"), input, bits); 864 hexlen = (bits + 3) >> 2; 865 input[hexlen] = '\0'; 866 } 867 } 868 869 /* 870 * Allocate. Remember, hexlen is in nibbles. 871 */ 872 873 alloclen = sizeof (*retval) + roundup((hexlen/2 + (hexlen & 0x1)), 8); 874 retval = malloc(alloclen); 875 876 if (retval == NULL) 877 Bail("malloc(parsekey)"); 878 retval->sadb_key_len = SADB_8TO64(alloclen); 879 880 retval->sadb_key_reserved = reserved_bits; 881 882 if (bits == 0) 883 retval->sadb_key_bits = (hexlen + (hexlen & 0x1)) << 2; 884 else 885 retval->sadb_key_bits = bits; 886 887 /* 888 * Read in nibbles. Read in odd-numbered as shifted high. 889 * (e.g. 123 becomes 0x1230). 890 */ 891 892 key = (uint8_t *)(retval + 1); 893 for (i = 0; input[i] != '\0'; i += 2) { 894 boolean_t second = (input[i + 1] != '\0'); 895 896 if (!isxdigit(input[i]) || 897 (!isxdigit(input[i + 1]) && second)) { 898 ERROR1(ep, ebuf, gettext( 899 "string '%s' not a hex value.\n"), input); 900 free(retval); 901 retval = NULL; 902 break; 903 } 904 *key = (hd2num(input[i]) << 4); 905 if (second) 906 *key |= hd2num(input[i + 1]); 907 else 908 break; /* out of for loop. */ 909 key++; 910 } 911 912 /* bzero the remaining bits if we're a non-octet amount. */ 913 if (bits & 0x7) 914 *((input[i] == '\0') ? key - 1 : key) &= 915 0xff << (8 - (bits & 0x7)); 916 917 handle_errors(ep, NULL, B_FALSE, B_FALSE); 918 return (retval); 919 } 920 921 #include <tsol/label.h> 922 923 #define PARSELABEL_BAD_TOKEN ((struct sadb_sens *)-1) 924 925 static struct sadb_sens * 926 parselabel(int token, char *label) 927 { 928 bslabel_t *sl = NULL; 929 int err, len; 930 sadb_sens_t *sens; 931 int doi = 1; /* XXX XXX DEFAULT_DOI XXX XXX */ 932 933 err = str_to_label(label, &sl, MAC_LABEL, L_DEFAULT, NULL); 934 if (err < 0) 935 return (NULL); 936 937 len = ipsec_convert_sl_to_sens(doi, sl, NULL); 938 939 sens = malloc(len); 940 if (sens == NULL) { 941 Bail("malloc parsed label"); 942 /* Should exit before reaching here... */ 943 return (NULL); 944 } 945 946 (void) ipsec_convert_sl_to_sens(doi, sl, sens); 947 948 switch (token) { 949 case TOK_LABEL: 950 break; 951 952 case TOK_OLABEL: 953 sens->sadb_sens_exttype = SADB_X_EXT_OUTER_SENS; 954 break; 955 956 case TOK_IMPLABEL: 957 sens->sadb_sens_exttype = SADB_X_EXT_OUTER_SENS; 958 sens->sadb_x_sens_flags = SADB_X_SENS_IMPLICIT; 959 break; 960 961 default: 962 free(sens); 963 /* 964 * Return a different return code for a bad label, but really, 965 * this would be a caller error. 966 */ 967 return (PARSELABEL_BAD_TOKEN); 968 } 969 970 return (sens); 971 } 972 973 /* 974 * Write a message to the PF_KEY socket. If verbose, print the message 975 * heading into the kernel. 976 */ 977 static int 978 key_write(int fd, void *msg, size_t len) 979 { 980 if (vflag) { 981 (void) printf( 982 gettext("VERBOSE ON: Message to kernel looks like:\n")); 983 (void) printf("==========================================\n"); 984 print_samsg(stdout, msg, B_FALSE, vflag, nflag); 985 (void) printf("==========================================\n"); 986 } 987 988 return (write(fd, msg, len)); 989 } 990 991 /* 992 * SIGALRM handler for time_critical_enter. 993 */ 994 static void 995 time_critical_catch(int signal) 996 { 997 if (signal == SIGALRM) { 998 errx(1, gettext("Reply message from PF_KEY timed out.")); 999 } else { 1000 errx(1, gettext("Caught signal %d while trying to receive" 1001 "PF_KEY reply message"), signal); 1002 } 1003 /* errx() calls exit. */ 1004 } 1005 1006 #define TIME_CRITICAL_TIME 10 /* In seconds */ 1007 1008 /* 1009 * Enter a "time critical" section where key is waiting for a return message. 1010 */ 1011 static void 1012 time_critical_enter(void) 1013 { 1014 (void) signal(SIGALRM, time_critical_catch); 1015 (void) alarm(TIME_CRITICAL_TIME); 1016 } 1017 1018 /* 1019 * Exit the "time critical" section after getting an appropriate return 1020 * message. 1021 */ 1022 static void 1023 time_critical_exit(void) 1024 { 1025 (void) alarm(0); 1026 (void) signal(SIGALRM, SIG_DFL); 1027 } 1028 1029 /* 1030 * Construct a PF_KEY FLUSH message for the SA type specified. 1031 */ 1032 static void 1033 doflush(int satype) 1034 { 1035 struct sadb_msg msg; 1036 int rc; 1037 1038 msg_init(&msg, SADB_FLUSH, (uint8_t)satype); 1039 rc = key_write(keysock, &msg, sizeof (msg)); 1040 if (rc == -1) 1041 Bail("write() to PF_KEY socket failed (in doflush)"); 1042 1043 time_critical_enter(); 1044 do { 1045 rc = read(keysock, &msg, sizeof (msg)); 1046 if (rc == -1) 1047 Bail("read (in doflush)"); 1048 } while (msg.sadb_msg_seq != seq || msg.sadb_msg_pid != mypid); 1049 time_critical_exit(); 1050 1051 /* 1052 * I should _never_ hit the following unless: 1053 * 1054 * 1. There is a kernel bug. 1055 * 2. There is another process filling in its pid with mine, and 1056 * issuing a different message that would cause a different result. 1057 */ 1058 if (msg.sadb_msg_type != SADB_FLUSH || 1059 msg.sadb_msg_satype != (uint8_t)satype) { 1060 syslog((LOG_NOTICE|LOG_AUTH), 1061 gettext("doflush: Return message not of type SADB_FLUSH!")); 1062 Bail("doflush: Return message not of type SADB_FLUSH!"); 1063 } 1064 1065 if (msg.sadb_msg_errno != 0) { 1066 errno = msg.sadb_msg_errno; 1067 if (errno == EINVAL) { 1068 print_diagnostic(stderr, msg.sadb_x_msg_diagnostic); 1069 warnx(gettext("Cannot flush SA type %d."), satype); 1070 } 1071 Bail("return message (in doflush)"); 1072 } 1073 } 1074 1075 /* 1076 * save_XXX functions are used when "saving" the SA tables to either a 1077 * file or standard output. They use the dump_XXX functions where needed, 1078 * but mostly they use the rparseXXX functions. 1079 */ 1080 1081 /* 1082 * Because "save" and "dump" both use the SADB_DUMP message, fold both 1083 * into the same function. 1084 */ 1085 static void 1086 dodump(int satype, FILE *ofile) 1087 { 1088 struct sadb_msg *msg = (struct sadb_msg *)get_buffer; 1089 int rc; 1090 1091 if (ofile != NULL) { 1092 (void) fprintf(ofile, 1093 gettext("# This key file was generated by the")); 1094 (void) fprintf(ofile, 1095 gettext(" ipseckey(1m) command's 'save' feature.\n\n")); 1096 } 1097 msg_init(msg, SADB_DUMP, (uint8_t)satype); 1098 rc = key_write(keysock, msg, sizeof (*msg)); 1099 if (rc == -1) 1100 Bail("write to PF_KEY socket failed (in dodump)"); 1101 1102 do { 1103 /* 1104 * For DUMP, do only the read as a time critical section. 1105 */ 1106 time_critical_enter(); 1107 rc = read(keysock, get_buffer, sizeof (get_buffer)); 1108 time_critical_exit(); 1109 if (rc == -1) 1110 Bail("read (in dodump)"); 1111 if (msg->sadb_msg_pid == mypid && 1112 msg->sadb_msg_type == SADB_DUMP && 1113 msg->sadb_msg_seq != 0 && 1114 msg->sadb_msg_errno == 0) { 1115 if (ofile == NULL) { 1116 print_samsg(stdout, get_buffer, B_FALSE, vflag, 1117 nflag); 1118 (void) putchar('\n'); 1119 } else { 1120 save_assoc(get_buffer, ofile); 1121 } 1122 } 1123 } while (msg->sadb_msg_pid != mypid || 1124 (msg->sadb_msg_errno == 0 && msg->sadb_msg_seq != 0)); 1125 1126 if (ofile != NULL && ofile != stdout) 1127 (void) fclose(ofile); 1128 1129 if (msg->sadb_msg_errno == 0) { 1130 if (ofile == NULL) 1131 (void) printf( 1132 gettext("Dump succeeded for SA type %d.\n"), 1133 satype); 1134 } else { 1135 print_diagnostic(stderr, msg->sadb_x_msg_diagnostic); 1136 errno = msg->sadb_msg_errno; 1137 Bail("Dump failed"); 1138 } 1139 } 1140 1141 #define SCOPE_UNSPEC 0 1142 #define SCOPE_LINKLOCAL 1 1143 #define SCOPE_SITELOCAL 2 1144 #define SCOPE_GLOBAL 3 1145 #define SCOPE_V4COMPAT 4 1146 #define SCOPE_LOOPBACK 5 /* Pedantic, yes, but necessary. */ 1147 1148 static int 1149 ipv6_addr_scope(struct in6_addr *addr) 1150 { 1151 /* Don't return anything regarding multicast for now... */ 1152 1153 if (IN6_IS_ADDR_UNSPECIFIED(addr)) 1154 return (SCOPE_UNSPEC); 1155 1156 if (IN6_IS_ADDR_LINKLOCAL(addr)) 1157 return (SCOPE_LINKLOCAL); 1158 1159 if (IN6_IS_ADDR_SITELOCAL(addr)) 1160 return (SCOPE_SITELOCAL); 1161 1162 if (IN6_IS_ADDR_V4COMPAT(addr)) 1163 return (SCOPE_V4COMPAT); 1164 1165 if (IN6_IS_ADDR_LOOPBACK(addr)) 1166 return (SCOPE_LOOPBACK); 1167 1168 /* For now, return global by default. */ 1169 return (SCOPE_GLOBAL); 1170 } 1171 1172 /* 1173 * doaddresses(): 1174 * 1175 * Used by doaddup() and dodelget() to create new SA's based on the 1176 * provided source and destination addresses hostent. 1177 * 1178 * sadb_msg_type: expected PF_KEY reply message type 1179 * sadb_msg_satype: expected PF_KEY reply satype 1180 * cmd: user command 1181 * srchp: hostent for the source address(es) 1182 * dsthp: hostent for the destination address(es) 1183 * src: points to the SADB source address extension 1184 * dst: points to the SADB destination address extension 1185 * unspec_src: indicates an unspecified source address. 1186 * buffer: pointer to the SADB buffer to use with PF_KEY 1187 * buffer_size: size of buffer 1188 * spi: spi for this message (set by caller) 1189 * srcport: source port if specified 1190 * dstport: destination port if specified 1191 * proto: IP protocol number if specified 1192 * iproto: Inner (tunnel mode) IP protocol number if specified 1193 * NATT note: we are going to assume a semi-sane world where NAT 1194 * boxen don't explode to multiple addresses. 1195 */ 1196 static void 1197 doaddresses(uint8_t sadb_msg_type, uint8_t sadb_msg_satype, int cmd, 1198 struct hostent *srchp, struct hostent *dsthp, 1199 struct sadb_address *src, struct sadb_address *dst, 1200 boolean_t unspec_src, uint64_t *buffer, int buffer_size, uint32_t spi, 1201 char *ebuf) 1202 { 1203 boolean_t last_dst; 1204 struct sockaddr_in6 *sin6; 1205 struct sadb_msg *msgp; 1206 int i, rc; 1207 char **walker; /* For the SRC and PROXY walking functions. */ 1208 char *first_match; 1209 uint64_t savebuf[MAX_GET_SIZE]; 1210 uint16_t srcport = 0, dstport = 0; 1211 char *ep = NULL; 1212 1213 /* 1214 * Okay, now we have "src", "dst", and maybe "proxy" reassigned 1215 * to point into the buffer to be written to PF_KEY, we can do 1216 * potentially several writes based on destination address. 1217 * 1218 * First, obtain port numbers from passed-in extensions. 1219 */ 1220 1221 if (src != NULL) { 1222 sin6 = (struct sockaddr_in6 *)(src + 1); 1223 srcport = ntohs(sin6->sin6_port); 1224 } 1225 if (dst != NULL) { 1226 sin6 = (struct sockaddr_in6 *)(dst + 1); 1227 dstport = ntohs(sin6->sin6_port); 1228 } 1229 1230 /* 1231 * The rules for ADD, GET, and UPDATE: (NOTE: This assumes IPsec. 1232 * If other consumers of PF_KEY happen, this will have to be 1233 * rewhacked.): 1234 * 1235 * Do a message for every possible DST address. 1236 * 1237 * If a source or proxy address explodes, keep unspecified 1238 * (and mention unspecified). 1239 * 1240 * DELETE is different, because you can leave either "src" or "dst" 1241 * blank! You need to explode if one of them is full, and not assume 1242 * that the other is set. 1243 */ 1244 1245 if (dsthp == NULL) { 1246 /* 1247 * No destination address specified. 1248 * With extended diagnostics, we don't have to bail the 1249 * non-DELETE cases here. The EINVAL diagnostics will be 1250 * enough to inform the user(s) what happened. 1251 */ 1252 i = 0; 1253 do { 1254 if (srchp == &dummy.he) { 1255 /* Just to be sure... */ 1256 srchp->h_addr_list[1] = NULL; 1257 } else if (srchp != NULL) { 1258 /* Degenerate case, h_addr_list[0] == NULL. */ 1259 if (srchp->h_addr_list[i] == NULL) 1260 Bail("Empty source address list"); 1261 1262 /* 1263 * Fill in the src sockaddr. 1264 */ 1265 sin6 = (struct sockaddr_in6 *)(src + 1); 1266 bzero(sin6, sizeof (*sin6)); 1267 bcopy(srchp->h_addr_list[i], &sin6->sin6_addr, 1268 sizeof (struct in6_addr)); 1269 sin6->sin6_family = AF_INET6; 1270 sin6->sin6_port = htons(srcport); 1271 } 1272 1273 /* Save off a copy for later writing... */ 1274 msgp = (struct sadb_msg *)buffer; 1275 bcopy(buffer, savebuf, SADB_64TO8(msgp->sadb_msg_len)); 1276 1277 rc = key_write(keysock, buffer, 1278 SADB_64TO8(msgp->sadb_msg_len)); 1279 if (rc == -1) 1280 Bail("write() to PF_KEY socket " 1281 "(in doaddresses)"); 1282 /* 1283 * Sends the message to the Solaris Cluster daemon 1284 */ 1285 1286 if (in_cluster_mode) { 1287 (void) sendto(cluster_socket, buffer, 1288 SADB_64TO8(msgp->sadb_msg_len), 0, 1289 (struct sockaddr *)&cli_addr, 1290 sizeof (cli_addr)); 1291 } 1292 1293 time_critical_enter(); 1294 do { 1295 rc = read(keysock, buffer, buffer_size); 1296 if (rc == -1) 1297 Bail("read (in doaddresses)"); 1298 } while (msgp->sadb_msg_seq != seq || 1299 msgp->sadb_msg_pid != mypid); 1300 time_critical_exit(); 1301 1302 if (msgp->sadb_msg_type != sadb_msg_type || 1303 msgp->sadb_msg_satype != sadb_msg_satype) { 1304 syslog((LOG_NOTICE|LOG_AUTH), gettext( 1305 "doaddresses: Unexpected returned message " 1306 "(%d exp %d)\n"), msgp->sadb_msg_type, 1307 sadb_msg_type); 1308 Bail("doaddresses: Unexpected returned " 1309 "message"); 1310 } 1311 1312 errno = msgp->sadb_msg_errno; 1313 if (errno != 0) { 1314 if (errno == EINVAL) { 1315 WARN(ep, ebuf, gettext( 1316 "One of the entered " 1317 "values is incorrect.")); 1318 print_diagnostic(stderr, 1319 msgp->sadb_x_msg_diagnostic); 1320 } else { 1321 Bail("return message (in doaddresses)"); 1322 } 1323 } 1324 1325 /* ...and then restore the saved buffer. */ 1326 msgp = (struct sadb_msg *)savebuf; 1327 bcopy(savebuf, buffer, SADB_64TO8(msgp->sadb_msg_len)); 1328 } while (srchp != NULL && srchp->h_addr_list[++i] != NULL); 1329 return; 1330 } 1331 1332 /* 1333 * Go through the list of all dst addresses, trying to find matching 1334 * src address for each. If the first address is == dummy.he we will go 1335 * through the loop just once. If any other hp is == dummy.he, then we 1336 * don't have to apply any silly rules. 1337 */ 1338 for (i = 0; dsthp->h_addr_list[i] != NULL; i++) { 1339 if (dsthp == &dummy.he) { 1340 /* Just to be sure... */ 1341 dsthp->h_addr_list[1] = NULL; 1342 } else { 1343 /* 1344 * Fill in the dst sockaddr. 1345 */ 1346 sin6 = (struct sockaddr_in6 *)(dst + 1); 1347 bzero(sin6, sizeof (*sin6)); 1348 bcopy(dsthp->h_addr_list[i], &sin6->sin6_addr, 1349 sizeof (struct in6_addr)); 1350 sin6->sin6_family = AF_INET6; 1351 sin6->sin6_port = htons(dstport); 1352 } 1353 1354 last_dst = (dsthp->h_addr_list[i + 1] == NULL); 1355 1356 /* 1357 * Try and assign src, if there's any ambiguity. 1358 */ 1359 if (!unspec_src && srchp != &dummy.he) { 1360 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 1361 /* 1362 * IPv4 address. Find an IPv4 address, then 1363 * keep looking for a second one. If a second 1364 * exists, print a message, and fill in the 1365 * unspecified address. 1366 */ 1367 first_match = NULL; 1368 1369 for (walker = srchp->h_addr_list; 1370 *walker != NULL; walker++) { 1371 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1372 if (IN6_IS_ADDR_V4MAPPED( 1373 (struct in6_addr *)*walker)) { 1374 if (first_match != NULL) 1375 break; 1376 else 1377 first_match = *walker; 1378 } 1379 } 1380 sin6 = (struct sockaddr_in6 *)(src + 1); 1381 bzero(sin6, sizeof (*sin6)); 1382 1383 if (first_match == NULL) { 1384 /* 1385 * No IPv4 hits. Is this the last 1386 * destination address in the list ? 1387 */ 1388 ERROR1(ep, ebuf, gettext( 1389 "No IPv4 source address " 1390 "for name %s.\n"), srchp->h_name); 1391 if (last_dst) { 1392 FATAL(ep, ebuf, gettext( 1393 "No match for destination " 1394 "IP address.\n")); 1395 } else { 1396 /* Continue, but do I print? */ 1397 continue; /* for loop */ 1398 } 1399 1400 /* I should never reach here. */ 1401 } 1402 1403 sin6->sin6_family = AF_INET6; 1404 sin6->sin6_port = htons(srcport); 1405 if (*walker != NULL) { 1406 /* 1407 * Early loop exit. It must've been 1408 * multiple hits... 1409 * 1410 * Issue a null-source warning? 1411 */ 1412 WARN1(ep, ebuf, gettext( 1413 "Multiple IPv4 source addresses " 1414 "for %s, using unspecified source " 1415 "instead."), srchp->h_name); 1416 } else { 1417 /* 1418 * If I reach here w/o hitting the 1419 * previous if statements, I have a 1420 * single source address for this 1421 * destination. 1422 */ 1423 bcopy(first_match, &sin6->sin6_addr, 1424 sizeof (struct in6_addr)); 1425 } 1426 } else { 1427 /* 1428 * IPv6 address. Find an IPv6 address. 1429 * Unlike IPv4 addresses, things can get a 1430 * little more sticky with scopes, etc. 1431 */ 1432 int dst_scope, src_scope; 1433 1434 dst_scope = ipv6_addr_scope(&sin6->sin6_addr); 1435 1436 first_match = NULL; 1437 for (walker = srchp->h_addr_list; 1438 *walker != NULL; walker++) { 1439 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1440 if (!IN6_IS_ADDR_V4MAPPED( 1441 (struct in6_addr *)*walker)) { 1442 /* 1443 * Set first-match, etc. 1444 * Take into account scopes, 1445 * and other IPv6 thingies. 1446 */ 1447 src_scope = ipv6_addr_scope( 1448 /* LINTED E_BAD_PTR_CAST */ 1449 (struct in6_addr *)*walker); 1450 if (src_scope == SCOPE_UNSPEC || 1451 src_scope == dst_scope) { 1452 if (first_match != 1453 NULL) 1454 break; 1455 else 1456 first_match = 1457 *walker; 1458 } 1459 } 1460 } 1461 1462 sin6 = (struct sockaddr_in6 *)(src + 1); 1463 bzero(sin6, sizeof (*sin6)); 1464 sin6->sin6_port = htons(srcport); 1465 if (first_match == NULL) { 1466 /* 1467 * No IPv6 hits. Is this the last 1468 * destination address in the list ? 1469 */ 1470 ERROR1(ep, ebuf, gettext( 1471 "No IPv6 source address of " 1472 "matching scope for name %s.\n"), 1473 srchp->h_name); 1474 if (last_dst) { 1475 FATAL(ep, ebuf, gettext( 1476 "No match for IPV6 " 1477 "destination " 1478 "address.\n")); 1479 } else { 1480 /* Continue, but do I print? */ 1481 continue; /* for loop */ 1482 } 1483 1484 /* I should never reach here. */ 1485 } 1486 sin6->sin6_family = AF_INET6; 1487 if (*walker != NULL) { 1488 /* 1489 * Early loop exit. Issue a 1490 * null-source warning? 1491 */ 1492 WARN1(ep, ebuf, gettext( 1493 "Multiple IPv6 source addresses " 1494 "for %s of the same scope, using " 1495 "unspecified source instead.\n"), 1496 srchp->h_name); 1497 } else { 1498 /* 1499 * If I reach here w/o hitting the 1500 * previous if statements, I have a 1501 * single source address for this 1502 * destination. 1503 */ 1504 bcopy(first_match, &sin6->sin6_addr, 1505 sizeof (struct in6_addr)); 1506 } 1507 } 1508 } 1509 1510 /* 1511 * If there are errors at this point there is no 1512 * point sending anything to PF_KEY. 1513 */ 1514 handle_errors(ep, ebuf, B_TRUE, B_FALSE); 1515 1516 /* Save off a copy for later writing... */ 1517 msgp = (struct sadb_msg *)buffer; 1518 bcopy(buffer, savebuf, SADB_64TO8(msgp->sadb_msg_len)); 1519 1520 rc = key_write(keysock, buffer, SADB_64TO8(msgp->sadb_msg_len)); 1521 if (rc == -1) 1522 Bail("write() to PF_KEY socket (in doaddresses)"); 1523 1524 if (in_cluster_mode) { 1525 (void) sendto(cluster_socket, buffer, 1526 SADB_64TO8(msgp->sadb_msg_len), 0, 1527 (struct sockaddr *)&cli_addr, 1528 sizeof (cli_addr)); 1529 } 1530 /* Blank the key for paranoia's sake. */ 1531 bzero(buffer, buffer_size); 1532 time_critical_enter(); 1533 do { 1534 rc = read(keysock, buffer, buffer_size); 1535 if (rc == -1) 1536 Bail("read (in doaddresses)"); 1537 } while (msgp->sadb_msg_seq != seq || 1538 msgp->sadb_msg_pid != mypid); 1539 time_critical_exit(); 1540 1541 /* 1542 * I should _never_ hit the following unless: 1543 * 1544 * 1. There is a kernel bug. 1545 * 2. Another process is mistakenly using my pid in a PF_KEY 1546 * message. 1547 */ 1548 if (msgp->sadb_msg_type != sadb_msg_type || 1549 msgp->sadb_msg_satype != sadb_msg_satype) { 1550 syslog((LOG_NOTICE|LOG_AUTH), gettext( 1551 "doaddresses: Unexpected returned message " 1552 "(%d exp %d)\n"), msgp->sadb_msg_type, 1553 sadb_msg_type); 1554 Bail("doaddresses: Unexpected returned message"); 1555 } 1556 1557 if (msgp->sadb_msg_errno != 0) { 1558 char addrprint[INET6_ADDRSTRLEN]; 1559 int on_errno = 0; 1560 char *on_errno_msg; 1561 1562 /* 1563 * Print different error messages depending 1564 * on the SADB message type being processed. 1565 * If we get a ESRCH error for a GET/DELETE 1566 * messages, we report that the SA does not 1567 * exist. If we get a EEXIST error for a 1568 * ADD/UPDATE message, we report that the 1569 * SA already exists. 1570 */ 1571 if (sadb_msg_type == SADB_GET || 1572 sadb_msg_type == SADB_DELETE) { 1573 on_errno = ESRCH; 1574 on_errno_msg = "does not exist"; 1575 } else if (sadb_msg_type == SADB_ADD || 1576 sadb_msg_type == SADB_UPDATE) { 1577 on_errno = EEXIST; 1578 on_errno_msg = "already exists"; 1579 } 1580 1581 errno = msgp->sadb_msg_errno; 1582 if (errno == on_errno) { 1583 ERROR2(ep, ebuf, gettext( 1584 "Association (type = %s) " 1585 "with spi 0x%x and addr\n"), 1586 rparsesatype(msgp->sadb_msg_satype), 1587 ntohl(spi)); 1588 ERROR2(ep, ebuf, "%s %s.\n", 1589 do_inet_ntop(dsthp->h_addr_list[i], 1590 addrprint, sizeof (addrprint)), 1591 on_errno_msg); 1592 msgp = (struct sadb_msg *)savebuf; 1593 bcopy(savebuf, buffer, 1594 SADB_64TO8(msgp->sadb_msg_len)); 1595 continue; 1596 } else { 1597 if (errno == EINVAL || errno == ESRCH) { 1598 ERROR2(ep, ebuf, gettext( 1599 "PF_KEY Diagnostic code %u: %s.\n"), 1600 msgp->sadb_x_msg_diagnostic, 1601 keysock_diag( 1602 msgp->sadb_x_msg_diagnostic)); 1603 } else { 1604 Bail("return message (in doaddresses)"); 1605 } 1606 } 1607 } 1608 1609 if (cmd == CMD_GET) { 1610 if (msgp->sadb_msg_len > MAX_GET_SIZE) { 1611 WARN1(ep, ebuf, gettext("WARNING: " 1612 "SA information bigger than %d bytes.\n"), 1613 SADB_64TO8(MAX_GET_SIZE)); 1614 } 1615 print_samsg(stdout, buffer, B_FALSE, vflag, nflag); 1616 } 1617 1618 handle_errors(ep, ebuf, B_TRUE, B_FALSE); 1619 1620 /* ...and then restore the saved buffer. */ 1621 msgp = (struct sadb_msg *)savebuf; 1622 bcopy(savebuf, buffer, SADB_64TO8(msgp->sadb_msg_len)); 1623 lines_added++; 1624 } 1625 1626 /* Degenerate case, h_addr_list[0] == NULL. */ 1627 if (i == 0) 1628 Bail("Empty destination address list"); 1629 1630 /* 1631 * free(ebuf) even if there are no errors. 1632 * handle_errors() won't return here. 1633 */ 1634 handle_errors(ep, ebuf, B_TRUE, B_TRUE); 1635 } 1636 1637 /* 1638 * Perform an add or an update. ADD and UPDATE are similar in the extensions 1639 * they need. 1640 */ 1641 static void 1642 doaddup(int cmd, int satype, char *argv[], char *ebuf) 1643 { 1644 uint64_t *buffer, *nexthdr; 1645 struct sadb_msg msg; 1646 struct sadb_sa *assoc = NULL; 1647 struct sadb_x_pair *sadb_pair = NULL; 1648 struct sadb_address *src = NULL, *dst = NULL; 1649 struct sadb_address *isrc = NULL, *idst = NULL; 1650 struct sadb_address *natt_local = NULL, *natt_remote = NULL; 1651 struct sadb_key *encrypt = NULL, *auth = NULL; 1652 struct sadb_ident *srcid = NULL, *dstid = NULL; 1653 struct sadb_lifetime *hard = NULL, *soft = NULL; /* Current? */ 1654 struct sadb_lifetime *idle = NULL; 1655 struct sadb_x_replay_ctr *replay_ctr = NULL; 1656 struct sadb_sens *label = NULL, *olabel = NULL; 1657 struct sockaddr_in6 *sin6; 1658 /* MLS TODO: Need sensitivity eventually. */ 1659 int next, token, sa_len, alloclen, totallen = sizeof (msg), prefix; 1660 uint32_t spi = 0; 1661 uint_t reserved_bits = 0; 1662 uint8_t sadb_msg_type; 1663 char *thiscmd, *pstr; 1664 boolean_t readstate = B_FALSE, unspec_src = B_FALSE; 1665 boolean_t alloc_inner = B_FALSE, use_natt = B_FALSE; 1666 struct hostent *srchp = NULL, *dsthp = NULL, *isrchp = NULL, 1667 *idsthp = NULL; 1668 struct hostent *natt_lhp = NULL, *natt_rhp = NULL; 1669 uint16_t srcport = 0, dstport = 0, natt_lport = 0, natt_rport = 0, 1670 isrcport = 0, idstport = 0; 1671 uint8_t proto = 0, iproto = 0; 1672 char *ep = NULL; 1673 1674 switch (cmd) { 1675 case CMD_ADD: 1676 thiscmd = "add"; 1677 sadb_msg_type = SADB_ADD; 1678 break; 1679 case CMD_UPDATE: 1680 thiscmd = "update"; 1681 sadb_msg_type = SADB_UPDATE; 1682 break; 1683 case CMD_UPDATE_PAIR: 1684 thiscmd = "update-pair"; 1685 sadb_msg_type = SADB_X_UPDATEPAIR; 1686 break; 1687 } 1688 1689 msg_init(&msg, sadb_msg_type, (uint8_t)satype); 1690 /* Assume last element in argv is set to NULL. */ 1691 do { 1692 token = parseextval(*argv, &next); 1693 argv++; 1694 switch (token) { 1695 case TOK_EOF: 1696 /* Do nothing, I'm done. */ 1697 break; 1698 case TOK_UNKNOWN: 1699 ERROR1(ep, ebuf, gettext( 1700 "Unknown extension field \"%s\" \n"), *(argv - 1)); 1701 break; 1702 case TOK_SPI: 1703 case TOK_PAIR_SPI: 1704 case TOK_REPLAY: 1705 case TOK_STATE: 1706 case TOK_AUTHALG: 1707 case TOK_ENCRALG: 1708 case TOK_ENCAP: 1709 /* 1710 * May want to place this chunk of code in a function. 1711 * 1712 * This code checks for duplicate entries on a command 1713 * line. 1714 */ 1715 1716 /* Allocate the SADB_EXT_SA extension. */ 1717 if (assoc == NULL) { 1718 assoc = malloc(sizeof (*assoc)); 1719 if (assoc == NULL) 1720 Bail("malloc(assoc)"); 1721 bzero(assoc, sizeof (*assoc)); 1722 assoc->sadb_sa_exttype = SADB_EXT_SA; 1723 assoc->sadb_sa_len = 1724 SADB_8TO64(sizeof (*assoc)); 1725 totallen += sizeof (*assoc); 1726 } 1727 switch (token) { 1728 case TOK_SPI: 1729 /* 1730 * If some cretin types in "spi 0" then he/she 1731 * can type in another SPI. 1732 */ 1733 if (assoc->sadb_sa_spi != 0) { 1734 ERROR(ep, ebuf, gettext( 1735 "Can only specify " 1736 "single SPI value.\n")); 1737 break; 1738 } 1739 /* Must convert SPI to network order! */ 1740 assoc->sadb_sa_spi = 1741 htonl((uint32_t)parsenum(*argv, B_TRUE, 1742 ebuf)); 1743 if (assoc->sadb_sa_spi == 0) { 1744 ERROR(ep, ebuf, gettext( 1745 "Invalid SPI value \"0\" .\n")); 1746 } 1747 break; 1748 case TOK_PAIR_SPI: 1749 if (cmd == CMD_UPDATE_PAIR) { 1750 ERROR(ep, ebuf, gettext( 1751 "pair-spi can not be used with the " 1752 "\"update-pair\" command.\n")); 1753 } 1754 if (sadb_pair == NULL) { 1755 sadb_pair = malloc(sizeof (*sadb_pair)); 1756 if (assoc == NULL) 1757 Bail("malloc(assoc)"); 1758 bzero(sadb_pair, sizeof (*sadb_pair)); 1759 totallen += sizeof (*sadb_pair); 1760 } 1761 if (sadb_pair->sadb_x_pair_spi != 0) { 1762 ERROR(ep, ebuf, gettext( 1763 "Can only specify " 1764 "single pair SPI value.\n")); 1765 break; 1766 } 1767 /* Must convert SPI to network order! */ 1768 sadb_pair->sadb_x_pair_len = 1769 SADB_8TO64(sizeof (*sadb_pair)); 1770 sadb_pair->sadb_x_pair_exttype = 1771 SADB_X_EXT_PAIR; 1772 sadb_pair->sadb_x_pair_spi = 1773 htonl((uint32_t)parsenum(*argv, B_TRUE, 1774 ebuf)); 1775 if (sadb_pair->sadb_x_pair_spi == 0) { 1776 ERROR(ep, ebuf, gettext( 1777 "Invalid SPI value \"0\" .\n")); 1778 } 1779 assoc->sadb_sa_flags |= 1780 SADB_X_SAFLAGS_PAIRED; 1781 break; 1782 case TOK_REPLAY: 1783 /* 1784 * That same cretin can do the same with 1785 * replay. 1786 */ 1787 if (assoc->sadb_sa_replay != 0) { 1788 ERROR(ep, ebuf, gettext( 1789 "Can only specify " 1790 "single replay window size.\n")); 1791 break; 1792 } 1793 assoc->sadb_sa_replay = 1794 (uint8_t)parsenum(*argv, B_TRUE, ebuf); 1795 if (assoc->sadb_sa_replay != 0) { 1796 WARN(ep, ebuf, gettext( 1797 "WARNING: Replay with manual" 1798 " keying considered harmful.\n")); 1799 } 1800 break; 1801 case TOK_STATE: 1802 /* 1803 * 0 is an actual state value, LARVAL. This 1804 * means that one can type in the larval state 1805 * and then type in another state on the same 1806 * command line. 1807 */ 1808 if (assoc->sadb_sa_state != 0) { 1809 ERROR(ep, ebuf, gettext( 1810 "Can only specify " 1811 "single SA state.\n")); 1812 break; 1813 } 1814 assoc->sadb_sa_state = parsestate(*argv, 1815 ebuf); 1816 readstate = B_TRUE; 1817 break; 1818 case TOK_AUTHALG: 1819 if (assoc->sadb_sa_auth != 0) { 1820 ERROR(ep, ebuf, gettext( 1821 "Can only specify " 1822 "single auth algorithm.\n")); 1823 break; 1824 } 1825 assoc->sadb_sa_auth = parsealg(*argv, 1826 IPSEC_PROTO_AH, ebuf); 1827 break; 1828 case TOK_ENCRALG: 1829 if (satype == SADB_SATYPE_AH) { 1830 ERROR(ep, ebuf, gettext("Cannot specify" 1831 " encryption with SA type ah.\n")); 1832 break; 1833 } 1834 if (assoc->sadb_sa_encrypt != 0) { 1835 ERROR(ep, ebuf, gettext( 1836 "Can only specify " 1837 "single encryption algorithm.\n")); 1838 break; 1839 } 1840 assoc->sadb_sa_encrypt = parsealg(*argv, 1841 IPSEC_PROTO_ESP, ebuf); 1842 break; 1843 case TOK_ENCAP: 1844 if (use_natt) { 1845 ERROR(ep, ebuf, gettext( 1846 "Can only specify single" 1847 " encapsulation.\n")); 1848 break; 1849 } 1850 if (strncmp(*argv, "udp", 3)) { 1851 ERROR(ep, ebuf, gettext( 1852 "Can only specify udp" 1853 " encapsulation.\n")); 1854 break; 1855 } 1856 use_natt = B_TRUE; 1857 /* set assoc flags later */ 1858 break; 1859 } 1860 argv++; 1861 break; 1862 case TOK_SRCPORT: 1863 if (srcport != 0) { 1864 ERROR(ep, ebuf, gettext("Can only specify " 1865 "single source port.\n")); 1866 break; 1867 } 1868 srcport = parsenum(*argv, B_TRUE, ebuf); 1869 argv++; 1870 break; 1871 case TOK_DSTPORT: 1872 if (dstport != 0) { 1873 ERROR(ep, ebuf, gettext("Can only specify " 1874 "single destination port.\n")); 1875 break; 1876 } 1877 dstport = parsenum(*argv, B_TRUE, ebuf); 1878 argv++; 1879 break; 1880 case TOK_ISRCPORT: 1881 alloc_inner = B_TRUE; 1882 if (isrcport != 0) { 1883 ERROR(ep, ebuf, gettext( 1884 "Can only specify " 1885 "single inner-source port.\n")); 1886 break; 1887 } 1888 isrcport = parsenum(*argv, B_TRUE, ebuf); 1889 argv++; 1890 break; 1891 case TOK_IDSTPORT: 1892 alloc_inner = B_TRUE; 1893 if (idstport != 0) { 1894 ERROR(ep, ebuf, gettext( 1895 "Can only specify " 1896 "single inner-destination port.\n")); 1897 break; 1898 } 1899 idstport = parsenum(*argv, B_TRUE, ebuf); 1900 argv++; 1901 break; 1902 case TOK_NATLPORT: 1903 if (natt_lport != 0) { 1904 ERROR(ep, ebuf, gettext( 1905 "Can only specify " 1906 "single NAT-T local port.\n")); 1907 break; 1908 } 1909 natt_lport = parsenum(*argv, B_TRUE, ebuf); 1910 argv++; 1911 break; 1912 case TOK_NATRPORT: 1913 if (natt_rport != 0) { 1914 ERROR(ep, ebuf, gettext( 1915 "Can only specify " 1916 "single NAT-T remote port.\n")); 1917 break; 1918 } 1919 natt_rport = parsenum(*argv, B_TRUE, ebuf); 1920 argv++; 1921 break; 1922 1923 case TOK_PROTO: 1924 if (proto != 0) { 1925 ERROR(ep, ebuf, gettext( 1926 "Can only specify " 1927 "single protocol.\n")); 1928 break; 1929 } 1930 proto = parsenum(*argv, B_TRUE, ebuf); 1931 argv++; 1932 break; 1933 case TOK_IPROTO: 1934 alloc_inner = B_TRUE; 1935 if (iproto != 0) { 1936 ERROR(ep, ebuf, gettext( 1937 "Can only specify " 1938 "single inner protocol.\n")); 1939 break; 1940 } 1941 iproto = parsenum(*argv, B_TRUE, ebuf); 1942 argv++; 1943 break; 1944 case TOK_SRCADDR: 1945 case TOK_SRCADDR6: 1946 if (src != NULL) { 1947 ERROR(ep, ebuf, gettext( 1948 "Can only specify " 1949 "single source address.\n")); 1950 break; 1951 } 1952 sa_len = parseaddr(*argv, &srchp, 1953 (token == TOK_SRCADDR6), ebuf); 1954 if (srchp == NULL) { 1955 ERROR1(ep, ebuf, gettext( 1956 "Unknown src address \"%s\"\n"), *argv); 1957 break; 1958 } 1959 argv++; 1960 /* 1961 * Round of the sockaddr length to an 8 byte 1962 * boundary to make PF_KEY happy. 1963 */ 1964 alloclen = sizeof (*src) + roundup(sa_len, 8); 1965 src = malloc(alloclen); 1966 if (src == NULL) 1967 Bail("malloc(src)"); 1968 totallen += alloclen; 1969 src->sadb_address_len = SADB_8TO64(alloclen); 1970 src->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1971 src->sadb_address_reserved = 0; 1972 src->sadb_address_prefixlen = 0; 1973 src->sadb_address_proto = 0; 1974 if (srchp == &dummy.he) { 1975 /* 1976 * Single address with -n flag. 1977 */ 1978 sin6 = (struct sockaddr_in6 *)(src + 1); 1979 bzero(sin6, sizeof (*sin6)); 1980 sin6->sin6_family = AF_INET6; 1981 bcopy(srchp->h_addr_list[0], &sin6->sin6_addr, 1982 sizeof (struct in6_addr)); 1983 } 1984 break; 1985 case TOK_DSTADDR: 1986 case TOK_DSTADDR6: 1987 if (dst != NULL) { 1988 ERROR(ep, ebuf, gettext( 1989 "Can only specify single " 1990 "destination address.\n")); 1991 break; 1992 } 1993 sa_len = parseaddr(*argv, &dsthp, 1994 (token == TOK_DSTADDR6), ebuf); 1995 if (dsthp == NULL) { 1996 ERROR1(ep, ebuf, gettext( 1997 "Unknown dst address \"%s\"\n"), *argv); 1998 break; 1999 } 2000 argv++; 2001 alloclen = sizeof (*dst) + roundup(sa_len, 8); 2002 dst = malloc(alloclen); 2003 if (dst == NULL) 2004 Bail("malloc(dst)"); 2005 totallen += alloclen; 2006 dst->sadb_address_len = SADB_8TO64(alloclen); 2007 dst->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 2008 dst->sadb_address_reserved = 0; 2009 dst->sadb_address_prefixlen = 0; 2010 dst->sadb_address_proto = 0; 2011 if (dsthp == &dummy.he) { 2012 /* 2013 * Single address with -n flag. 2014 */ 2015 sin6 = (struct sockaddr_in6 *)(dst + 1); 2016 bzero(sin6, sizeof (*sin6)); 2017 sin6->sin6_family = AF_INET6; 2018 bcopy(dsthp->h_addr_list[0], &sin6->sin6_addr, 2019 sizeof (struct in6_addr)); 2020 } 2021 break; 2022 case TOK_PROXYADDR: 2023 case TOK_PROXYADDR6: 2024 if (isrc != NULL) { 2025 ERROR(ep, ebuf, gettext( 2026 "Can only specify single " 2027 "proxy/inner-source address.\n")); 2028 break; 2029 } 2030 if ((pstr = strchr(*argv, '/')) != NULL) { 2031 /* Parse out the prefix. */ 2032 errno = 0; 2033 prefix = strtol(pstr + 1, NULL, 10); 2034 if (errno != 0) { 2035 ERROR1(ep, ebuf, gettext( 2036 "Invalid prefix %s."), pstr); 2037 break; 2038 } 2039 /* Recycle pstr */ 2040 alloclen = (int)(pstr - *argv); 2041 pstr = malloc(alloclen + 1); 2042 if (pstr == NULL) { 2043 Bail("malloc(pstr)"); 2044 } 2045 (void) strlcpy(pstr, *argv, alloclen + 1); 2046 } else { 2047 pstr = *argv; 2048 /* 2049 * Assume mapping to AF_INET6, and we're a host. 2050 * XXX some miscreants may still make classful 2051 * assumptions. If this is a problem, fix it 2052 * here. 2053 */ 2054 prefix = 128; 2055 } 2056 sa_len = parseaddr(pstr, &isrchp, 2057 (token == TOK_PROXYADDR6), ebuf); 2058 if (isrchp == NULL) { 2059 ERROR1(ep, ebuf, gettext( 2060 "Unknown proxy/inner-source address " 2061 "\"%s\"\n"), *argv); 2062 break; 2063 } 2064 if (pstr != *argv) 2065 free(pstr); 2066 argv++; 2067 alloclen = sizeof (*isrc) + roundup(sa_len, 8); 2068 isrc = malloc(alloclen); 2069 if (isrc == NULL) 2070 Bail("malloc(isrc)"); 2071 totallen += alloclen; 2072 isrc->sadb_address_len = SADB_8TO64(alloclen); 2073 isrc->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; 2074 isrc->sadb_address_reserved = 0; 2075 isrc->sadb_address_prefixlen = prefix; 2076 isrc->sadb_address_proto = 0; 2077 if (isrchp == &dummy.he || 2078 isrchp->h_addr_list[1] == NULL) { 2079 /* 2080 * Single address with -n flag or single name. 2081 */ 2082 sin6 = (struct sockaddr_in6 *)(isrc + 1); 2083 bzero(sin6, sizeof (*sin6)); 2084 sin6->sin6_family = AF_INET6; 2085 bcopy(isrchp->h_addr_list[0], &sin6->sin6_addr, 2086 sizeof (struct in6_addr)); 2087 /* 2088 * normalize prefixlen for IPv4-mapped 2089 * addresses. 2090 */ 2091 if (prefix <= 32 && 2092 IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 2093 isrc->sadb_address_prefixlen += 96; 2094 alloc_inner = B_TRUE; 2095 } else { 2096 /* 2097 * If the proxy/isrc address is vague, don't 2098 * bother. 2099 */ 2100 totallen -= alloclen; 2101 free(isrc); 2102 isrc = NULL; 2103 WARN1(ep, ebuf, gettext( 2104 "Proxy/inner-source address %s " 2105 "is vague, not using.\n"), isrchp->h_name); 2106 freehostent(isrchp); 2107 isrchp = NULL; 2108 break; 2109 } 2110 break; 2111 case TOK_IDSTADDR: 2112 case TOK_IDSTADDR6: 2113 if (idst != NULL) { 2114 ERROR(ep, ebuf, gettext( 2115 "Can only specify single " 2116 "inner-destination address.\n")); 2117 break; 2118 } 2119 if ((pstr = strchr(*argv, '/')) != NULL) { 2120 /* Parse out the prefix. */ 2121 errno = 0; 2122 prefix = strtol(pstr + 1, NULL, 10); 2123 if (errno != 0) { 2124 ERROR1(ep, ebuf, gettext( 2125 "Invalid prefix %s.\n"), pstr); 2126 break; 2127 } 2128 /* Recycle pstr */ 2129 alloclen = (int)(pstr - *argv); 2130 pstr = malloc(alloclen + 1); 2131 if (pstr == NULL) { 2132 Bail("malloc(pstr)"); 2133 } 2134 (void) strlcpy(pstr, *argv, alloclen + 1); 2135 } else { 2136 pstr = *argv; 2137 /* 2138 * Assume mapping to AF_INET6, and we're a host. 2139 * XXX some miscreants may still make classful 2140 * assumptions. If this is a problem, fix it 2141 * here. 2142 */ 2143 prefix = 128; 2144 } 2145 sa_len = parseaddr(pstr, &idsthp, 2146 (token == TOK_IDSTADDR6), ebuf); 2147 if (idsthp == NULL) { 2148 ERROR1(ep, ebuf, gettext( 2149 "Unknown Inner Src address " 2150 " \"%s\"\n"), *argv); 2151 break; 2152 } 2153 if (pstr != *argv) 2154 free(pstr); 2155 argv++; 2156 alloclen = sizeof (*idst) + roundup(sa_len, 8); 2157 idst = malloc(alloclen); 2158 if (idst == NULL) 2159 Bail("malloc(idst)"); 2160 totallen += alloclen; 2161 idst->sadb_address_len = SADB_8TO64(alloclen); 2162 idst->sadb_address_exttype = 2163 SADB_X_EXT_ADDRESS_INNER_DST; 2164 idst->sadb_address_reserved = 0; 2165 idst->sadb_address_prefixlen = prefix; 2166 idst->sadb_address_proto = 0; 2167 if (idsthp == &dummy.he || 2168 idsthp->h_addr_list[1] == NULL) { 2169 /* 2170 * Single address with -n flag or single name. 2171 */ 2172 sin6 = (struct sockaddr_in6 *)(idst + 1); 2173 bzero(sin6, sizeof (*sin6)); 2174 sin6->sin6_family = AF_INET6; 2175 bcopy(idsthp->h_addr_list[0], &sin6->sin6_addr, 2176 sizeof (struct in6_addr)); 2177 /* 2178 * normalize prefixlen for IPv4-mapped 2179 * addresses. 2180 */ 2181 if (prefix <= 32 && 2182 IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 2183 idst->sadb_address_prefixlen += 96; 2184 alloc_inner = B_TRUE; 2185 } else { 2186 /* 2187 * If the idst address is vague, don't bother. 2188 */ 2189 totallen -= alloclen; 2190 free(idst); 2191 idst = NULL; 2192 WARN1(ep, ebuf, gettext( 2193 "Inner destination address %s " 2194 "is vague, not using.\n"), idsthp->h_name); 2195 freehostent(idsthp); 2196 idsthp = NULL; 2197 break; 2198 } 2199 break; 2200 case TOK_NATLOC: 2201 if (natt_local != NULL) { 2202 ERROR(ep, ebuf, gettext( 2203 "Can only specify " 2204 "single NAT-T local address.\n")); 2205 break; 2206 } 2207 sa_len = parseaddr(*argv, &natt_lhp, 0, ebuf); 2208 if (natt_lhp == NULL) { 2209 ERROR1(ep, ebuf, gettext( 2210 "Unknown NAT-T local address \"%s\"\n"), 2211 *argv); 2212 break; 2213 } 2214 argv++; 2215 /* 2216 * Round of the sockaddr length to an 8 byte 2217 * boundary to make PF_KEY happy. 2218 */ 2219 alloclen = sizeof (*natt_local) + roundup(sa_len, 8); 2220 natt_local = malloc(alloclen); 2221 if (natt_local == NULL) 2222 Bail("malloc(natt_local)"); 2223 totallen += alloclen; 2224 natt_local->sadb_address_len = SADB_8TO64(alloclen); 2225 natt_local->sadb_address_exttype = 2226 SADB_X_EXT_ADDRESS_NATT_LOC; 2227 natt_local->sadb_address_reserved = 0; 2228 natt_local->sadb_address_prefixlen = 0; 2229 natt_local->sadb_address_proto = 0; 2230 if (natt_lhp == &dummy.he || 2231 natt_lhp->h_addr_list[1] == NULL) { 2232 /* 2233 * Single address with -n flag or single name. 2234 */ 2235 sin6 = (struct sockaddr_in6 *)(natt_local + 1); 2236 bzero(sin6, sizeof (*sin6)); 2237 sin6->sin6_family = AF_INET6; 2238 bcopy(natt_lhp->h_addr_list[0], 2239 &sin6->sin6_addr, sizeof (struct in6_addr)); 2240 } else { 2241 /* 2242 * If the nat-local address is vague, don't 2243 * bother. 2244 */ 2245 totallen -= alloclen; 2246 free(natt_local); 2247 natt_local = NULL; 2248 WARN1(ep, ebuf, gettext( 2249 "NAT-T local address %s " 2250 "is vague, not using.\n"), 2251 natt_lhp->h_name); 2252 freehostent(natt_lhp); 2253 natt_lhp = NULL; 2254 break; 2255 } 2256 break; 2257 case TOK_NATREM: 2258 if (natt_remote != NULL) { 2259 ERROR(ep, ebuf, gettext( 2260 "Can only specify " 2261 "single NAT-T remote address.\n")); 2262 break; 2263 } 2264 sa_len = parseaddr(*argv, &natt_rhp, 0, ebuf); 2265 if (natt_rhp == NULL) { 2266 ERROR1(ep, ebuf, gettext( 2267 "Unknown NAT-T remote address \"%s\"\n"), 2268 *argv); 2269 break; 2270 } 2271 argv++; 2272 /* 2273 * Round of the sockaddr length to an 8 byte 2274 * boundary to make PF_KEY happy. 2275 */ 2276 alloclen = sizeof (*natt_remote) + roundup(sa_len, 8); 2277 natt_remote = malloc(alloclen); 2278 if (natt_remote == NULL) 2279 Bail("malloc(natt_remote)"); 2280 totallen += alloclen; 2281 natt_remote->sadb_address_len = SADB_8TO64(alloclen); 2282 natt_remote->sadb_address_exttype = 2283 SADB_X_EXT_ADDRESS_NATT_REM; 2284 natt_remote->sadb_address_reserved = 0; 2285 natt_remote->sadb_address_prefixlen = 0; 2286 natt_remote->sadb_address_proto = 0; 2287 if (natt_rhp == &dummy.he || 2288 natt_rhp->h_addr_list[1] == NULL) { 2289 /* 2290 * Single address with -n flag or single name. 2291 */ 2292 sin6 = (struct sockaddr_in6 *)(natt_remote + 1); 2293 bzero(sin6, sizeof (*sin6)); 2294 sin6->sin6_family = AF_INET6; 2295 bcopy(natt_rhp->h_addr_list[0], 2296 &sin6->sin6_addr, sizeof (struct in6_addr)); 2297 } else { 2298 /* 2299 * If the nat-renote address is vague, don't 2300 * bother. 2301 */ 2302 totallen -= alloclen; 2303 free(natt_remote); 2304 natt_remote = NULL; 2305 WARN1(ep, ebuf, gettext( 2306 "NAT-T remote address %s " 2307 "is vague, not using.\n"), 2308 natt_rhp->h_name); 2309 freehostent(natt_rhp); 2310 natt_rhp = NULL; 2311 break; 2312 } 2313 break; 2314 case TOK_ENCRKEY: 2315 if (encrypt != NULL) { 2316 ERROR(ep, ebuf, gettext( 2317 "Can only specify " 2318 "single encryption key.\n")); 2319 break; 2320 } 2321 if (assoc != NULL && 2322 assoc->sadb_sa_encrypt == SADB_EALG_NULL) { 2323 FATAL(ep, ebuf, gettext( 2324 "Cannot specify a key with NULL " 2325 "encryption algorithm.\n")); 2326 break; 2327 } 2328 encrypt = parsekey(*argv, ebuf, reserved_bits); 2329 argv++; 2330 if (encrypt == NULL) { 2331 ERROR(ep, ebuf, gettext( 2332 "Invalid encryption key.\n")); 2333 break; 2334 } 2335 totallen += SADB_64TO8(encrypt->sadb_key_len); 2336 encrypt->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 2337 break; 2338 case TOK_AUTHKEY: 2339 if (auth != NULL) { 2340 ERROR(ep, ebuf, gettext( 2341 "Can only specify single" 2342 " authentication key.\n")); 2343 break; 2344 } 2345 auth = parsekey(*argv, ebuf, 0); 2346 argv++; 2347 if (auth == NULL) { 2348 ERROR(ep, ebuf, gettext( 2349 "Invalid authentication key.\n")); 2350 break; 2351 } 2352 totallen += SADB_64TO8(auth->sadb_key_len); 2353 auth->sadb_key_exttype = SADB_EXT_KEY_AUTH; 2354 break; 2355 case TOK_SRCIDTYPE: 2356 if (*argv == NULL || *(argv + 1) == NULL) { 2357 FATAL(ep, ebuf, gettext( 2358 "Unexpected end of command " 2359 "line - Expecting Src Type.\n")); 2360 /* NOTREACHED */ 2361 break; 2362 } 2363 if (srcid != NULL) { 2364 ERROR(ep, ebuf, gettext( 2365 "Can only specify single" 2366 " source certificate identity.\n")); 2367 break; 2368 } 2369 alloclen = sizeof (*srcid) + 2370 roundup(strlen(*(argv + 1)) + 1, 8); 2371 srcid = malloc(alloclen); 2372 if (srcid == NULL) 2373 Bail("malloc(srcid)"); 2374 totallen += alloclen; 2375 srcid->sadb_ident_type = parseidtype(*argv, ebuf); 2376 argv++; 2377 srcid->sadb_ident_len = SADB_8TO64(alloclen); 2378 srcid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 2379 srcid->sadb_ident_reserved = 0; 2380 srcid->sadb_ident_id = 0; /* Not useful here. */ 2381 (void) strlcpy((char *)(srcid + 1), *argv, alloclen); 2382 argv++; 2383 break; 2384 case TOK_DSTIDTYPE: 2385 if (*argv == NULL || *(argv + 1) == NULL) { 2386 ERROR(ep, ebuf, gettext( 2387 "Unexpected end of command" 2388 " line - expecting dst type.\n")); 2389 break; 2390 } 2391 if (dstid != NULL) { 2392 ERROR(ep, ebuf, gettext( 2393 "Can only specify single destination " 2394 "certificate identity.\n")); 2395 break; 2396 } 2397 alloclen = sizeof (*dstid) + 2398 roundup(strlen(*(argv + 1)) + 1, 8); 2399 dstid = malloc(alloclen); 2400 if (dstid == NULL) 2401 Bail("malloc(dstid)"); 2402 totallen += alloclen; 2403 dstid->sadb_ident_type = parseidtype(*argv, ebuf); 2404 argv++; 2405 dstid->sadb_ident_len = SADB_8TO64(alloclen); 2406 dstid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 2407 dstid->sadb_ident_reserved = 0; 2408 dstid->sadb_ident_id = 0; /* Not useful here. */ 2409 (void) strlcpy((char *)(dstid + 1), *argv, alloclen); 2410 argv++; 2411 break; 2412 case TOK_HARD_ALLOC: 2413 case TOK_HARD_BYTES: 2414 case TOK_HARD_ADDTIME: 2415 case TOK_HARD_USETIME: 2416 if (hard == NULL) { 2417 hard = malloc(sizeof (*hard)); 2418 if (hard == NULL) 2419 Bail("malloc(hard_lifetime)"); 2420 bzero(hard, sizeof (*hard)); 2421 hard->sadb_lifetime_exttype = 2422 SADB_EXT_LIFETIME_HARD; 2423 hard->sadb_lifetime_len = 2424 SADB_8TO64(sizeof (*hard)); 2425 totallen += sizeof (*hard); 2426 } 2427 switch (token) { 2428 case TOK_HARD_ALLOC: 2429 if (hard->sadb_lifetime_allocations != 0) { 2430 ERROR(ep, ebuf, gettext( 2431 "Can only specify single" 2432 " hard allocation limit.\n")); 2433 break; 2434 } 2435 hard->sadb_lifetime_allocations = 2436 (uint32_t)parsenum(*argv, B_TRUE, ebuf); 2437 break; 2438 case TOK_HARD_BYTES: 2439 if (hard->sadb_lifetime_bytes != 0) { 2440 ERROR(ep, ebuf, gettext( 2441 "Can only specify " 2442 "single hard byte limit.\n")); 2443 break; 2444 } 2445 hard->sadb_lifetime_bytes = parsenum(*argv, 2446 B_TRUE, ebuf); 2447 break; 2448 case TOK_HARD_ADDTIME: 2449 if (hard->sadb_lifetime_addtime != 0) { 2450 ERROR(ep, ebuf, gettext( 2451 "Can only specify " 2452 "single past-add lifetime.\n")); 2453 break; 2454 } 2455 hard->sadb_lifetime_addtime = parsenum(*argv, 2456 B_TRUE, ebuf); 2457 break; 2458 case TOK_HARD_USETIME: 2459 if (hard->sadb_lifetime_usetime != 0) { 2460 ERROR(ep, ebuf, gettext( 2461 "Can only specify " 2462 "single past-use lifetime.\n")); 2463 break; 2464 } 2465 hard->sadb_lifetime_usetime = parsenum(*argv, 2466 B_TRUE, ebuf); 2467 break; 2468 } 2469 argv++; 2470 break; 2471 case TOK_SOFT_ALLOC: 2472 case TOK_SOFT_BYTES: 2473 case TOK_SOFT_ADDTIME: 2474 case TOK_SOFT_USETIME: 2475 if (soft == NULL) { 2476 soft = malloc(sizeof (*soft)); 2477 if (soft == NULL) 2478 Bail("malloc(soft_lifetime)"); 2479 bzero(soft, sizeof (*soft)); 2480 soft->sadb_lifetime_exttype = 2481 SADB_EXT_LIFETIME_SOFT; 2482 soft->sadb_lifetime_len = 2483 SADB_8TO64(sizeof (*soft)); 2484 totallen += sizeof (*soft); 2485 } 2486 switch (token) { 2487 case TOK_SOFT_ALLOC: 2488 if (soft->sadb_lifetime_allocations != 0) { 2489 ERROR(ep, ebuf, gettext( 2490 "Can only specify single" 2491 " soft allocation limit.\n")); 2492 break; 2493 } 2494 soft->sadb_lifetime_allocations = 2495 (uint32_t)parsenum(*argv, B_TRUE, ebuf); 2496 break; 2497 case TOK_SOFT_BYTES: 2498 if (soft->sadb_lifetime_bytes != 0) { 2499 ERROR(ep, ebuf, gettext( 2500 "Can only specify single" 2501 " soft byte limit.\n")); 2502 break; 2503 } 2504 soft->sadb_lifetime_bytes = parsenum(*argv, 2505 B_TRUE, ebuf); 2506 break; 2507 case TOK_SOFT_ADDTIME: 2508 if (soft->sadb_lifetime_addtime != 0) { 2509 ERROR(ep, ebuf, gettext( 2510 "Can only specify single" 2511 " past-add lifetime.\n")); 2512 break; 2513 } 2514 soft->sadb_lifetime_addtime = parsenum(*argv, 2515 B_TRUE, ebuf); 2516 break; 2517 case TOK_SOFT_USETIME: 2518 if (soft->sadb_lifetime_usetime != 0) { 2519 ERROR(ep, ebuf, gettext( 2520 "Can only specify single" 2521 " past-use lifetime.\n")); 2522 break; 2523 } 2524 soft->sadb_lifetime_usetime = parsenum(*argv, 2525 B_TRUE, ebuf); 2526 break; 2527 } 2528 argv++; 2529 break; 2530 case TOK_FLAG_INBOUND: 2531 assoc->sadb_sa_flags |= SADB_X_SAFLAGS_INBOUND; 2532 break; 2533 case TOK_FLAG_OUTBOUND: 2534 assoc->sadb_sa_flags |= SADB_X_SAFLAGS_OUTBOUND; 2535 break; 2536 case TOK_REPLAY_VALUE: 2537 if (replay_ctr != NULL) { 2538 ERROR(ep, ebuf, gettext( 2539 "Can only specify single " 2540 "replay value.")); 2541 break; 2542 } 2543 replay_ctr = calloc(1, sizeof (*replay_ctr)); 2544 if (replay_ctr == NULL) { 2545 Bail("malloc(replay value)"); 2546 } 2547 /* 2548 * We currently do not support a 64-bit 2549 * replay value. RFC 4301 will require one, 2550 * however, and we have a field in place when 2551 * 4301 is built. 2552 */ 2553 replay_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE; 2554 replay_ctr->sadb_x_rc_len = 2555 SADB_8TO64(sizeof (*replay_ctr)); 2556 totallen += sizeof (*replay_ctr); 2557 replay_ctr->sadb_x_rc_replay32 = (uint32_t)parsenum( 2558 *argv, B_TRUE, ebuf); 2559 argv++; 2560 break; 2561 case TOK_IDLE_ADDTIME: 2562 case TOK_IDLE_USETIME: 2563 if (idle == NULL) { 2564 idle = calloc(1, sizeof (*idle)); 2565 if (idle == NULL) { 2566 Bail("malloc idle lifetime"); 2567 } 2568 idle->sadb_lifetime_exttype = 2569 SADB_X_EXT_LIFETIME_IDLE; 2570 idle->sadb_lifetime_len = 2571 SADB_8TO64(sizeof (*idle)); 2572 totallen += sizeof (*idle); 2573 } 2574 switch (token) { 2575 case TOK_IDLE_ADDTIME: 2576 idle->sadb_lifetime_addtime = 2577 (uint32_t)parsenum(*argv, 2578 B_TRUE, ebuf); 2579 break; 2580 case TOK_IDLE_USETIME: 2581 idle->sadb_lifetime_usetime = 2582 (uint32_t)parsenum(*argv, 2583 B_TRUE, ebuf); 2584 break; 2585 } 2586 argv++; 2587 break; 2588 case TOK_RESERVED: 2589 if (encrypt != NULL) 2590 ERROR(ep, ebuf, gettext( 2591 "Reserved bits need to be " 2592 "specified before key.\n")); 2593 reserved_bits = (uint_t)parsenum(*argv, 2594 B_TRUE, ebuf); 2595 argv++; 2596 break; 2597 case TOK_LABEL: 2598 label = parselabel(token, *argv); 2599 argv++; 2600 if (label == NULL) { 2601 ERROR(ep, ebuf, 2602 gettext("Malformed security label\n")); 2603 break; 2604 } else if (label == PARSELABEL_BAD_TOKEN) { 2605 Bail("Internal token value error"); 2606 } 2607 totallen += SADB_64TO8(label->sadb_sens_len); 2608 break; 2609 2610 case TOK_OLABEL: 2611 case TOK_IMPLABEL: 2612 olabel = parselabel(token, *argv); 2613 argv++; 2614 if (label == NULL) { 2615 ERROR(ep, ebuf, 2616 gettext("Malformed security label\n")); 2617 break; 2618 } else if (label == PARSELABEL_BAD_TOKEN) { 2619 Bail("Internal token value error"); 2620 } 2621 totallen += SADB_64TO8(olabel->sadb_sens_len); 2622 break; 2623 default: 2624 ERROR1(ep, ebuf, gettext( 2625 "Don't use extension %s for add/update.\n"), 2626 *(argv - 1)); 2627 break; 2628 } 2629 } while (token != TOK_EOF); 2630 2631 handle_errors(ep, ebuf, B_TRUE, B_FALSE); 2632 2633 #define PORT_ONLY_ALLOCATE(af, socktype, exttype, extvar, port) { \ 2634 alloclen = sizeof (sadb_address_t) + roundup(sizeof (socktype), 8); \ 2635 (extvar) = calloc(1, alloclen); \ 2636 if ((extvar) == NULL) { \ 2637 Bail("malloc(implicit port)"); \ 2638 } \ 2639 totallen += alloclen; \ 2640 (extvar)->sadb_address_len = SADB_8TO64(alloclen); \ 2641 (extvar)->sadb_address_exttype = (exttype); \ 2642 /* sin/sin6 has equivalent offsets for ports! */ \ 2643 sin6 = (struct sockaddr_in6 *)((extvar) + 1); \ 2644 sin6->sin6_family = (af); \ 2645 sin6->sin6_port = (port); \ 2646 } 2647 2648 /* 2649 * If we specify inner ports or NAT ports w/o addresses, we still need 2650 * to allocate. Also, if we have one inner address, we need the 2651 * other, even if we don't specify anything. 2652 */ 2653 if (use_natt) { 2654 if (natt_lport != 0 && natt_local == NULL) { 2655 PORT_ONLY_ALLOCATE(AF_INET, struct sockaddr_in, 2656 SADB_X_EXT_ADDRESS_NATT_LOC, natt_local, 2657 natt_lport); 2658 } 2659 2660 if (natt_rport != 0 && natt_remote == NULL) { 2661 PORT_ONLY_ALLOCATE(AF_INET, struct sockaddr_in, 2662 SADB_X_EXT_ADDRESS_NATT_REM, natt_remote, 2663 natt_rport); 2664 } 2665 } else { 2666 if (natt_lport != 0 || natt_rport != 0) { 2667 ERROR(ep, ebuf, gettext("Must specify 'encap udp' " 2668 "with any NAT-T port.\n")); 2669 } else if (natt_local != NULL || natt_remote != NULL) { 2670 ERROR(ep, ebuf, gettext("Must specify 'encap udp' " 2671 "with any NAT-T address.\n")); 2672 } 2673 } 2674 2675 if (alloc_inner && idst == NULL) { 2676 PORT_ONLY_ALLOCATE(AF_INET6, struct sockaddr_in6, 2677 SADB_X_EXT_ADDRESS_INNER_DST, idst, 0); 2678 } 2679 2680 if (alloc_inner && isrc == NULL) { 2681 PORT_ONLY_ALLOCATE(AF_INET6, struct sockaddr_in6, 2682 SADB_X_EXT_ADDRESS_INNER_SRC, isrc, 0); 2683 } 2684 #undef PORT_ONLY_ALLOCATE 2685 2686 /* 2687 * Okay, so now I have all of the potential extensions! 2688 * Allocate a single contiguous buffer. Keep in mind that it'll 2689 * be enough because the key itself will be yanked. 2690 */ 2691 2692 if (src == NULL && dst != NULL) { 2693 /* 2694 * Set explicit unspecified source address. 2695 */ 2696 size_t lenbytes = SADB_64TO8(dst->sadb_address_len); 2697 2698 unspec_src = B_TRUE; 2699 totallen += lenbytes; 2700 src = malloc(lenbytes); 2701 if (src == NULL) 2702 Bail("malloc(implicit src)"); 2703 /* Confusing, but we're copying from DST to SRC. :) */ 2704 bcopy(dst, src, lenbytes); 2705 src->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 2706 sin6 = (struct sockaddr_in6 *)(src + 1); 2707 bzero(sin6, sizeof (*sin6)); 2708 sin6->sin6_family = AF_INET6; 2709 } 2710 2711 msg.sadb_msg_len = SADB_8TO64(totallen); 2712 2713 buffer = malloc(totallen); 2714 nexthdr = buffer; 2715 bcopy(&msg, nexthdr, sizeof (msg)); 2716 nexthdr += SADB_8TO64(sizeof (msg)); 2717 if (assoc != NULL) { 2718 if (assoc->sadb_sa_spi == 0) { 2719 ERROR1(ep, ebuf, gettext( 2720 "The SPI value is missing for " 2721 "the association you wish to %s.\n"), thiscmd); 2722 } 2723 if (assoc->sadb_sa_auth == 0 && assoc->sadb_sa_encrypt == 0 && 2724 cmd == CMD_ADD) { 2725 free(assoc); 2726 FATAL(ep, ebuf, gettext( 2727 "Select at least one algorithm " 2728 "for this add.\n")); 2729 } 2730 2731 /* Hack to let user specify NULL ESP implicitly. */ 2732 if (msg.sadb_msg_satype == SADB_SATYPE_ESP && 2733 assoc->sadb_sa_encrypt == 0) 2734 assoc->sadb_sa_encrypt = SADB_EALG_NULL; 2735 2736 /* 0 is an actual value. Print a warning if it was entered. */ 2737 if (assoc->sadb_sa_state == 0) { 2738 if (readstate) { 2739 ERROR(ep, ebuf, gettext( 2740 "WARNING: Cannot set LARVAL SA state.\n")); 2741 } 2742 assoc->sadb_sa_state = SADB_SASTATE_MATURE; 2743 } 2744 2745 if (use_natt) { 2746 if (natt_remote != NULL) 2747 assoc->sadb_sa_flags |= SADB_X_SAFLAGS_NATT_REM; 2748 if (natt_local != NULL) 2749 assoc->sadb_sa_flags |= SADB_X_SAFLAGS_NATT_LOC; 2750 } 2751 2752 if (alloc_inner) { 2753 /* 2754 * For now, assume RFC 3884's dream of transport-mode 2755 * SAs with inner IP address selectors will not 2756 * happen. 2757 */ 2758 assoc->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; 2759 if (proto != 0 && proto != IPPROTO_ENCAP && 2760 proto != IPPROTO_IPV6) { 2761 ERROR1(ep, ebuf, gettext( 2762 "WARNING: Protocol type %d not " 2763 "for use with Tunnel-Mode SA.\n"), proto); 2764 /* Continue and let PF_KEY scream... */ 2765 } 2766 } 2767 2768 bcopy(assoc, nexthdr, SADB_64TO8(assoc->sadb_sa_len)); 2769 nexthdr += assoc->sadb_sa_len; 2770 /* Save the SPI for the case of an error. */ 2771 spi = assoc->sadb_sa_spi; 2772 free(assoc); 2773 } else { 2774 if (spi == 0) 2775 ERROR1(ep, ebuf, gettext( 2776 "Need to define SPI for %s.\n"), thiscmd); 2777 ERROR1(ep, ebuf, gettext( 2778 "Need SA parameters for %s.\n"), thiscmd); 2779 } 2780 2781 if (sadb_pair != NULL) { 2782 if (sadb_pair->sadb_x_pair_spi == 0) { 2783 ERROR1(ep, ebuf, gettext( 2784 "The SPI value is missing for the " 2785 "association you wish to %s.\n"), thiscmd); 2786 } 2787 bcopy(sadb_pair, nexthdr, 2788 SADB_64TO8(sadb_pair->sadb_x_pair_len)); 2789 nexthdr += sadb_pair->sadb_x_pair_len; 2790 free(sadb_pair); 2791 } 2792 2793 if (hard != NULL) { 2794 bcopy(hard, nexthdr, SADB_64TO8(hard->sadb_lifetime_len)); 2795 nexthdr += hard->sadb_lifetime_len; 2796 free(hard); 2797 } 2798 2799 if (soft != NULL) { 2800 bcopy(soft, nexthdr, SADB_64TO8(soft->sadb_lifetime_len)); 2801 nexthdr += soft->sadb_lifetime_len; 2802 free(soft); 2803 } 2804 2805 if (idle != NULL) { 2806 bcopy(idle, nexthdr, SADB_64TO8(idle->sadb_lifetime_len)); 2807 nexthdr += idle->sadb_lifetime_len; 2808 free(idle); 2809 } 2810 2811 if (encrypt == NULL && auth == NULL && cmd == CMD_ADD) { 2812 ERROR(ep, ebuf, gettext( 2813 "Must have at least one key for an add.\n")); 2814 } 2815 2816 if (encrypt != NULL) { 2817 bcopy(encrypt, nexthdr, SADB_64TO8(encrypt->sadb_key_len)); 2818 nexthdr += encrypt->sadb_key_len; 2819 bzero(encrypt, SADB_64TO8(encrypt->sadb_key_len)); 2820 free(encrypt); 2821 } 2822 2823 if (auth != NULL) { 2824 bcopy(auth, nexthdr, SADB_64TO8(auth->sadb_key_len)); 2825 nexthdr += auth->sadb_key_len; 2826 bzero(auth, SADB_64TO8(auth->sadb_key_len)); 2827 free(auth); 2828 } 2829 2830 if (srcid != NULL) { 2831 bcopy(srcid, nexthdr, SADB_64TO8(srcid->sadb_ident_len)); 2832 nexthdr += srcid->sadb_ident_len; 2833 free(srcid); 2834 } 2835 2836 if (dstid != NULL) { 2837 bcopy(dstid, nexthdr, SADB_64TO8(dstid->sadb_ident_len)); 2838 nexthdr += dstid->sadb_ident_len; 2839 free(dstid); 2840 } 2841 2842 if (dst != NULL) { 2843 bcopy(dst, nexthdr, SADB_64TO8(dst->sadb_address_len)); 2844 free(dst); 2845 dst = (struct sadb_address *)nexthdr; 2846 dst->sadb_address_proto = proto; 2847 ((struct sockaddr_in6 *)(dst + 1))->sin6_port = htons(dstport); 2848 nexthdr += dst->sadb_address_len; 2849 } else { 2850 FATAL1(ep, ebuf, gettext( 2851 "Need destination address for %s.\n"), thiscmd); 2852 } 2853 2854 if (use_natt) { 2855 if (natt_remote == NULL && natt_local == NULL) { 2856 ERROR(ep, ebuf, gettext( 2857 "Must specify NAT-T remote or local address " 2858 "for UDP encapsulation.\n")); 2859 } 2860 2861 if (natt_remote != NULL) { 2862 bcopy(natt_remote, nexthdr, 2863 SADB_64TO8(natt_remote->sadb_address_len)); 2864 free(natt_remote); 2865 natt_remote = (struct sadb_address *)nexthdr; 2866 nexthdr += natt_remote->sadb_address_len; 2867 ((struct sockaddr_in6 *)(natt_remote + 1))->sin6_port = 2868 htons(natt_rport); 2869 } 2870 2871 if (natt_local != NULL) { 2872 bcopy(natt_local, nexthdr, 2873 SADB_64TO8(natt_local->sadb_address_len)); 2874 free(natt_local); 2875 natt_local = (struct sadb_address *)nexthdr; 2876 nexthdr += natt_local->sadb_address_len; 2877 ((struct sockaddr_in6 *)(natt_local + 1))->sin6_port = 2878 htons(natt_lport); 2879 } 2880 } 2881 2882 handle_errors(ep, ebuf, B_TRUE, B_FALSE); 2883 2884 /* 2885 * PF_KEY requires a source address extension, even if the source 2886 * address itself is unspecified. (See "Set explicit unspecified..." 2887 * code fragment above. Destination reality check was above.) 2888 */ 2889 bcopy(src, nexthdr, SADB_64TO8(src->sadb_address_len)); 2890 free(src); 2891 src = (struct sadb_address *)nexthdr; 2892 src->sadb_address_proto = proto; 2893 ((struct sockaddr_in6 *)(src + 1))->sin6_port = htons(srcport); 2894 nexthdr += src->sadb_address_len; 2895 2896 if (isrc != NULL) { 2897 bcopy(isrc, nexthdr, SADB_64TO8(isrc->sadb_address_len)); 2898 free(isrc); 2899 isrc = (struct sadb_address *)nexthdr; 2900 isrc->sadb_address_proto = iproto; 2901 ((struct sockaddr_in6 *)(isrc + 1))->sin6_port = 2902 htons(isrcport); 2903 nexthdr += isrc->sadb_address_len; 2904 } 2905 2906 if (idst != NULL) { 2907 bcopy(idst, nexthdr, SADB_64TO8(idst->sadb_address_len)); 2908 free(idst); 2909 idst = (struct sadb_address *)nexthdr; 2910 idst->sadb_address_proto = iproto; 2911 ((struct sockaddr_in6 *)(idst + 1))->sin6_port = 2912 htons(idstport); 2913 nexthdr += idst->sadb_address_len; 2914 } 2915 2916 if (replay_ctr != NULL) { 2917 bcopy(replay_ctr, nexthdr, 2918 SADB_64TO8(replay_ctr->sadb_x_rc_len)); 2919 nexthdr += replay_ctr->sadb_x_rc_len; 2920 free(replay_ctr); 2921 } 2922 2923 if (label != NULL) { 2924 bcopy(label, nexthdr, SADB_64TO8(label->sadb_sens_len)); 2925 nexthdr += label->sadb_sens_len; 2926 free(label); 2927 label = NULL; 2928 } 2929 2930 if (olabel != NULL) { 2931 bcopy(olabel, nexthdr, SADB_64TO8(olabel->sadb_sens_len)); 2932 nexthdr += olabel->sadb_sens_len; 2933 free(olabel); 2934 olabel = NULL; 2935 } 2936 2937 if (cflag) { 2938 /* 2939 * Assume the checked cmd would have worked if it was actually 2940 * used. doaddresses() will increment lines_added if it 2941 * succeeds. 2942 */ 2943 lines_added++; 2944 } else { 2945 doaddresses(sadb_msg_type, satype, 2946 cmd, srchp, dsthp, src, dst, unspec_src, buffer, totallen, 2947 spi, ebuf); 2948 } 2949 2950 if (isrchp != NULL && isrchp != &dummy.he) 2951 freehostent(isrchp); 2952 if (idsthp != NULL && idsthp != &dummy.he) 2953 freehostent(idsthp); 2954 if (srchp != NULL && srchp != &dummy.he) 2955 freehostent(srchp); 2956 if (dsthp != NULL && dsthp != &dummy.he) 2957 freehostent(dsthp); 2958 if (natt_lhp != NULL && natt_lhp != &dummy.he) 2959 freehostent(natt_lhp); 2960 if (natt_rhp != NULL && natt_rhp != &dummy.he) 2961 freehostent(natt_rhp); 2962 free(ebuf); 2963 free(buffer); 2964 } 2965 2966 /* 2967 * DELETE and GET are similar, in that they only need the extensions 2968 * required to _find_ an SA, and then either delete it or obtain its 2969 * information. 2970 */ 2971 static void 2972 dodelget(int cmd, int satype, char *argv[], char *ebuf) 2973 { 2974 struct sadb_msg *msg = (struct sadb_msg *)get_buffer; 2975 uint64_t *nextext; 2976 struct sadb_sa *assoc = NULL; 2977 struct sadb_address *src = NULL, *dst = NULL; 2978 int next, token, sa_len; 2979 char *thiscmd; 2980 uint32_t spi; 2981 uint8_t sadb_msg_type; 2982 struct hostent *srchp = NULL, *dsthp = NULL; 2983 struct sockaddr_in6 *sin6; 2984 boolean_t unspec_src = B_TRUE; 2985 uint16_t srcport = 0, dstport = 0; 2986 uint8_t proto = 0; 2987 char *ep = NULL; 2988 uint32_t sa_flags = 0; 2989 2990 /* Set the first extension header to right past the base message. */ 2991 nextext = (uint64_t *)(msg + 1); 2992 bzero(nextext, sizeof (get_buffer) - sizeof (*msg)); 2993 2994 switch (cmd) { 2995 case CMD_GET: 2996 thiscmd = "get"; 2997 sadb_msg_type = SADB_GET; 2998 break; 2999 case CMD_DELETE: 3000 thiscmd = "delete"; 3001 sadb_msg_type = SADB_DELETE; 3002 break; 3003 case CMD_DELETE_PAIR: 3004 thiscmd = "delete-pair"; 3005 sadb_msg_type = SADB_X_DELPAIR; 3006 break; 3007 } 3008 3009 msg_init(msg, sadb_msg_type, (uint8_t)satype); 3010 3011 #define ALLOC_ADDR_EXT(ext, exttype) \ 3012 (ext) = (struct sadb_address *)nextext; \ 3013 nextext = (uint64_t *)((ext) + 1); \ 3014 nextext += SADB_8TO64(roundup(sa_len, 8)); \ 3015 (ext)->sadb_address_exttype = exttype; \ 3016 (ext)->sadb_address_len = nextext - ((uint64_t *)ext); 3017 3018 /* Assume last element in argv is set to NULL. */ 3019 do { 3020 token = parseextval(*argv, &next); 3021 argv++; 3022 switch (token) { 3023 case TOK_EOF: 3024 /* Do nothing, I'm done. */ 3025 break; 3026 case TOK_UNKNOWN: 3027 ERROR1(ep, ebuf, gettext( 3028 "Unknown extension field \"%s\"\n"), *(argv - 1)); 3029 break; 3030 case TOK_SPI: 3031 if (assoc != NULL) { 3032 ERROR(ep, ebuf, gettext( 3033 "Can only specify single SPI value.\n")); 3034 break; 3035 } 3036 assoc = (struct sadb_sa *)nextext; 3037 nextext = (uint64_t *)(assoc + 1); 3038 assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc)); 3039 assoc->sadb_sa_exttype = SADB_EXT_SA; 3040 assoc->sadb_sa_spi = htonl((uint32_t)parsenum(*argv, 3041 B_TRUE, ebuf)); 3042 spi = assoc->sadb_sa_spi; 3043 argv++; 3044 break; 3045 case TOK_SRCPORT: 3046 if (srcport != 0) { 3047 ERROR(ep, ebuf, gettext( 3048 "Can only specify single source port.\n")); 3049 break; 3050 } 3051 srcport = parsenum(*argv, B_TRUE, ebuf); 3052 argv++; 3053 break; 3054 case TOK_DSTPORT: 3055 if (dstport != 0) { 3056 ERROR(ep, ebuf, gettext( 3057 "Can only " 3058 "specify single destination port.\n")); 3059 break; 3060 } 3061 dstport = parsenum(*argv, B_TRUE, ebuf); 3062 argv++; 3063 break; 3064 case TOK_PROTO: 3065 if (proto != 0) { 3066 ERROR(ep, ebuf, gettext( 3067 "Can only specify single protocol.\n")); 3068 break; 3069 } 3070 proto = parsenum(*argv, B_TRUE, ebuf); 3071 argv++; 3072 break; 3073 case TOK_SRCADDR: 3074 case TOK_SRCADDR6: 3075 if (src != NULL) { 3076 ERROR(ep, ebuf, gettext( 3077 "Can only specify single source addr.\n")); 3078 break; 3079 } 3080 sa_len = parseaddr(*argv, &srchp, 3081 (token == TOK_SRCADDR6), ebuf); 3082 if (srchp == NULL) { 3083 ERROR1(ep, ebuf, gettext( 3084 "Unknown source address \"%s\"\n"), *argv); 3085 break; 3086 } 3087 argv++; 3088 3089 unspec_src = B_FALSE; 3090 3091 ALLOC_ADDR_EXT(src, SADB_EXT_ADDRESS_SRC); 3092 3093 if (srchp == &dummy.he) { 3094 /* 3095 * Single address with -n flag. 3096 */ 3097 sin6 = (struct sockaddr_in6 *)(src + 1); 3098 bzero(sin6, sizeof (*sin6)); 3099 sin6->sin6_family = AF_INET6; 3100 bcopy(srchp->h_addr_list[0], &sin6->sin6_addr, 3101 sizeof (struct in6_addr)); 3102 } 3103 /* The rest is pre-bzeroed for us. */ 3104 break; 3105 case TOK_DSTADDR: 3106 case TOK_DSTADDR6: 3107 if (dst != NULL) { 3108 ERROR(ep, ebuf, gettext( 3109 "Can only specify single destination " 3110 "address.\n")); 3111 break; 3112 } 3113 sa_len = parseaddr(*argv, &dsthp, 3114 (token == TOK_SRCADDR6), ebuf); 3115 if (dsthp == NULL) { 3116 ERROR1(ep, ebuf, gettext( 3117 "Unknown destination address \"%s\"\n"), 3118 *argv); 3119 break; 3120 } 3121 argv++; 3122 3123 ALLOC_ADDR_EXT(dst, SADB_EXT_ADDRESS_DST); 3124 3125 if (dsthp == &dummy.he) { 3126 /* 3127 * Single address with -n flag. 3128 */ 3129 sin6 = (struct sockaddr_in6 *)(dst + 1); 3130 bzero(sin6, sizeof (*sin6)); 3131 sin6->sin6_family = AF_INET6; 3132 bcopy(dsthp->h_addr_list[0], &sin6->sin6_addr, 3133 sizeof (struct in6_addr)); 3134 } 3135 /* The rest is pre-bzeroed for us. */ 3136 break; 3137 case TOK_FLAG_INBOUND: 3138 sa_flags |= SADB_X_SAFLAGS_INBOUND; 3139 break; 3140 case TOK_FLAG_OUTBOUND: 3141 sa_flags |= SADB_X_SAFLAGS_OUTBOUND; 3142 break; 3143 default: 3144 ERROR2(ep, ebuf, gettext( 3145 "Don't use extension %s for '%s' command.\n"), 3146 *(argv - 1), thiscmd); 3147 break; 3148 } 3149 } while (token != TOK_EOF); 3150 3151 handle_errors(ep, ebuf, B_TRUE, B_FALSE); 3152 3153 if (assoc == NULL) { 3154 FATAL1(ep, ebuf, gettext( 3155 "Need SA parameters for %s.\n"), thiscmd); 3156 } 3157 3158 /* We can set the flags now with valid assoc in hand. */ 3159 assoc->sadb_sa_flags |= sa_flags; 3160 3161 if ((srcport != 0) && (src == NULL)) { 3162 ALLOC_ADDR_EXT(src, SADB_EXT_ADDRESS_SRC); 3163 sin6 = (struct sockaddr_in6 *)(src + 1); 3164 src->sadb_address_proto = proto; 3165 bzero(sin6, sizeof (*sin6)); 3166 sin6->sin6_family = AF_INET6; 3167 sin6->sin6_port = htons(srcport); 3168 } 3169 3170 if ((dstport != 0) && (dst == NULL)) { 3171 ALLOC_ADDR_EXT(dst, SADB_EXT_ADDRESS_DST); 3172 sin6 = (struct sockaddr_in6 *)(dst + 1); 3173 src->sadb_address_proto = proto; 3174 bzero(sin6, sizeof (*sin6)); 3175 sin6->sin6_family = AF_INET6; 3176 sin6->sin6_port = htons(dstport); 3177 } 3178 3179 /* So I have enough of the message to send it down! */ 3180 msg->sadb_msg_len = nextext - get_buffer; 3181 3182 if (cflag) { 3183 /* 3184 * Assume the checked cmd would have worked if it was actually 3185 * used. doaddresses() will increment lines_added if it 3186 * succeeds. 3187 */ 3188 lines_added++; 3189 } else { 3190 doaddresses(sadb_msg_type, satype, 3191 cmd, srchp, dsthp, src, dst, unspec_src, get_buffer, 3192 sizeof (get_buffer), spi, NULL); 3193 } 3194 3195 if (srchp != NULL && srchp != &dummy.he) 3196 freehostent(srchp); 3197 if (dsthp != NULL && dsthp != &dummy.he) 3198 freehostent(dsthp); 3199 } 3200 3201 /* 3202 * "ipseckey monitor" should exit very gracefully if ^C is tapped provided 3203 * it is not running in interactive mode. 3204 */ 3205 static void 3206 monitor_catch(int signal) 3207 { 3208 if (!interactive) 3209 errx(signal, gettext("Bailing on signal %d."), signal); 3210 } 3211 3212 /* 3213 * Loop forever, listening on PF_KEY messages. 3214 */ 3215 static void 3216 domonitor(boolean_t passive) 3217 { 3218 struct sadb_msg *samsg; 3219 struct sigaction newsig, oldsig; 3220 int rc; 3221 3222 /* Catch ^C. */ 3223 newsig.sa_handler = monitor_catch; 3224 newsig.sa_flags = 0; 3225 (void) sigemptyset(&newsig.sa_mask); 3226 (void) sigaddset(&newsig.sa_mask, SIGINT); 3227 (void) sigaction(SIGINT, &newsig, &oldsig); 3228 3229 samsg = (struct sadb_msg *)get_buffer; 3230 if (!passive) { 3231 (void) printf(gettext("Actively")); 3232 msg_init(samsg, SADB_X_PROMISC, 1); /* Turn ON promisc. */ 3233 rc = key_write(keysock, samsg, sizeof (*samsg)); 3234 if (rc == -1) 3235 Bail("write (SADB_X_PROMISC)"); 3236 } else { 3237 (void) printf(gettext("Passively")); 3238 } 3239 (void) printf(gettext(" monitoring the PF_KEY socket.\n")); 3240 3241 for (; ; ) { 3242 /* 3243 * I assume that read() is non-blocking, and will never 3244 * return 0. 3245 */ 3246 rc = read(keysock, samsg, sizeof (get_buffer)); 3247 if (rc == -1) { 3248 if (errno == EINTR && interactive) 3249 goto out; 3250 else 3251 Bail("read (in domonitor)"); 3252 } 3253 (void) printf(gettext("Read %d bytes.\n"), rc); 3254 /* 3255 * Q: Should I use the same method of printing as GET does? 3256 * A: For now, yes. 3257 */ 3258 print_samsg(stdout, get_buffer, B_TRUE, vflag, nflag); 3259 (void) putchar('\n'); 3260 } 3261 3262 out: 3263 if (interactive) 3264 /* restore SIGINT behavior */ 3265 (void) sigaction(SIGINT, &oldsig, NULL); 3266 } 3267 3268 /* 3269 * Either mask or unmask all relevant signals. 3270 */ 3271 static void 3272 mask_signals(boolean_t unmask) 3273 { 3274 sigset_t set; 3275 static sigset_t oset; 3276 3277 if (unmask) { 3278 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 3279 } else { 3280 (void) sigfillset(&set); 3281 (void) sigprocmask(SIG_SETMASK, &set, &oset); 3282 } 3283 } 3284 3285 /* 3286 * Assorted functions to print help text. 3287 */ 3288 #define puts_tr(s) (void) puts(gettext(s)) 3289 3290 static void 3291 doattrhelp() 3292 { 3293 int i; 3294 3295 puts_tr("\nSA attributes:"); 3296 3297 for (i = 0; tokens[i].string != NULL; i++) { 3298 if (i%3 == 0) 3299 (void) printf("\n"); 3300 (void) printf(" %-15.15s", tokens[i].string); 3301 } 3302 (void) printf("\n"); 3303 } 3304 3305 static void 3306 dohelpcmd(char *cmds) 3307 { 3308 int cmd; 3309 3310 if (strcmp(cmds, "attr") == 0) { 3311 doattrhelp(); 3312 return; 3313 } 3314 3315 cmd = parsecmd(cmds); 3316 switch (cmd) { 3317 case CMD_UPDATE: 3318 puts_tr("update - Update an existing SA"); 3319 break; 3320 case CMD_UPDATE_PAIR: 3321 puts_tr("update-pair - Update an existing pair of SA's"); 3322 break; 3323 case CMD_ADD: 3324 puts_tr("add - Add a new security association (SA)"); 3325 break; 3326 case CMD_DELETE: 3327 puts_tr("delete - Delete an SA"); 3328 break; 3329 case CMD_DELETE_PAIR: 3330 puts_tr("delete-pair - Delete a pair of SA's"); 3331 break; 3332 case CMD_GET: 3333 puts_tr("get - Display an SA"); 3334 break; 3335 case CMD_FLUSH: 3336 puts_tr("flush - Delete all SAs"); 3337 puts_tr(""); 3338 puts_tr("Optional arguments:"); 3339 puts_tr("all delete all SAs"); 3340 puts_tr("esp delete just ESP SAs"); 3341 puts_tr("ah delete just AH SAs"); 3342 puts_tr("<number> delete just SAs with type given by number"); 3343 puts_tr(""); 3344 break; 3345 case CMD_DUMP: 3346 puts_tr("dump - Display all SAs"); 3347 puts_tr(""); 3348 puts_tr("Optional arguments:"); 3349 puts_tr("all display all SAs"); 3350 puts_tr("esp display just ESP SAs"); 3351 puts_tr("ah display just AH SAs"); 3352 puts_tr("<number> display just SAs with type " 3353 "given by number"); 3354 puts_tr(""); 3355 break; 3356 case CMD_MONITOR: 3357 puts_tr("monitor - Monitor all PF_KEY reply messages."); 3358 break; 3359 case CMD_PMONITOR: 3360 puts_tr( 3361 "pmonitor, passive_monitor - Monitor PF_KEY messages that"); 3362 puts_tr( 3363 " reply to all PF_KEY sockets."); 3364 break; 3365 3366 case CMD_QUIT: 3367 puts_tr("quit, exit - Exit the program"); 3368 break; 3369 case CMD_SAVE: 3370 puts_tr("save - Saves all SAs to a file"); 3371 break; 3372 case CMD_HELP: 3373 puts_tr("help - Display list of commands"); 3374 puts_tr("help <cmd> - Display help for command"); 3375 puts_tr("help attr - Display possible SA attributes"); 3376 break; 3377 default: 3378 (void) printf(gettext("%s: Unknown command\n"), cmds); 3379 break; 3380 } 3381 } 3382 3383 3384 static void 3385 dohelp(char *cmds) 3386 { 3387 if (cmds != NULL) { 3388 dohelpcmd(cmds); 3389 return; 3390 } 3391 puts_tr("Commands"); 3392 puts_tr("--------"); 3393 puts_tr("?, help - Display this list"); 3394 puts_tr("help <cmd> - Display help for command"); 3395 puts_tr("help attr - Display possible SA attributes"); 3396 puts_tr("quit, exit - Exit the program"); 3397 puts_tr("monitor - Monitor all PF_KEY reply messages."); 3398 puts_tr("pmonitor, passive_monitor - Monitor PF_KEY messages that"); 3399 puts_tr(" reply to all PF_KEY sockets."); 3400 puts_tr(""); 3401 puts_tr("The following commands are of the form:"); 3402 puts_tr(" <command> {SA type} {attribute value}*"); 3403 puts_tr(""); 3404 puts_tr("add (interactive only) - Add a new security association (SA)"); 3405 puts_tr("update (interactive only) - Update an existing SA"); 3406 puts_tr("update-pair (interactive only) - Update an existing SA pair"); 3407 puts_tr("delete - Delete an SA"); 3408 puts_tr("delete-pair - Delete an SA pair"); 3409 puts_tr("get - Display an SA"); 3410 puts_tr("flush - Delete all SAs"); 3411 puts_tr("dump - Display all SAs"); 3412 puts_tr("save - Saves all SAs to a file"); 3413 } 3414 3415 /* 3416 * "Parse" a command line from argv. 3417 */ 3418 static void 3419 parseit(int argc, char *argv[], char *ebuf, boolean_t read_cmdfile) 3420 { 3421 int cmd, satype; 3422 char *ep = NULL; 3423 3424 if (argc == 0) 3425 return; 3426 cmd = parsecmd(*argv++); 3427 3428 /* 3429 * Some commands loop forever and should only be run from the command 3430 * line, they should never be run from a command file as this may 3431 * be used at boot time. 3432 */ 3433 switch (cmd) { 3434 case CMD_HELP: 3435 if (read_cmdfile) 3436 ERROR(ep, ebuf, gettext("Help not appropriate in " 3437 "config file.")); 3438 else 3439 dohelp(*argv); 3440 return; 3441 case CMD_MONITOR: 3442 if (read_cmdfile) 3443 ERROR(ep, ebuf, gettext("Monitor not appropriate in " 3444 "config file.")); 3445 else { 3446 domonitor(B_FALSE); 3447 /* 3448 * Return from the function in interactive mode to 3449 * avoid error message in the next switch statement. 3450 * Also print newline to prevent prompt clobbering. 3451 * The same is done for CMD_PMONITOR. 3452 */ 3453 if (interactive) { 3454 (void) printf("\n"); 3455 return; 3456 } 3457 } 3458 break; 3459 case CMD_PMONITOR: 3460 if (read_cmdfile) 3461 ERROR(ep, ebuf, gettext("Monitor not appropriate in " 3462 "config file.")); 3463 else { 3464 domonitor(B_TRUE); 3465 if (interactive) { 3466 (void) printf("\n"); 3467 return; 3468 } 3469 } 3470 break; 3471 case CMD_QUIT: 3472 EXIT_OK(NULL); 3473 } 3474 3475 handle_errors(ep, ebuf, B_FALSE, B_FALSE); 3476 3477 satype = parsesatype(*argv, ebuf); 3478 3479 if (satype != SADB_SATYPE_UNSPEC) { 3480 argv++; 3481 } else { 3482 /* 3483 * You must specify either "all" or a specific SA type 3484 * for the "save" command. 3485 */ 3486 if (cmd == CMD_SAVE) 3487 if (*argv == NULL) { 3488 FATAL(ep, ebuf, gettext( 3489 "Must specify a specific " 3490 "SA type for save.\n")); 3491 } else { 3492 argv++; 3493 } 3494 } 3495 3496 switch (cmd) { 3497 case CMD_FLUSH: 3498 if (argc > 2) { 3499 ERROR(ep, ebuf, gettext("Too many arguments for " 3500 "flush command")); 3501 handle_errors(ep, ebuf, 3502 interactive ? B_TRUE : B_FALSE, B_FALSE); 3503 } 3504 if (!cflag) 3505 doflush(satype); 3506 /* 3507 * If this was called because of an entry in a cmd file 3508 * then this action needs to be counted to prevent 3509 * do_interactive() treating this as an error. 3510 */ 3511 lines_added++; 3512 break; 3513 case CMD_ADD: 3514 case CMD_UPDATE: 3515 case CMD_UPDATE_PAIR: 3516 /* 3517 * NOTE: Shouldn't allow ADDs or UPDATEs with keying material 3518 * from the command line. 3519 */ 3520 if (!interactive) { 3521 errx(1, gettext( 3522 "can't do ADD or UPDATE from the command line.\n")); 3523 } 3524 if (satype == SADB_SATYPE_UNSPEC) { 3525 FATAL(ep, ebuf, gettext( 3526 "Must specify a specific SA type.")); 3527 /* NOTREACHED */ 3528 } 3529 /* Parse for extensions, including keying material. */ 3530 doaddup(cmd, satype, argv, ebuf); 3531 break; 3532 case CMD_DELETE: 3533 case CMD_DELETE_PAIR: 3534 case CMD_GET: 3535 if (satype == SADB_SATYPE_UNSPEC) { 3536 FATAL(ep, ebuf, gettext( 3537 "Must specify a single SA type.")); 3538 /* NOTREACHED */ 3539 } 3540 /* Parse for bare minimum to locate an SA. */ 3541 dodelget(cmd, satype, argv, ebuf); 3542 break; 3543 case CMD_DUMP: 3544 if (read_cmdfile) 3545 ERROR(ep, ebuf, gettext("Dump not appropriate in " 3546 "config file.")); 3547 else { 3548 if (argc > 2) { 3549 ERROR(ep, ebuf, gettext("Too many arguments " 3550 "for dump command")); 3551 handle_errors(ep, ebuf, 3552 interactive ? B_TRUE : B_FALSE, B_FALSE); 3553 } 3554 dodump(satype, NULL); 3555 } 3556 break; 3557 case CMD_SAVE: 3558 if (read_cmdfile) { 3559 ERROR(ep, ebuf, gettext("Save not appropriate in " 3560 "config file.")); 3561 } else { 3562 mask_signals(B_FALSE); /* Mask signals */ 3563 dodump(satype, opensavefile(argv[0])); 3564 mask_signals(B_TRUE); /* Unmask signals */ 3565 } 3566 break; 3567 default: 3568 warnx(gettext("Unknown command (%s).\n"), 3569 *(argv - ((satype == SADB_SATYPE_UNSPEC) ? 1 : 2))); 3570 usage(); 3571 } 3572 handle_errors(ep, ebuf, B_FALSE, B_FALSE); 3573 } 3574 3575 int 3576 main(int argc, char *argv[]) 3577 { 3578 int ch; 3579 FILE *infile = stdin, *savefile; 3580 boolean_t dosave = B_FALSE, readfile = B_FALSE; 3581 char *configfile = NULL; 3582 struct stat sbuf; 3583 int bootflags; 3584 3585 (void) setlocale(LC_ALL, ""); 3586 #if !defined(TEXT_DOMAIN) 3587 #define TEXT_DOMAIN "SYS_TEST" 3588 #endif 3589 (void) textdomain(TEXT_DOMAIN); 3590 3591 /* 3592 * Check to see if the command is being run from smf(5). 3593 */ 3594 my_fmri = getenv("SMF_FMRI"); 3595 3596 openlog("ipseckey", LOG_CONS, LOG_AUTH); 3597 if (getuid() != 0) { 3598 errx(1, "Insufficient privileges to run ipseckey."); 3599 } 3600 3601 /* umask me to paranoid, I only want to create files read-only */ 3602 (void) umask((mode_t)00377); 3603 3604 while ((ch = getopt(argc, argv, "pnvf:s:c:")) != EOF) 3605 switch (ch) { 3606 case 'p': 3607 pflag = B_TRUE; 3608 break; 3609 case 'n': 3610 nflag = B_TRUE; 3611 break; 3612 case 'v': 3613 vflag = B_TRUE; 3614 break; 3615 case 'c': 3616 cflag = B_TRUE; 3617 /* FALLTHRU */ 3618 case 'f': 3619 if (dosave) 3620 usage(); 3621 3622 /* 3623 * Use stat() to check and see if the user inadvertently 3624 * passed in a bad pathname, or the name of a directory. 3625 * We should also check to see if the filename is a 3626 * pipe. We use stat() here because fopen() will block 3627 * unless the other end of the pipe is open. This would 3628 * be undesirable, especially if this is called at boot 3629 * time. If we ever need to support reading from a pipe 3630 * or special file, this should be revisited. 3631 */ 3632 if (stat(optarg, &sbuf) == -1) { 3633 EXIT_BADCONFIG2("Invalid pathname: %s\n", 3634 optarg); 3635 } 3636 if (!(sbuf.st_mode & S_IFREG)) { 3637 EXIT_BADCONFIG2("%s - Not a regular file\n", 3638 optarg); 3639 } 3640 infile = fopen(optarg, "r"); 3641 if (infile == NULL) { 3642 EXIT_BADCONFIG2("Unable to open configuration " 3643 "file: %s\n", optarg); 3644 } 3645 /* 3646 * The input file contains keying information, because 3647 * this is sensative, we should only accept data from 3648 * this file if the file is root owned and only readable 3649 * by privileged users. If the command is being run by 3650 * the administrator, issue a warning, if this is run by 3651 * smf(5) (IE: boot time) and the permissions are too 3652 * open, we will fail, the SMF service will end up in 3653 * maintenace mode. The check is made with fstat() to 3654 * eliminate any possible TOT to TOU window. 3655 */ 3656 if (fstat(fileno(infile), &sbuf) == -1) { 3657 (void) fclose(infile); 3658 EXIT_BADCONFIG2("Unable to stat configuration " 3659 "file: %s\n", optarg); 3660 } 3661 if (INSECURE_PERMS(sbuf)) { 3662 if (my_fmri != NULL) { 3663 (void) fclose(infile); 3664 EXIT_BADCONFIG2("Config file " 3665 "%s has insecure permissions.", 3666 optarg); 3667 } else { 3668 (void) fprintf(stderr, gettext( 3669 "Config file %s has insecure " 3670 "permissions, will be rejected in " 3671 "permanent config.\n"), optarg); 3672 } 3673 } 3674 configfile = strdup(optarg); 3675 readfile = B_TRUE; 3676 break; 3677 case 's': 3678 if (readfile) 3679 usage(); 3680 dosave = B_TRUE; 3681 savefile = opensavefile(optarg); 3682 break; 3683 default: 3684 usage(); 3685 } 3686 3687 argc -= optind; 3688 argv += optind; 3689 3690 mypid = getpid(); 3691 3692 keysock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); 3693 3694 if (keysock == -1) { 3695 if (errno == EPERM) { 3696 EXIT_BADPERM("Insufficient privileges to open " 3697 "PF_KEY socket.\n"); 3698 } else { 3699 /* some other reason */ 3700 EXIT_FATAL("Opening PF_KEY socket"); 3701 } 3702 } 3703 3704 if ((_cladm(CL_INITIALIZE, CL_GET_BOOTFLAG, &bootflags) != 0) || 3705 (bootflags & CLUSTER_BOOTED)) { 3706 in_cluster_mode = B_TRUE; 3707 cluster_socket = socket(AF_INET, SOCK_DGRAM, 0); 3708 cli_addr.sin_family = AF_INET; 3709 cli_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 3710 cli_addr.sin_port = htons(CLUSTER_UDP_PORT); 3711 } 3712 3713 if (dosave) { 3714 mask_signals(B_FALSE); /* Mask signals */ 3715 dodump(SADB_SATYPE_UNSPEC, savefile); 3716 mask_signals(B_TRUE); /* Unmask signals */ 3717 EXIT_OK(NULL); 3718 } 3719 3720 /* 3721 * When run from smf(5) flush any existing SA's first 3722 * otherwise you will end up in maintenance mode. 3723 */ 3724 if ((my_fmri != NULL) && readfile) { 3725 (void) fprintf(stdout, gettext( 3726 "Flushing existing SA's before adding new SA's\n")); 3727 (void) fflush(stdout); 3728 doflush(SADB_SATYPE_UNSPEC); 3729 } 3730 if (infile != stdin || argc == 0) { 3731 /* Go into interactive mode here. */ 3732 do_interactive(infile, configfile, "ipseckey> ", my_fmri, 3733 parseit, no_match); 3734 } 3735 parseit(argc, argv, NULL, B_FALSE); 3736 3737 return (0); 3738 } 3739