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