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