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