1 /* $NetBSD: readconf.c,v 1.17 2016/01/14 22:30:04 christos Exp $ */ 2 /* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */ 3 /* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * Functions for reading the configuration files. 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 */ 15 16 #include "includes.h" 17 __RCSID("$NetBSD: readconf.c,v 1.17 2016/01/14 22:30:04 christos Exp $"); 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <sys/socket.h> 21 #include <sys/wait.h> 22 #include <sys/un.h> 23 24 #include <netinet/in.h> 25 #include <netinet/ip.h> 26 27 #include <ctype.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <netdb.h> 31 #include <paths.h> 32 #include <pwd.h> 33 #include <signal.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <unistd.h> 37 #include <limits.h> 38 #include <util.h> 39 #include <vis.h> 40 41 #include "xmalloc.h" 42 #include "ssh.h" 43 #include "compat.h" 44 #include "cipher.h" 45 #include "pathnames.h" 46 #include "log.h" 47 #include "sshkey.h" 48 #include "misc.h" 49 #include "readconf.h" 50 #include "match.h" 51 #include "kex.h" 52 #include "mac.h" 53 #include "fmt_scaled.h" 54 #include "uidswap.h" 55 #include "myproposal.h" 56 #include "digest.h" 57 58 /* Format of the configuration file: 59 60 # Configuration data is parsed as follows: 61 # 1. command line options 62 # 2. user-specific file 63 # 3. system-wide file 64 # Any configuration value is only changed the first time it is set. 65 # Thus, host-specific definitions should be at the beginning of the 66 # configuration file, and defaults at the end. 67 68 # Host-specific declarations. These may override anything above. A single 69 # host may match multiple declarations; these are processed in the order 70 # that they are given in. 71 72 Host *.ngs.fi ngs.fi 73 User foo 74 75 Host fake.com 76 HostName another.host.name.real.org 77 User blaah 78 Port 34289 79 ForwardX11 no 80 ForwardAgent no 81 82 Host books.com 83 RemoteForward 9999 shadows.cs.hut.fi:9999 84 Cipher 3des 85 86 Host fascist.blob.com 87 Port 23123 88 User tylonen 89 PasswordAuthentication no 90 91 Host puukko.hut.fi 92 User t35124p 93 ProxyCommand ssh-proxy %h %p 94 95 Host *.fr 96 PublicKeyAuthentication no 97 98 Host *.su 99 Cipher none 100 PasswordAuthentication no 101 102 Host vpn.fake.com 103 Tunnel yes 104 TunnelDevice 3 105 106 # Defaults for various options 107 Host * 108 ForwardAgent no 109 ForwardX11 no 110 PasswordAuthentication yes 111 RSAAuthentication yes 112 RhostsRSAAuthentication yes 113 StrictHostKeyChecking yes 114 TcpKeepAlive no 115 IdentityFile ~/.ssh/identity 116 Port 22 117 EscapeChar ~ 118 119 */ 120 121 /* Keyword tokens. */ 122 123 typedef enum { 124 oBadOption, 125 oHost, oMatch, 126 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, 127 oGatewayPorts, oExitOnForwardFailure, 128 oPasswordAuthentication, oRSAAuthentication, 129 oChallengeResponseAuthentication, oXAuthLocation, 130 #if defined(KRB4) || defined(KRB5) 131 oKerberosAuthentication, 132 #endif 133 #if defined(AFS) || defined(KRB5) 134 oKerberosTgtPassing, 135 #endif 136 #ifdef AFS 137 oAFSTokenPassing, 138 #endif 139 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 140 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 141 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 142 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 143 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 144 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 145 oPubkeyAuthentication, 146 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 147 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 148 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 149 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 150 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 151 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 152 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 153 oSendEnv, oControlPath, oControlMaster, oControlPersist, 154 oHashKnownHosts, 155 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 156 oVisualHostKey, 157 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 158 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 159 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 160 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, 161 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, 162 oPubkeyAcceptedKeyTypes, 163 oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled, 164 oHPNBufferSize, 165 oSendVersionFirst, 166 oIgnoredUnknownOption, oDeprecated, oUnsupported 167 } OpCodes; 168 169 /* Textual representations of the tokens. */ 170 171 static struct { 172 const char *name; 173 OpCodes opcode; 174 } keywords[] = { 175 { "forwardagent", oForwardAgent }, 176 { "forwardx11", oForwardX11 }, 177 { "forwardx11trusted", oForwardX11Trusted }, 178 { "forwardx11timeout", oForwardX11Timeout }, 179 { "exitonforwardfailure", oExitOnForwardFailure }, 180 { "xauthlocation", oXAuthLocation }, 181 { "gatewayports", oGatewayPorts }, 182 { "useprivilegedport", oUsePrivilegedPort }, 183 { "rhostsauthentication", oDeprecated }, 184 { "passwordauthentication", oPasswordAuthentication }, 185 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 186 { "kbdinteractivedevices", oKbdInteractiveDevices }, 187 { "rsaauthentication", oRSAAuthentication }, 188 { "pubkeyauthentication", oPubkeyAuthentication }, 189 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 190 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 191 { "hostbasedauthentication", oHostbasedAuthentication }, 192 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 193 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 194 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 195 #if defined(KRB4) || defined(KRB5) 196 { "kerberosauthentication", oKerberosAuthentication }, 197 #endif 198 #if defined(AFS) || defined(KRB5) 199 { "kerberostgtpassing", oKerberosTgtPassing }, 200 { "kerberos5tgtpassing", oKerberosTgtPassing }, /* alias */ 201 { "kerberos4tgtpassing", oKerberosTgtPassing }, /* alias */ 202 #endif 203 #ifdef AFS 204 { "afstokenpassing", oAFSTokenPassing }, 205 #endif 206 #if defined(GSSAPI) 207 { "gssapiauthentication", oGssAuthentication }, 208 { "gssapidelegatecredentials", oGssDelegateCreds }, 209 #else 210 { "gssapiauthentication", oUnsupported }, 211 { "gssapidelegatecredentials", oUnsupported }, 212 #endif 213 { "fallbacktorsh", oDeprecated }, 214 { "usersh", oDeprecated }, 215 { "identityfile", oIdentityFile }, 216 { "identityfile2", oIdentityFile }, /* obsolete */ 217 { "identitiesonly", oIdentitiesOnly }, 218 { "hostname", oHostName }, 219 { "hostkeyalias", oHostKeyAlias }, 220 { "proxycommand", oProxyCommand }, 221 { "port", oPort }, 222 { "cipher", oCipher }, 223 { "ciphers", oCiphers }, 224 { "macs", oMacs }, 225 { "protocol", oProtocol }, 226 { "remoteforward", oRemoteForward }, 227 { "localforward", oLocalForward }, 228 { "user", oUser }, 229 { "host", oHost }, 230 { "match", oMatch }, 231 { "escapechar", oEscapeChar }, 232 { "globalknownhostsfile", oGlobalKnownHostsFile }, 233 { "globalknownhostsfile2", oDeprecated }, 234 { "userknownhostsfile", oUserKnownHostsFile }, 235 { "userknownhostsfile2", oDeprecated }, 236 { "connectionattempts", oConnectionAttempts }, 237 { "batchmode", oBatchMode }, 238 { "checkhostip", oCheckHostIP }, 239 { "stricthostkeychecking", oStrictHostKeyChecking }, 240 { "compression", oCompression }, 241 { "compressionlevel", oCompressionLevel }, 242 { "tcpkeepalive", oTCPKeepAlive }, 243 { "keepalive", oTCPKeepAlive }, /* obsolete */ 244 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 245 { "loglevel", oLogLevel }, 246 { "dynamicforward", oDynamicForward }, 247 { "preferredauthentications", oPreferredAuthentications }, 248 { "hostkeyalgorithms", oHostKeyAlgorithms }, 249 { "bindaddress", oBindAddress }, 250 #ifdef ENABLE_PKCS11 251 { "smartcarddevice", oPKCS11Provider }, 252 { "pkcs11provider", oPKCS11Provider }, 253 #else 254 { "smartcarddevice", oUnsupported }, 255 { "pkcs11provider", oUnsupported }, 256 #endif 257 { "clearallforwardings", oClearAllForwardings }, 258 { "enablesshkeysign", oEnableSSHKeysign }, 259 { "verifyhostkeydns", oVerifyHostKeyDNS }, 260 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 261 { "rekeylimit", oRekeyLimit }, 262 { "connecttimeout", oConnectTimeout }, 263 { "addressfamily", oAddressFamily }, 264 { "serveraliveinterval", oServerAliveInterval }, 265 { "serveralivecountmax", oServerAliveCountMax }, 266 { "sendenv", oSendEnv }, 267 { "controlpath", oControlPath }, 268 { "controlmaster", oControlMaster }, 269 { "controlpersist", oControlPersist }, 270 { "hashknownhosts", oHashKnownHosts }, 271 { "tunnel", oTunnel }, 272 { "tunneldevice", oTunnelDevice }, 273 { "localcommand", oLocalCommand }, 274 { "permitlocalcommand", oPermitLocalCommand }, 275 { "visualhostkey", oVisualHostKey }, 276 { "kexalgorithms", oKexAlgorithms }, 277 { "ipqos", oIPQoS }, 278 { "requesttty", oRequestTTY }, 279 { "proxyusefdpass", oProxyUseFdpass }, 280 { "canonicaldomains", oCanonicalDomains }, 281 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, 282 { "canonicalizehostname", oCanonicalizeHostname }, 283 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 284 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 285 { "streamlocalbindmask", oStreamLocalBindMask }, 286 { "streamlocalbindunlink", oStreamLocalBindUnlink }, 287 { "revokedhostkeys", oRevokedHostKeys }, 288 { "fingerprinthash", oFingerprintHash }, 289 { "updatehostkeys", oUpdateHostkeys }, 290 { "hostbasedkeytypes", oHostbasedKeyTypes }, 291 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, 292 { "noneenabled", oNoneEnabled }, 293 { "tcprcvbufpoll", oTcpRcvBufPoll }, 294 { "tcprcvbuf", oTcpRcvBuf }, 295 { "noneswitch", oNoneSwitch }, 296 { "hpndisabled", oHPNDisabled }, 297 { "hpnbuffersize", oHPNBufferSize }, 298 { "sendversionfirst", oSendVersionFirst }, 299 { "ignoreunknown", oIgnoreUnknown }, 300 { NULL, oBadOption } 301 }; 302 303 /* 304 * Adds a local TCP/IP port forward to options. Never returns if there is an 305 * error. 306 */ 307 308 void 309 add_local_forward(Options *options, const struct Forward *newfwd) 310 { 311 struct Forward *fwd; 312 extern uid_t original_real_uid; 313 314 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && 315 newfwd->listen_path == NULL) 316 fatal("Privileged ports can only be forwarded by root."); 317 options->local_forwards = xreallocarray(options->local_forwards, 318 options->num_local_forwards + 1, 319 sizeof(*options->local_forwards)); 320 fwd = &options->local_forwards[options->num_local_forwards++]; 321 322 fwd->listen_host = newfwd->listen_host; 323 fwd->listen_port = newfwd->listen_port; 324 fwd->listen_path = newfwd->listen_path; 325 fwd->connect_host = newfwd->connect_host; 326 fwd->connect_port = newfwd->connect_port; 327 fwd->connect_path = newfwd->connect_path; 328 } 329 330 /* 331 * Adds a remote TCP/IP port forward to options. Never returns if there is 332 * an error. 333 */ 334 335 void 336 add_remote_forward(Options *options, const struct Forward *newfwd) 337 { 338 struct Forward *fwd; 339 340 options->remote_forwards = xreallocarray(options->remote_forwards, 341 options->num_remote_forwards + 1, 342 sizeof(*options->remote_forwards)); 343 fwd = &options->remote_forwards[options->num_remote_forwards++]; 344 345 fwd->listen_host = newfwd->listen_host; 346 fwd->listen_port = newfwd->listen_port; 347 fwd->listen_path = newfwd->listen_path; 348 fwd->connect_host = newfwd->connect_host; 349 fwd->connect_port = newfwd->connect_port; 350 fwd->connect_path = newfwd->connect_path; 351 fwd->handle = newfwd->handle; 352 fwd->allocated_port = 0; 353 } 354 355 static void 356 clear_forwardings(Options *options) 357 { 358 int i; 359 360 for (i = 0; i < options->num_local_forwards; i++) { 361 free(options->local_forwards[i].listen_host); 362 free(options->local_forwards[i].listen_path); 363 free(options->local_forwards[i].connect_host); 364 free(options->local_forwards[i].connect_path); 365 } 366 if (options->num_local_forwards > 0) { 367 free(options->local_forwards); 368 options->local_forwards = NULL; 369 } 370 options->num_local_forwards = 0; 371 for (i = 0; i < options->num_remote_forwards; i++) { 372 free(options->remote_forwards[i].listen_host); 373 free(options->remote_forwards[i].listen_path); 374 free(options->remote_forwards[i].connect_host); 375 free(options->remote_forwards[i].connect_path); 376 } 377 if (options->num_remote_forwards > 0) { 378 free(options->remote_forwards); 379 options->remote_forwards = NULL; 380 } 381 options->num_remote_forwards = 0; 382 options->tun_open = SSH_TUNMODE_NO; 383 } 384 385 void 386 add_identity_file(Options *options, const char *dir, const char *filename, 387 int userprovided) 388 { 389 char *path; 390 int i; 391 392 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 393 fatal("Too many identity files specified (max %d)", 394 SSH_MAX_IDENTITY_FILES); 395 396 if (dir == NULL) /* no dir, filename is absolute */ 397 path = xstrdup(filename); 398 else 399 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 400 401 /* Avoid registering duplicates */ 402 for (i = 0; i < options->num_identity_files; i++) { 403 if (options->identity_file_userprovided[i] == userprovided && 404 strcmp(options->identity_files[i], path) == 0) { 405 debug2("%s: ignoring duplicate key %s", __func__, path); 406 free(path); 407 return; 408 } 409 } 410 411 options->identity_file_userprovided[options->num_identity_files] = 412 userprovided; 413 options->identity_files[options->num_identity_files++] = path; 414 } 415 416 int 417 default_ssh_port(void) 418 { 419 static int port; 420 struct servent *sp; 421 422 if (port == 0) { 423 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 424 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 425 } 426 return port; 427 } 428 429 /* 430 * Execute a command in a shell. 431 * Return its exit status or -1 on abnormal exit. 432 */ 433 static int 434 execute_in_shell(const char *cmd) 435 { 436 const char *shell; 437 char *command_string; 438 pid_t pid; 439 int devnull, status; 440 extern uid_t original_real_uid; 441 442 if ((shell = getenv("SHELL")) == NULL) 443 shell = _PATH_BSHELL; 444 445 /* 446 * Use "exec" to avoid "sh -c" processes on some platforms 447 * (e.g. Solaris) 448 */ 449 xasprintf(&command_string, "exec %s", cmd); 450 451 /* Need this to redirect subprocess stdin/out */ 452 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 453 fatal("open(/dev/null): %s", strerror(errno)); 454 455 debug("Executing command: '%.500s'", cmd); 456 457 /* Fork and execute the command. */ 458 if ((pid = fork()) == 0) { 459 char *argv[4]; 460 461 /* Child. Permanently give up superuser privileges. */ 462 permanently_drop_suid(original_real_uid); 463 464 /* Redirect child stdin and stdout. Leave stderr */ 465 if (dup2(devnull, STDIN_FILENO) == -1) 466 fatal("dup2: %s", strerror(errno)); 467 if (dup2(devnull, STDOUT_FILENO) == -1) 468 fatal("dup2: %s", strerror(errno)); 469 if (devnull > STDERR_FILENO) 470 close(devnull); 471 if (closefrom(STDERR_FILENO + 1) == -1) 472 fatal("closefrom: %s", strerror(errno)); 473 474 argv[0] = __UNCONST(shell); 475 argv[1] = __UNCONST("-c"); 476 argv[2] = command_string; 477 argv[3] = NULL; 478 479 execv(argv[0], argv); 480 error("Unable to execute '%.100s': %s", cmd, strerror(errno)); 481 /* Die with signal to make this error apparent to parent. */ 482 signal(SIGTERM, SIG_DFL); 483 kill(getpid(), SIGTERM); 484 _exit(1); 485 } 486 /* Parent. */ 487 if (pid < 0) 488 fatal("%s: fork: %.100s", __func__, strerror(errno)); 489 490 close(devnull); 491 free(command_string); 492 493 while (waitpid(pid, &status, 0) == -1) { 494 if (errno != EINTR && errno != EAGAIN) 495 fatal("%s: waitpid: %s", __func__, strerror(errno)); 496 } 497 if (!WIFEXITED(status)) { 498 error("command '%.100s' exited abnormally", cmd); 499 return -1; 500 } 501 debug3("command returned status %d", WEXITSTATUS(status)); 502 return WEXITSTATUS(status); 503 } 504 505 /* 506 * Parse and execute a Match directive. 507 */ 508 static int 509 match_cfg_line(Options *options, char **condition, struct passwd *pw, 510 const char *host_arg, const char *original_host, int post_canon, 511 const char *filename, int linenum) 512 { 513 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; 514 const char *ruser; 515 int r, port, this_result, result = 1, attributes = 0, negate; 516 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 517 518 /* 519 * Configuration is likely to be incomplete at this point so we 520 * must be prepared to use default values. 521 */ 522 port = options->port <= 0 ? default_ssh_port() : options->port; 523 ruser = options->user == NULL ? pw->pw_name : options->user; 524 if (options->hostname != NULL) { 525 /* NB. Please keep in sync with ssh.c:main() */ 526 host = percent_expand(options->hostname, 527 "h", host_arg, (char *)NULL); 528 } else 529 host = xstrdup(host_arg); 530 531 debug2("checking match for '%s' host %s originally %s", 532 cp, host, original_host); 533 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { 534 criteria = NULL; 535 this_result = 1; 536 if ((negate = attrib[0] == '!')) 537 attrib++; 538 /* criteria "all" and "canonical" have no argument */ 539 if (strcasecmp(attrib, "all") == 0) { 540 if (attributes > 1 || 541 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 542 error("%.200s line %d: '%s' cannot be combined " 543 "with other Match attributes", 544 filename, linenum, oattrib); 545 result = -1; 546 goto out; 547 } 548 if (result) 549 result = negate ? 0 : 1; 550 goto out; 551 } 552 attributes++; 553 if (strcasecmp(attrib, "canonical") == 0) { 554 r = !!post_canon; /* force bitmask member to boolean */ 555 if (r == (negate ? 1 : 0)) 556 this_result = result = 0; 557 debug3("%.200s line %d: %smatched '%s'", 558 filename, linenum, 559 this_result ? "" : "not ", oattrib); 560 continue; 561 } 562 /* All other criteria require an argument */ 563 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 564 error("Missing Match criteria for %s", attrib); 565 result = -1; 566 goto out; 567 } 568 if (strcasecmp(attrib, "host") == 0) { 569 criteria = xstrdup(host); 570 r = match_hostname(host, arg) == 1; 571 if (r == (negate ? 1 : 0)) 572 this_result = result = 0; 573 } else if (strcasecmp(attrib, "originalhost") == 0) { 574 criteria = xstrdup(original_host); 575 r = match_hostname(original_host, arg) == 1; 576 if (r == (negate ? 1 : 0)) 577 this_result = result = 0; 578 } else if (strcasecmp(attrib, "user") == 0) { 579 criteria = xstrdup(ruser); 580 r = match_pattern_list(ruser, arg, 0) == 1; 581 if (r == (negate ? 1 : 0)) 582 this_result = result = 0; 583 } else if (strcasecmp(attrib, "localuser") == 0) { 584 criteria = xstrdup(pw->pw_name); 585 r = match_pattern_list(pw->pw_name, arg, 0) == 1; 586 if (r == (negate ? 1 : 0)) 587 this_result = result = 0; 588 } else if (strcasecmp(attrib, "exec") == 0) { 589 if (gethostname(thishost, sizeof(thishost)) == -1) 590 fatal("gethostname: %s", strerror(errno)); 591 strlcpy(shorthost, thishost, sizeof(shorthost)); 592 shorthost[strcspn(thishost, ".")] = '\0'; 593 snprintf(portstr, sizeof(portstr), "%d", port); 594 595 cmd = percent_expand(arg, 596 "L", shorthost, 597 "d", pw->pw_dir, 598 "h", host, 599 "l", thishost, 600 "n", original_host, 601 "p", portstr, 602 "r", ruser, 603 "u", pw->pw_name, 604 (char *)NULL); 605 if (result != 1) { 606 /* skip execution if prior predicate failed */ 607 debug3("%.200s line %d: skipped exec " 608 "\"%.100s\"", filename, linenum, cmd); 609 free(cmd); 610 continue; 611 } 612 r = execute_in_shell(cmd); 613 if (r == -1) { 614 fatal("%.200s line %d: match exec " 615 "'%.100s' error", filename, 616 linenum, cmd); 617 } 618 criteria = xstrdup(cmd); 619 free(cmd); 620 /* Force exit status to boolean */ 621 r = r == 0; 622 if (r == (negate ? 1 : 0)) 623 this_result = result = 0; 624 } else { 625 error("Unsupported Match attribute %s", attrib); 626 result = -1; 627 goto out; 628 } 629 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", 630 filename, linenum, this_result ? "": "not ", 631 oattrib, criteria); 632 free(criteria); 633 } 634 if (attributes == 0) { 635 error("One or more attributes required for Match"); 636 result = -1; 637 goto out; 638 } 639 out: 640 if (result != -1) 641 debug2("match %sfound", result ? "" : "not "); 642 *condition = cp; 643 free(host); 644 return result; 645 } 646 647 /* Check and prepare a domain name: removes trailing '.' and lowercases */ 648 static void 649 valid_domain(char *name, const char *filename, int linenum) 650 { 651 size_t i, l = strlen(name); 652 u_char c, last = '\0'; 653 654 if (l == 0) 655 fatal("%s line %d: empty hostname suffix", filename, linenum); 656 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) 657 fatal("%s line %d: hostname suffix \"%.100s\" " 658 "starts with invalid character", filename, linenum, name); 659 for (i = 0; i < l; i++) { 660 c = tolower((u_char)name[i]); 661 name[i] = (char)c; 662 if (last == '.' && c == '.') 663 fatal("%s line %d: hostname suffix \"%.100s\" contains " 664 "consecutive separators", filename, linenum, name); 665 if (c != '.' && c != '-' && !isalnum(c) && 666 c != '_') /* technically invalid, but common */ 667 fatal("%s line %d: hostname suffix \"%.100s\" contains " 668 "invalid characters", filename, linenum, name); 669 last = c; 670 } 671 if (name[l - 1] == '.') 672 name[l - 1] = '\0'; 673 } 674 675 /* 676 * Returns the number of the token pointed to by cp or oBadOption. 677 */ 678 static OpCodes 679 parse_token(const char *cp, const char *filename, int linenum, 680 const char *ignored_unknown) 681 { 682 int i; 683 684 for (i = 0; keywords[i].name; i++) 685 if (strcmp(cp, keywords[i].name) == 0) 686 return keywords[i].opcode; 687 if (ignored_unknown != NULL && 688 match_pattern_list(cp, ignored_unknown, 1) == 1) 689 return oIgnoredUnknownOption; 690 error("%s: line %d: Bad configuration option: %s", 691 filename, linenum, cp); 692 return oBadOption; 693 } 694 695 /* Multistate option parsing */ 696 struct multistate { 697 const char *key; 698 int value; 699 }; 700 static const struct multistate multistate_flag[] = { 701 { "true", 1 }, 702 { "false", 0 }, 703 { "yes", 1 }, 704 { "no", 0 }, 705 { NULL, -1 } 706 }; 707 static const struct multistate multistate_yesnoask[] = { 708 { "true", 1 }, 709 { "false", 0 }, 710 { "yes", 1 }, 711 { "no", 0 }, 712 { "ask", 2 }, 713 { NULL, -1 } 714 }; 715 static const struct multistate multistate_addressfamily[] = { 716 { "inet", AF_INET }, 717 { "inet6", AF_INET6 }, 718 { "any", AF_UNSPEC }, 719 { NULL, -1 } 720 }; 721 static const struct multistate multistate_controlmaster[] = { 722 { "true", SSHCTL_MASTER_YES }, 723 { "yes", SSHCTL_MASTER_YES }, 724 { "false", SSHCTL_MASTER_NO }, 725 { "no", SSHCTL_MASTER_NO }, 726 { "auto", SSHCTL_MASTER_AUTO }, 727 { "ask", SSHCTL_MASTER_ASK }, 728 { "autoask", SSHCTL_MASTER_AUTO_ASK }, 729 { NULL, -1 } 730 }; 731 static const struct multistate multistate_tunnel[] = { 732 { "ethernet", SSH_TUNMODE_ETHERNET }, 733 { "point-to-point", SSH_TUNMODE_POINTOPOINT }, 734 { "true", SSH_TUNMODE_DEFAULT }, 735 { "yes", SSH_TUNMODE_DEFAULT }, 736 { "false", SSH_TUNMODE_NO }, 737 { "no", SSH_TUNMODE_NO }, 738 { NULL, -1 } 739 }; 740 static const struct multistate multistate_requesttty[] = { 741 { "true", REQUEST_TTY_YES }, 742 { "yes", REQUEST_TTY_YES }, 743 { "false", REQUEST_TTY_NO }, 744 { "no", REQUEST_TTY_NO }, 745 { "force", REQUEST_TTY_FORCE }, 746 { "auto", REQUEST_TTY_AUTO }, 747 { NULL, -1 } 748 }; 749 static const struct multistate multistate_canonicalizehostname[] = { 750 { "true", SSH_CANONICALISE_YES }, 751 { "false", SSH_CANONICALISE_NO }, 752 { "yes", SSH_CANONICALISE_YES }, 753 { "no", SSH_CANONICALISE_NO }, 754 { "always", SSH_CANONICALISE_ALWAYS }, 755 { NULL, -1 } 756 }; 757 758 /* 759 * Processes a single option line as used in the configuration files. This 760 * only sets those values that have not already been set. 761 */ 762 #define WHITESPACE " \t\r\n" 763 int 764 process_config_line(Options *options, struct passwd *pw, const char *host, 765 const char *original_host, char *line, const char *filename, 766 int linenum, int *activep, int flags) 767 { 768 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 769 char **cpptr, fwdarg[256]; 770 u_int i, *uintptr, max_entries = 0; 771 int negated, opcode, *intptr, value, value2, cmdline = 0; 772 LogLevel *log_level_ptr; 773 long long val64; 774 size_t len; 775 struct Forward fwd; 776 const struct multistate *multistate_ptr; 777 struct allowed_cname *cname; 778 779 if (activep == NULL) { /* We are processing a command line directive */ 780 cmdline = 1; 781 activep = &cmdline; 782 } 783 784 /* Strip trailing whitespace */ 785 if ((len = strlen(line)) == 0) 786 return 0; 787 for (len--; len > 0; len--) { 788 if (strchr(WHITESPACE, line[len]) == NULL) 789 break; 790 line[len] = '\0'; 791 } 792 793 s = line; 794 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 795 if ((keyword = strdelim(&s)) == NULL) 796 return 0; 797 /* Ignore leading whitespace. */ 798 if (*keyword == '\0') 799 keyword = strdelim(&s); 800 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 801 return 0; 802 /* Match lowercase keyword */ 803 lowercase(keyword); 804 805 opcode = parse_token(keyword, filename, linenum, 806 options->ignored_unknown); 807 808 switch (opcode) { 809 case oBadOption: 810 /* don't panic, but count bad options */ 811 return -1; 812 /* NOTREACHED */ 813 case oIgnoredUnknownOption: 814 debug("%s line %d: Ignored unknown option \"%s\"", 815 filename, linenum, keyword); 816 return 0; 817 case oConnectTimeout: 818 intptr = &options->connection_timeout; 819 parse_time: 820 arg = strdelim(&s); 821 if (!arg || *arg == '\0') 822 fatal("%s line %d: missing time value.", 823 filename, linenum); 824 if (strcmp(arg, "none") == 0) 825 value = -1; 826 else if ((value = convtime(arg)) == -1) 827 fatal("%s line %d: invalid time value.", 828 filename, linenum); 829 if (*activep && *intptr == -1) 830 *intptr = value; 831 break; 832 833 case oForwardAgent: 834 intptr = &options->forward_agent; 835 parse_flag: 836 multistate_ptr = multistate_flag; 837 parse_multistate: 838 arg = strdelim(&s); 839 if (!arg || *arg == '\0') 840 fatal("%s line %d: missing argument.", 841 filename, linenum); 842 value = -1; 843 for (i = 0; multistate_ptr[i].key != NULL; i++) { 844 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 845 value = multistate_ptr[i].value; 846 break; 847 } 848 } 849 if (value == -1) 850 fatal("%s line %d: unsupported option \"%s\".", 851 filename, linenum, arg); 852 if (*activep && *intptr == -1) 853 *intptr = value; 854 break; 855 856 case oForwardX11: 857 intptr = &options->forward_x11; 858 goto parse_flag; 859 860 case oForwardX11Trusted: 861 intptr = &options->forward_x11_trusted; 862 goto parse_flag; 863 864 case oForwardX11Timeout: 865 intptr = &options->forward_x11_timeout; 866 goto parse_time; 867 868 case oGatewayPorts: 869 intptr = &options->fwd_opts.gateway_ports; 870 goto parse_flag; 871 872 case oExitOnForwardFailure: 873 intptr = &options->exit_on_forward_failure; 874 goto parse_flag; 875 876 case oUsePrivilegedPort: 877 intptr = &options->use_privileged_port; 878 goto parse_flag; 879 880 case oPasswordAuthentication: 881 intptr = &options->password_authentication; 882 goto parse_flag; 883 884 case oKbdInteractiveAuthentication: 885 intptr = &options->kbd_interactive_authentication; 886 goto parse_flag; 887 888 case oKbdInteractiveDevices: 889 charptr = &options->kbd_interactive_devices; 890 goto parse_string; 891 892 case oPubkeyAuthentication: 893 intptr = &options->pubkey_authentication; 894 goto parse_flag; 895 896 case oRSAAuthentication: 897 intptr = &options->rsa_authentication; 898 goto parse_flag; 899 900 case oRhostsRSAAuthentication: 901 intptr = &options->rhosts_rsa_authentication; 902 goto parse_flag; 903 904 case oHostbasedAuthentication: 905 intptr = &options->hostbased_authentication; 906 goto parse_flag; 907 908 case oChallengeResponseAuthentication: 909 intptr = &options->challenge_response_authentication; 910 goto parse_flag; 911 912 #if defined(KRB4) || defined(KRB5) 913 case oKerberosAuthentication: 914 intptr = &options->kerberos_authentication; 915 goto parse_flag; 916 #endif 917 #if defined(AFS) || defined(KRB5) 918 case oKerberosTgtPassing: 919 intptr = &options->kerberos_tgt_passing; 920 goto parse_flag; 921 #endif 922 923 case oGssAuthentication: 924 intptr = &options->gss_authentication; 925 goto parse_flag; 926 927 #ifdef AFS 928 case oAFSTokenPassing: 929 intptr = &options->afs_token_passing; 930 goto parse_flag; 931 #endif 932 933 case oGssDelegateCreds: 934 intptr = &options->gss_deleg_creds; 935 goto parse_flag; 936 937 case oBatchMode: 938 intptr = &options->batch_mode; 939 goto parse_flag; 940 941 case oCheckHostIP: 942 intptr = &options->check_host_ip; 943 goto parse_flag; 944 945 case oNoneEnabled: 946 intptr = &options->none_enabled; 947 goto parse_flag; 948 949 /* we check to see if the command comes from the */ 950 /* command line or not. If it does then enable it */ 951 /* otherwise fail. NONE should never be a default configuration */ 952 case oNoneSwitch: 953 if(strcmp(filename,"command-line")==0) 954 { 955 intptr = &options->none_switch; 956 goto parse_flag; 957 } else { 958 error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); 959 error("Continuing..."); 960 debug("NoneSwitch directive found in %.200s.", filename); 961 return 0; 962 } 963 964 case oHPNDisabled: 965 intptr = &options->hpn_disabled; 966 goto parse_flag; 967 968 case oHPNBufferSize: 969 intptr = &options->hpn_buffer_size; 970 goto parse_int; 971 972 case oTcpRcvBufPoll: 973 intptr = &options->tcp_rcv_buf_poll; 974 goto parse_flag; 975 976 case oVerifyHostKeyDNS: 977 intptr = &options->verify_host_key_dns; 978 multistate_ptr = multistate_yesnoask; 979 goto parse_multistate; 980 981 case oStrictHostKeyChecking: 982 intptr = &options->strict_host_key_checking; 983 multistate_ptr = multistate_yesnoask; 984 goto parse_multistate; 985 986 case oCompression: 987 intptr = &options->compression; 988 goto parse_flag; 989 990 case oTCPKeepAlive: 991 intptr = &options->tcp_keep_alive; 992 goto parse_flag; 993 994 case oNoHostAuthenticationForLocalhost: 995 intptr = &options->no_host_authentication_for_localhost; 996 goto parse_flag; 997 998 case oNumberOfPasswordPrompts: 999 intptr = &options->number_of_password_prompts; 1000 goto parse_int; 1001 1002 case oCompressionLevel: 1003 intptr = &options->compression_level; 1004 goto parse_int; 1005 1006 case oRekeyLimit: 1007 arg = strdelim(&s); 1008 if (!arg || *arg == '\0') 1009 fatal("%.200s line %d: Missing argument.", filename, 1010 linenum); 1011 if (strcmp(arg, "default") == 0) { 1012 val64 = 0; 1013 } else { 1014 if (scan_scaled(arg, &val64) == -1) 1015 fatal("%.200s line %d: Bad number '%s': %s", 1016 filename, linenum, arg, strerror(errno)); 1017 /* check for too-large or too-small limits */ 1018 if (val64 > UINT_MAX) 1019 fatal("%.200s line %d: RekeyLimit too large", 1020 filename, linenum); 1021 if (val64 != 0 && val64 < 16) 1022 fatal("%.200s line %d: RekeyLimit too small", 1023 filename, linenum); 1024 } 1025 if (*activep && options->rekey_limit == -1) 1026 options->rekey_limit = (u_int32_t)val64; 1027 if (s != NULL) { /* optional rekey interval present */ 1028 if (strcmp(s, "none") == 0) { 1029 (void)strdelim(&s); /* discard */ 1030 break; 1031 } 1032 intptr = &options->rekey_interval; 1033 goto parse_time; 1034 } 1035 break; 1036 1037 case oIdentityFile: 1038 arg = strdelim(&s); 1039 if (!arg || *arg == '\0') 1040 fatal("%.200s line %d: Missing argument.", filename, linenum); 1041 if (*activep) { 1042 intptr = &options->num_identity_files; 1043 if (*intptr >= SSH_MAX_IDENTITY_FILES) 1044 fatal("%.200s line %d: Too many identity files specified (max %d).", 1045 filename, linenum, SSH_MAX_IDENTITY_FILES); 1046 add_identity_file(options, NULL, 1047 arg, flags & SSHCONF_USERCONF); 1048 } 1049 break; 1050 1051 case oXAuthLocation: 1052 charptr=&options->xauth_location; 1053 goto parse_string; 1054 1055 case oUser: 1056 charptr = &options->user; 1057 parse_string: 1058 arg = strdelim(&s); 1059 if (!arg || *arg == '\0') 1060 fatal("%.200s line %d: Missing argument.", 1061 filename, linenum); 1062 if (*activep && *charptr == NULL) 1063 *charptr = xstrdup(arg); 1064 break; 1065 1066 case oGlobalKnownHostsFile: 1067 cpptr = (char **)&options->system_hostfiles; 1068 uintptr = &options->num_system_hostfiles; 1069 max_entries = SSH_MAX_HOSTS_FILES; 1070 parse_char_array: 1071 if (*activep && *uintptr == 0) { 1072 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1073 if ((*uintptr) >= max_entries) 1074 fatal("%s line %d: " 1075 "too many authorized keys files.", 1076 filename, linenum); 1077 cpptr[(*uintptr)++] = xstrdup(arg); 1078 } 1079 } 1080 return 0; 1081 1082 case oUserKnownHostsFile: 1083 cpptr = (char **)&options->user_hostfiles; 1084 uintptr = &options->num_user_hostfiles; 1085 max_entries = SSH_MAX_HOSTS_FILES; 1086 goto parse_char_array; 1087 1088 case oHostName: 1089 charptr = &options->hostname; 1090 goto parse_string; 1091 1092 case oHostKeyAlias: 1093 charptr = &options->host_key_alias; 1094 goto parse_string; 1095 1096 case oPreferredAuthentications: 1097 charptr = &options->preferred_authentications; 1098 goto parse_string; 1099 1100 case oBindAddress: 1101 charptr = &options->bind_address; 1102 goto parse_string; 1103 1104 case oPKCS11Provider: 1105 charptr = &options->pkcs11_provider; 1106 goto parse_string; 1107 1108 case oProxyCommand: 1109 charptr = &options->proxy_command; 1110 parse_command: 1111 if (s == NULL) 1112 fatal("%.200s line %d: Missing argument.", filename, linenum); 1113 len = strspn(s, WHITESPACE "="); 1114 if (*activep && *charptr == NULL) 1115 *charptr = xstrdup(s + len); 1116 return 0; 1117 1118 case oPort: 1119 intptr = &options->port; 1120 parse_int: 1121 arg = strdelim(&s); 1122 if (!arg || *arg == '\0') 1123 fatal("%.200s line %d: Missing argument.", filename, linenum); 1124 if (arg[0] < '0' || arg[0] > '9') 1125 fatal("%.200s line %d: Bad number.", filename, linenum); 1126 1127 /* Octal, decimal, or hex format? */ 1128 value = strtol(arg, &endofnumber, 0); 1129 if (arg == endofnumber) 1130 fatal("%.200s line %d: Bad number.", filename, linenum); 1131 if (*activep && *intptr == -1) 1132 *intptr = value; 1133 break; 1134 1135 case oConnectionAttempts: 1136 intptr = &options->connection_attempts; 1137 goto parse_int; 1138 1139 case oTcpRcvBuf: 1140 intptr = &options->tcp_rcv_buf; 1141 goto parse_int; 1142 1143 case oCipher: 1144 intptr = &options->cipher; 1145 arg = strdelim(&s); 1146 if (!arg || *arg == '\0') 1147 fatal("%.200s line %d: Missing argument.", filename, linenum); 1148 value = cipher_number(arg); 1149 if (value == -1) 1150 fatal("%.200s line %d: Bad cipher '%s'.", 1151 filename, linenum, arg ? arg : "<NONE>"); 1152 if (*activep && *intptr == -1) 1153 *intptr = value; 1154 break; 1155 1156 case oCiphers: 1157 arg = strdelim(&s); 1158 if (!arg || *arg == '\0') 1159 fatal("%.200s line %d: Missing argument.", filename, linenum); 1160 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) 1161 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 1162 filename, linenum, arg ? arg : "<NONE>"); 1163 if (*activep && options->ciphers == NULL) 1164 options->ciphers = xstrdup(arg); 1165 break; 1166 1167 case oMacs: 1168 arg = strdelim(&s); 1169 if (!arg || *arg == '\0') 1170 fatal("%.200s line %d: Missing argument.", filename, linenum); 1171 if (!mac_valid(*arg == '+' ? arg + 1 : arg)) 1172 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 1173 filename, linenum, arg ? arg : "<NONE>"); 1174 if (*activep && options->macs == NULL) 1175 options->macs = xstrdup(arg); 1176 break; 1177 1178 case oKexAlgorithms: 1179 arg = strdelim(&s); 1180 if (!arg || *arg == '\0') 1181 fatal("%.200s line %d: Missing argument.", 1182 filename, linenum); 1183 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) 1184 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 1185 filename, linenum, arg ? arg : "<NONE>"); 1186 if (*activep && options->kex_algorithms == NULL) 1187 options->kex_algorithms = xstrdup(arg); 1188 break; 1189 1190 case oHostKeyAlgorithms: 1191 charptr = &options->hostkeyalgorithms; 1192 parse_keytypes: 1193 arg = strdelim(&s); 1194 if (!arg || *arg == '\0') 1195 fatal("%.200s line %d: Missing argument.", 1196 filename, linenum); 1197 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) 1198 fatal("%s line %d: Bad key types '%s'.", 1199 filename, linenum, arg ? arg : "<NONE>"); 1200 if (*activep && *charptr == NULL) 1201 *charptr = xstrdup(arg); 1202 break; 1203 1204 case oProtocol: 1205 intptr = &options->protocol; 1206 arg = strdelim(&s); 1207 if (!arg || *arg == '\0') 1208 fatal("%.200s line %d: Missing argument.", filename, linenum); 1209 value = proto_spec(arg); 1210 if (value == SSH_PROTO_UNKNOWN) 1211 fatal("%.200s line %d: Bad protocol spec '%s'.", 1212 filename, linenum, arg ? arg : "<NONE>"); 1213 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 1214 *intptr = value; 1215 break; 1216 1217 case oLogLevel: 1218 log_level_ptr = &options->log_level; 1219 arg = strdelim(&s); 1220 value = log_level_number(arg); 1221 if (value == SYSLOG_LEVEL_NOT_SET) 1222 fatal("%.200s line %d: unsupported log level '%s'", 1223 filename, linenum, arg ? arg : "<NONE>"); 1224 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 1225 *log_level_ptr = (LogLevel) value; 1226 break; 1227 1228 case oLocalForward: 1229 case oRemoteForward: 1230 case oDynamicForward: 1231 arg = strdelim(&s); 1232 if (arg == NULL || *arg == '\0') 1233 fatal("%.200s line %d: Missing port argument.", 1234 filename, linenum); 1235 1236 if (opcode == oLocalForward || 1237 opcode == oRemoteForward) { 1238 arg2 = strdelim(&s); 1239 if (arg2 == NULL || *arg2 == '\0') 1240 fatal("%.200s line %d: Missing target argument.", 1241 filename, linenum); 1242 1243 /* construct a string for parse_forward */ 1244 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 1245 } else if (opcode == oDynamicForward) { 1246 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1247 } 1248 1249 if (parse_forward(&fwd, fwdarg, 1250 opcode == oDynamicForward ? 1 : 0, 1251 opcode == oRemoteForward ? 1 : 0) == 0) 1252 fatal("%.200s line %d: Bad forwarding specification.", 1253 filename, linenum); 1254 1255 if (*activep) { 1256 if (opcode == oLocalForward || 1257 opcode == oDynamicForward) 1258 add_local_forward(options, &fwd); 1259 else if (opcode == oRemoteForward) 1260 add_remote_forward(options, &fwd); 1261 } 1262 break; 1263 1264 case oClearAllForwardings: 1265 intptr = &options->clear_forwardings; 1266 goto parse_flag; 1267 1268 case oHost: 1269 if (cmdline) 1270 fatal("Host directive not supported as a command-line " 1271 "option"); 1272 *activep = 0; 1273 arg2 = NULL; 1274 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1275 negated = *arg == '!'; 1276 if (negated) 1277 arg++; 1278 if (match_pattern(host, arg)) { 1279 if (negated) { 1280 debug("%.200s line %d: Skipping Host " 1281 "block because of negated match " 1282 "for %.100s", filename, linenum, 1283 arg); 1284 *activep = 0; 1285 break; 1286 } 1287 if (!*activep) 1288 arg2 = arg; /* logged below */ 1289 *activep = 1; 1290 } 1291 } 1292 if (*activep) 1293 debug("%.200s line %d: Applying options for %.100s", 1294 filename, linenum, arg2); 1295 /* Avoid garbage check below, as strdelim is done. */ 1296 return 0; 1297 1298 case oMatch: 1299 if (cmdline) 1300 fatal("Host directive not supported as a command-line " 1301 "option"); 1302 value = match_cfg_line(options, &s, pw, host, original_host, 1303 flags & SSHCONF_POSTCANON, filename, linenum); 1304 if (value < 0) 1305 fatal("%.200s line %d: Bad Match condition", filename, 1306 linenum); 1307 *activep = value; 1308 break; 1309 1310 case oEscapeChar: 1311 intptr = &options->escape_char; 1312 arg = strdelim(&s); 1313 if (!arg || *arg == '\0') 1314 fatal("%.200s line %d: Missing argument.", filename, linenum); 1315 value = 0; /* To avoid compiler warning... */ 1316 if (strcmp(arg, "none") == 0) 1317 value = SSH_ESCAPECHAR_NONE; 1318 else if (arg[1] == '\0') 1319 value = (u_char) arg[0]; 1320 else if (arg[0] == '^' && arg[2] == 0 && 1321 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 1322 value = (u_char) arg[1] & 31; 1323 else { 1324 fatal("%.200s line %d: Bad escape character.", 1325 filename, linenum); 1326 /* NOTREACHED */ 1327 value = 0; /* Avoid compiler warning. */ 1328 } 1329 if (*activep && *intptr == -1) 1330 *intptr = value; 1331 break; 1332 1333 case oAddressFamily: 1334 intptr = &options->address_family; 1335 multistate_ptr = multistate_addressfamily; 1336 goto parse_multistate; 1337 1338 case oEnableSSHKeysign: 1339 intptr = &options->enable_ssh_keysign; 1340 goto parse_flag; 1341 1342 case oIdentitiesOnly: 1343 intptr = &options->identities_only; 1344 goto parse_flag; 1345 1346 case oServerAliveInterval: 1347 intptr = &options->server_alive_interval; 1348 goto parse_time; 1349 1350 case oServerAliveCountMax: 1351 intptr = &options->server_alive_count_max; 1352 goto parse_int; 1353 1354 case oSendEnv: 1355 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1356 if (strchr(arg, '=') != NULL) 1357 fatal("%s line %d: Invalid environment name.", 1358 filename, linenum); 1359 if (!*activep) 1360 continue; 1361 if (options->num_send_env >= MAX_SEND_ENV) 1362 fatal("%s line %d: too many send env.", 1363 filename, linenum); 1364 options->send_env[options->num_send_env++] = 1365 xstrdup(arg); 1366 } 1367 break; 1368 1369 case oControlPath: 1370 charptr = &options->control_path; 1371 goto parse_string; 1372 1373 case oControlMaster: 1374 intptr = &options->control_master; 1375 multistate_ptr = multistate_controlmaster; 1376 goto parse_multistate; 1377 1378 case oControlPersist: 1379 /* no/false/yes/true, or a time spec */ 1380 intptr = &options->control_persist; 1381 arg = strdelim(&s); 1382 if (!arg || *arg == '\0') 1383 fatal("%.200s line %d: Missing ControlPersist" 1384 " argument.", filename, linenum); 1385 value = 0; 1386 value2 = 0; /* timeout */ 1387 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 1388 value = 0; 1389 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 1390 value = 1; 1391 else if ((value2 = convtime(arg)) >= 0) 1392 value = 1; 1393 else 1394 fatal("%.200s line %d: Bad ControlPersist argument.", 1395 filename, linenum); 1396 if (*activep && *intptr == -1) { 1397 *intptr = value; 1398 options->control_persist_timeout = value2; 1399 } 1400 break; 1401 1402 case oHashKnownHosts: 1403 intptr = &options->hash_known_hosts; 1404 goto parse_flag; 1405 1406 case oTunnel: 1407 intptr = &options->tun_open; 1408 multistate_ptr = multistate_tunnel; 1409 goto parse_multistate; 1410 1411 case oTunnelDevice: 1412 arg = strdelim(&s); 1413 if (!arg || *arg == '\0') 1414 fatal("%.200s line %d: Missing argument.", filename, linenum); 1415 value = a2tun(arg, &value2); 1416 if (value == SSH_TUNID_ERR) 1417 fatal("%.200s line %d: Bad tun device.", filename, linenum); 1418 if (*activep) { 1419 options->tun_local = value; 1420 options->tun_remote = value2; 1421 } 1422 break; 1423 1424 case oLocalCommand: 1425 charptr = &options->local_command; 1426 goto parse_command; 1427 1428 case oPermitLocalCommand: 1429 intptr = &options->permit_local_command; 1430 goto parse_flag; 1431 1432 case oVisualHostKey: 1433 intptr = &options->visual_host_key; 1434 goto parse_flag; 1435 1436 case oIPQoS: 1437 arg = strdelim(&s); 1438 if ((value = parse_ipqos(arg)) == -1) 1439 fatal("%s line %d: Bad IPQoS value: %s", 1440 filename, linenum, arg); 1441 arg = strdelim(&s); 1442 if (arg == NULL) 1443 value2 = value; 1444 else if ((value2 = parse_ipqos(arg)) == -1) 1445 fatal("%s line %d: Bad IPQoS value: %s", 1446 filename, linenum, arg); 1447 if (*activep) { 1448 options->ip_qos_interactive = value; 1449 options->ip_qos_bulk = value2; 1450 } 1451 break; 1452 1453 case oRequestTTY: 1454 intptr = &options->request_tty; 1455 multistate_ptr = multistate_requesttty; 1456 goto parse_multistate; 1457 1458 case oSendVersionFirst: 1459 intptr = &options->send_version_first; 1460 goto parse_flag; 1461 1462 case oIgnoreUnknown: 1463 charptr = &options->ignored_unknown; 1464 goto parse_string; 1465 1466 case oProxyUseFdpass: 1467 intptr = &options->proxy_use_fdpass; 1468 goto parse_flag; 1469 1470 case oCanonicalDomains: 1471 value = options->num_canonical_domains != 0; 1472 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1473 valid_domain(arg, filename, linenum); 1474 if (!*activep || value) 1475 continue; 1476 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1477 fatal("%s line %d: too many hostname suffixes.", 1478 filename, linenum); 1479 options->canonical_domains[ 1480 options->num_canonical_domains++] = xstrdup(arg); 1481 } 1482 break; 1483 1484 case oCanonicalizePermittedCNAMEs: 1485 value = options->num_permitted_cnames != 0; 1486 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1487 /* Either '*' for everything or 'list:list' */ 1488 if (strcmp(arg, "*") == 0) 1489 arg2 = arg; 1490 else { 1491 lowercase(arg); 1492 if ((arg2 = strchr(arg, ':')) == NULL || 1493 arg2[1] == '\0') { 1494 fatal("%s line %d: " 1495 "Invalid permitted CNAME \"%s\"", 1496 filename, linenum, arg); 1497 } 1498 *arg2 = '\0'; 1499 arg2++; 1500 } 1501 if (!*activep || value) 1502 continue; 1503 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1504 fatal("%s line %d: too many permitted CNAMEs.", 1505 filename, linenum); 1506 cname = options->permitted_cnames + 1507 options->num_permitted_cnames++; 1508 cname->source_list = xstrdup(arg); 1509 cname->target_list = xstrdup(arg2); 1510 } 1511 break; 1512 1513 case oCanonicalizeHostname: 1514 intptr = &options->canonicalize_hostname; 1515 multistate_ptr = multistate_canonicalizehostname; 1516 goto parse_multistate; 1517 1518 case oCanonicalizeMaxDots: 1519 intptr = &options->canonicalize_max_dots; 1520 goto parse_int; 1521 1522 case oCanonicalizeFallbackLocal: 1523 intptr = &options->canonicalize_fallback_local; 1524 goto parse_flag; 1525 1526 case oStreamLocalBindMask: 1527 arg = strdelim(&s); 1528 if (!arg || *arg == '\0') 1529 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); 1530 /* Parse mode in octal format */ 1531 value = strtol(arg, &endofnumber, 8); 1532 if (arg == endofnumber || value < 0 || value > 0777) 1533 fatal("%.200s line %d: Bad mask.", filename, linenum); 1534 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1535 break; 1536 1537 case oStreamLocalBindUnlink: 1538 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1539 goto parse_flag; 1540 1541 case oRevokedHostKeys: 1542 charptr = &options->revoked_host_keys; 1543 goto parse_string; 1544 1545 case oFingerprintHash: 1546 intptr = &options->fingerprint_hash; 1547 arg = strdelim(&s); 1548 if (!arg || *arg == '\0') 1549 fatal("%.200s line %d: Missing argument.", 1550 filename, linenum); 1551 if ((value = ssh_digest_alg_by_name(arg)) == -1) 1552 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1553 filename, linenum, arg); 1554 if (*activep && *intptr == -1) 1555 *intptr = value; 1556 break; 1557 1558 case oUpdateHostkeys: 1559 intptr = &options->update_hostkeys; 1560 multistate_ptr = multistate_yesnoask; 1561 goto parse_multistate; 1562 1563 case oHostbasedKeyTypes: 1564 charptr = &options->hostbased_key_types; 1565 goto parse_keytypes; 1566 1567 case oPubkeyAcceptedKeyTypes: 1568 charptr = &options->pubkey_key_types; 1569 goto parse_keytypes; 1570 1571 case oDeprecated: 1572 debug("%s line %d: Deprecated option \"%s\"", 1573 filename, linenum, keyword); 1574 return 0; 1575 1576 case oUnsupported: 1577 error("%s line %d: Unsupported option \"%s\"", 1578 filename, linenum, keyword); 1579 return 0; 1580 1581 default: 1582 fatal("%s: Unimplemented opcode %d", __func__, opcode); 1583 } 1584 1585 /* Check that there is no garbage at end of line. */ 1586 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1587 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1588 filename, linenum, arg); 1589 } 1590 return 0; 1591 } 1592 1593 1594 /* 1595 * Reads the config file and modifies the options accordingly. Options 1596 * should already be initialized before this call. This never returns if 1597 * there is an error. If the file does not exist, this returns 0. 1598 */ 1599 1600 int 1601 read_config_file(const char *filename, struct passwd *pw, const char *host, 1602 const char *original_host, Options *options, int flags) 1603 { 1604 FILE *f; 1605 char line[1024]; 1606 int active, linenum; 1607 int bad_options = 0; 1608 1609 if ((f = fopen(filename, "r")) == NULL) 1610 return 0; 1611 1612 if (flags & SSHCONF_CHECKPERM) { 1613 struct stat sb; 1614 1615 if (fstat(fileno(f), &sb) == -1) 1616 fatal("fstat %s: %s", filename, strerror(errno)); 1617 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 1618 (sb.st_mode & 022) != 0)) 1619 fatal("Bad owner or permissions on %s", filename); 1620 } 1621 1622 debug("Reading configuration data %.200s", filename); 1623 1624 /* 1625 * Mark that we are now processing the options. This flag is turned 1626 * on/off by Host specifications. 1627 */ 1628 active = 1; 1629 linenum = 0; 1630 while (fgets(line, sizeof(line), f)) { 1631 /* Update line number counter. */ 1632 linenum++; 1633 if (process_config_line(options, pw, host, original_host, 1634 line, filename, linenum, &active, flags) != 0) 1635 bad_options++; 1636 } 1637 fclose(f); 1638 if (bad_options > 0) 1639 fatal("%s: terminating, %d bad configuration options", 1640 filename, bad_options); 1641 return 1; 1642 } 1643 1644 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 1645 int 1646 option_clear_or_none(const char *o) 1647 { 1648 return o == NULL || strcasecmp(o, "none") == 0; 1649 } 1650 1651 /* 1652 * Initializes options to special values that indicate that they have not yet 1653 * been set. Read_config_file will only set options with this value. Options 1654 * are processed in the following order: command line, user config file, 1655 * system config file. Last, fill_default_options is called. 1656 */ 1657 1658 void 1659 initialize_options(Options * options) 1660 { 1661 memset(options, 'X', sizeof(*options)); 1662 options->forward_agent = -1; 1663 options->forward_x11 = -1; 1664 options->forward_x11_trusted = -1; 1665 options->forward_x11_timeout = -1; 1666 options->exit_on_forward_failure = -1; 1667 options->xauth_location = NULL; 1668 options->fwd_opts.gateway_ports = -1; 1669 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 1670 options->fwd_opts.streamlocal_bind_unlink = -1; 1671 options->use_privileged_port = -1; 1672 options->rsa_authentication = -1; 1673 options->pubkey_authentication = -1; 1674 options->challenge_response_authentication = -1; 1675 #if defined(KRB4) || defined(KRB5) 1676 options->kerberos_authentication = -1; 1677 #endif 1678 #if defined(AFS) || defined(KRB5) 1679 options->kerberos_tgt_passing = -1; 1680 #endif 1681 #ifdef AFS 1682 options->afs_token_passing = -1; 1683 #endif 1684 options->gss_authentication = -1; 1685 options->gss_deleg_creds = -1; 1686 options->password_authentication = -1; 1687 options->kbd_interactive_authentication = -1; 1688 options->kbd_interactive_devices = NULL; 1689 options->rhosts_rsa_authentication = -1; 1690 options->hostbased_authentication = -1; 1691 options->batch_mode = -1; 1692 options->check_host_ip = -1; 1693 options->strict_host_key_checking = -1; 1694 options->compression = -1; 1695 options->tcp_keep_alive = -1; 1696 options->compression_level = -1; 1697 options->port = -1; 1698 options->address_family = -1; 1699 options->connection_attempts = -1; 1700 options->connection_timeout = -1; 1701 options->number_of_password_prompts = -1; 1702 options->cipher = -1; 1703 options->ciphers = NULL; 1704 options->macs = NULL; 1705 options->kex_algorithms = NULL; 1706 options->hostkeyalgorithms = NULL; 1707 options->protocol = SSH_PROTO_UNKNOWN; 1708 options->num_identity_files = 0; 1709 options->hostname = NULL; 1710 options->host_key_alias = NULL; 1711 options->proxy_command = NULL; 1712 options->user = NULL; 1713 options->escape_char = -1; 1714 options->num_system_hostfiles = 0; 1715 options->num_user_hostfiles = 0; 1716 options->local_forwards = NULL; 1717 options->num_local_forwards = 0; 1718 options->remote_forwards = NULL; 1719 options->num_remote_forwards = 0; 1720 options->clear_forwardings = -1; 1721 options->log_level = SYSLOG_LEVEL_NOT_SET; 1722 options->preferred_authentications = NULL; 1723 options->bind_address = NULL; 1724 options->pkcs11_provider = NULL; 1725 options->enable_ssh_keysign = - 1; 1726 options->no_host_authentication_for_localhost = - 1; 1727 options->identities_only = - 1; 1728 options->rekey_limit = - 1; 1729 options->rekey_interval = -1; 1730 options->verify_host_key_dns = -1; 1731 options->server_alive_interval = -1; 1732 options->server_alive_count_max = -1; 1733 options->num_send_env = 0; 1734 options->control_path = NULL; 1735 options->control_master = -1; 1736 options->control_persist = -1; 1737 options->control_persist_timeout = 0; 1738 options->hash_known_hosts = -1; 1739 options->tun_open = -1; 1740 options->tun_local = -1; 1741 options->tun_remote = -1; 1742 options->local_command = NULL; 1743 options->permit_local_command = -1; 1744 options->visual_host_key = -1; 1745 options->ip_qos_interactive = -1; 1746 options->ip_qos_bulk = -1; 1747 options->request_tty = -1; 1748 options->proxy_use_fdpass = -1; 1749 options->ignored_unknown = NULL; 1750 options->num_canonical_domains = 0; 1751 options->num_permitted_cnames = 0; 1752 options->canonicalize_max_dots = -1; 1753 options->canonicalize_fallback_local = -1; 1754 options->canonicalize_hostname = -1; 1755 options->revoked_host_keys = NULL; 1756 options->fingerprint_hash = -1; 1757 options->update_hostkeys = -1; 1758 options->hostbased_key_types = NULL; 1759 options->pubkey_key_types = NULL; 1760 options->none_switch = -1; 1761 options->none_enabled = -1; 1762 options->hpn_disabled = -1; 1763 options->hpn_buffer_size = -1; 1764 options->tcp_rcv_buf_poll = -1; 1765 options->tcp_rcv_buf = -1; 1766 options->send_version_first = -1; 1767 } 1768 1769 /* 1770 * A petite version of fill_default_options() that just fills the options 1771 * needed for hostname canonicalization to proceed. 1772 */ 1773 void 1774 fill_default_options_for_canonicalization(Options *options) 1775 { 1776 if (options->canonicalize_max_dots == -1) 1777 options->canonicalize_max_dots = 1; 1778 if (options->canonicalize_fallback_local == -1) 1779 options->canonicalize_fallback_local = 1; 1780 if (options->canonicalize_hostname == -1) 1781 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1782 } 1783 1784 /* 1785 * Called after processing other sources of option data, this fills those 1786 * options for which no value has been specified with their default values. 1787 */ 1788 void 1789 fill_default_options(Options * options) 1790 { 1791 if (options->forward_agent == -1) 1792 options->forward_agent = 0; 1793 if (options->forward_x11 == -1) 1794 options->forward_x11 = 0; 1795 if (options->forward_x11_trusted == -1) 1796 options->forward_x11_trusted = 0; 1797 if (options->forward_x11_timeout == -1) 1798 options->forward_x11_timeout = 1200; 1799 if (options->exit_on_forward_failure == -1) 1800 options->exit_on_forward_failure = 0; 1801 if (options->xauth_location == NULL) 1802 options->xauth_location = __UNCONST(_PATH_XAUTH); 1803 if (options->fwd_opts.gateway_ports == -1) 1804 options->fwd_opts.gateway_ports = 0; 1805 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 1806 options->fwd_opts.streamlocal_bind_mask = 0177; 1807 if (options->fwd_opts.streamlocal_bind_unlink == -1) 1808 options->fwd_opts.streamlocal_bind_unlink = 0; 1809 if (options->use_privileged_port == -1) 1810 options->use_privileged_port = 0; 1811 if (options->rsa_authentication == -1) 1812 options->rsa_authentication = 1; 1813 if (options->pubkey_authentication == -1) 1814 options->pubkey_authentication = 1; 1815 if (options->challenge_response_authentication == -1) 1816 options->challenge_response_authentication = 1; 1817 #if defined(KRB4) || defined(KRB5) 1818 if (options->kerberos_authentication == -1) 1819 options->kerberos_authentication = 1; 1820 #endif 1821 #if defined(AFS) || defined(KRB5) 1822 if (options->kerberos_tgt_passing == -1) 1823 options->kerberos_tgt_passing = 1; 1824 #endif 1825 #ifdef AFS 1826 if (options->afs_token_passing == -1) 1827 options->afs_token_passing = 1; 1828 #endif 1829 if (options->gss_authentication == -1) 1830 options->gss_authentication = 0; 1831 if (options->gss_deleg_creds == -1) 1832 options->gss_deleg_creds = 0; 1833 if (options->password_authentication == -1) 1834 options->password_authentication = 1; 1835 if (options->kbd_interactive_authentication == -1) 1836 options->kbd_interactive_authentication = 1; 1837 if (options->rhosts_rsa_authentication == -1) 1838 options->rhosts_rsa_authentication = 0; 1839 if (options->hostbased_authentication == -1) 1840 options->hostbased_authentication = 0; 1841 if (options->batch_mode == -1) 1842 options->batch_mode = 0; 1843 if (options->check_host_ip == -1) 1844 options->check_host_ip = 1; 1845 if (options->strict_host_key_checking == -1) 1846 options->strict_host_key_checking = 2; /* 2 is default */ 1847 if (options->compression == -1) 1848 options->compression = 0; 1849 if (options->tcp_keep_alive == -1) 1850 options->tcp_keep_alive = 1; 1851 if (options->compression_level == -1) 1852 options->compression_level = 6; 1853 if (options->port == -1) 1854 options->port = 0; /* Filled in ssh_connect. */ 1855 if (options->address_family == -1) 1856 options->address_family = AF_UNSPEC; 1857 if (options->connection_attempts == -1) 1858 options->connection_attempts = 1; 1859 if (options->number_of_password_prompts == -1) 1860 options->number_of_password_prompts = 3; 1861 /* Selected in ssh_login(). */ 1862 if (options->cipher == -1) 1863 options->cipher = SSH_CIPHER_NOT_SET; 1864 /* options->hostkeyalgorithms, default set in myproposals.h */ 1865 if (options->protocol == SSH_PROTO_UNKNOWN) 1866 options->protocol = SSH_PROTO_2; 1867 if (options->num_identity_files == 0) { 1868 if (options->protocol & SSH_PROTO_1) { 1869 add_identity_file(options, "~/", 1870 _PATH_SSH_CLIENT_IDENTITY, 0); 1871 } 1872 if (options->protocol & SSH_PROTO_2) { 1873 add_identity_file(options, "~/", 1874 _PATH_SSH_CLIENT_ID_RSA, 0); 1875 add_identity_file(options, "~/", 1876 _PATH_SSH_CLIENT_ID_DSA, 0); 1877 add_identity_file(options, "~/", 1878 _PATH_SSH_CLIENT_ID_ECDSA, 0); 1879 add_identity_file(options, "~/", 1880 _PATH_SSH_CLIENT_ID_ED25519, 0); 1881 } 1882 } 1883 if (options->escape_char == -1) 1884 options->escape_char = '~'; 1885 if (options->num_system_hostfiles == 0) { 1886 options->system_hostfiles[options->num_system_hostfiles++] = 1887 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1888 options->system_hostfiles[options->num_system_hostfiles++] = 1889 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1890 } 1891 if (options->num_user_hostfiles == 0) { 1892 options->user_hostfiles[options->num_user_hostfiles++] = 1893 xstrdup(_PATH_SSH_USER_HOSTFILE); 1894 options->user_hostfiles[options->num_user_hostfiles++] = 1895 xstrdup(_PATH_SSH_USER_HOSTFILE2); 1896 } 1897 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1898 options->log_level = SYSLOG_LEVEL_INFO; 1899 if (options->clear_forwardings == 1) 1900 clear_forwardings(options); 1901 if (options->no_host_authentication_for_localhost == - 1) 1902 options->no_host_authentication_for_localhost = 0; 1903 if (options->identities_only == -1) 1904 options->identities_only = 0; 1905 if (options->enable_ssh_keysign == -1) 1906 options->enable_ssh_keysign = 0; 1907 if (options->rekey_limit == -1) 1908 options->rekey_limit = 0; 1909 if (options->rekey_interval == -1) 1910 options->rekey_interval = 0; 1911 if (options->verify_host_key_dns == -1) 1912 options->verify_host_key_dns = 0; 1913 if (options->server_alive_interval == -1) 1914 options->server_alive_interval = 0; 1915 if (options->server_alive_count_max == -1) 1916 options->server_alive_count_max = 3; 1917 if (options->none_switch == -1) 1918 options->none_switch = 0; 1919 if (options->hpn_disabled == -1) 1920 options->hpn_disabled = 0; 1921 if (options->hpn_buffer_size > -1) 1922 { 1923 /* if a user tries to set the size to 0 set it to 1KB */ 1924 if (options->hpn_buffer_size == 0) 1925 options->hpn_buffer_size = 1024; 1926 /*limit the buffer to 64MB*/ 1927 if (options->hpn_buffer_size > 65536) 1928 { 1929 options->hpn_buffer_size = 65536*1024; 1930 debug("User requested buffer larger than 64MB. Request reverted to 64MB"); 1931 } 1932 debug("hpn_buffer_size set to %d", options->hpn_buffer_size); 1933 } 1934 if (options->tcp_rcv_buf == 0) 1935 options->tcp_rcv_buf = 1; 1936 if (options->tcp_rcv_buf > -1) 1937 options->tcp_rcv_buf *=1024; 1938 if (options->tcp_rcv_buf_poll == -1) 1939 options->tcp_rcv_buf_poll = 1; 1940 if (options->control_master == -1) 1941 options->control_master = 0; 1942 if (options->control_persist == -1) { 1943 options->control_persist = 0; 1944 options->control_persist_timeout = 0; 1945 } 1946 if (options->hash_known_hosts == -1) 1947 options->hash_known_hosts = 0; 1948 if (options->tun_open == -1) 1949 options->tun_open = SSH_TUNMODE_NO; 1950 if (options->tun_local == -1) 1951 options->tun_local = SSH_TUNID_ANY; 1952 if (options->tun_remote == -1) 1953 options->tun_remote = SSH_TUNID_ANY; 1954 if (options->permit_local_command == -1) 1955 options->permit_local_command = 0; 1956 if (options->visual_host_key == -1) 1957 options->visual_host_key = 0; 1958 if (options->ip_qos_interactive == -1) 1959 options->ip_qos_interactive = IPTOS_LOWDELAY; 1960 if (options->ip_qos_bulk == -1) 1961 options->ip_qos_bulk = IPTOS_THROUGHPUT; 1962 if (options->request_tty == -1) 1963 options->request_tty = REQUEST_TTY_AUTO; 1964 if (options->proxy_use_fdpass == -1) 1965 options->proxy_use_fdpass = 0; 1966 if (options->canonicalize_max_dots == -1) 1967 options->canonicalize_max_dots = 1; 1968 if (options->canonicalize_fallback_local == -1) 1969 options->canonicalize_fallback_local = 1; 1970 if (options->canonicalize_hostname == -1) 1971 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1972 if (options->fingerprint_hash == -1) 1973 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 1974 if (options->update_hostkeys == -1) 1975 options->update_hostkeys = 0; 1976 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || 1977 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || 1978 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || 1979 kex_assemble_names(KEX_DEFAULT_PK_ALG, 1980 &options->hostbased_key_types) != 0 || 1981 kex_assemble_names(KEX_DEFAULT_PK_ALG, 1982 &options->pubkey_key_types) != 0) 1983 fatal("%s: kex_assemble_names failed", __func__); 1984 1985 if (options->send_version_first == -1) 1986 options->send_version_first = 1; 1987 #define CLEAR_ON_NONE(v) \ 1988 do { \ 1989 if (option_clear_or_none(v)) { \ 1990 free(v); \ 1991 v = NULL; \ 1992 } \ 1993 } while(0) 1994 CLEAR_ON_NONE(options->local_command); 1995 CLEAR_ON_NONE(options->proxy_command); 1996 CLEAR_ON_NONE(options->control_path); 1997 CLEAR_ON_NONE(options->revoked_host_keys); 1998 /* options->user will be set in the main program if appropriate */ 1999 /* options->hostname will be set in the main program if appropriate */ 2000 /* options->host_key_alias should not be set by default */ 2001 /* options->preferred_authentications will be set in ssh */ 2002 } 2003 2004 struct fwdarg { 2005 char *arg; 2006 int ispath; 2007 }; 2008 2009 /* 2010 * parse_fwd_field 2011 * parses the next field in a port forwarding specification. 2012 * sets fwd to the parsed field and advances p past the colon 2013 * or sets it to NULL at end of string. 2014 * returns 0 on success, else non-zero. 2015 */ 2016 static int 2017 parse_fwd_field(char **p, struct fwdarg *fwd) 2018 { 2019 char *ep, *cp = *p; 2020 int ispath = 0; 2021 2022 if (*cp == '\0') { 2023 *p = NULL; 2024 return -1; /* end of string */ 2025 } 2026 2027 /* 2028 * A field escaped with square brackets is used literally. 2029 * XXX - allow ']' to be escaped via backslash? 2030 */ 2031 if (*cp == '[') { 2032 /* find matching ']' */ 2033 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { 2034 if (*ep == '/') 2035 ispath = 1; 2036 } 2037 /* no matching ']' or not at end of field. */ 2038 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) 2039 return -1; 2040 /* NUL terminate the field and advance p past the colon */ 2041 *ep++ = '\0'; 2042 if (*ep != '\0') 2043 *ep++ = '\0'; 2044 fwd->arg = cp + 1; 2045 fwd->ispath = ispath; 2046 *p = ep; 2047 return 0; 2048 } 2049 2050 for (cp = *p; *cp != '\0'; cp++) { 2051 switch (*cp) { 2052 case '\\': 2053 memmove(cp, cp + 1, strlen(cp + 1) + 1); 2054 if (*cp == '\0') 2055 return -1; 2056 break; 2057 case '/': 2058 ispath = 1; 2059 break; 2060 case ':': 2061 *cp++ = '\0'; 2062 goto done; 2063 } 2064 } 2065 done: 2066 fwd->arg = *p; 2067 fwd->ispath = ispath; 2068 *p = cp; 2069 return 0; 2070 } 2071 2072 /* 2073 * parse_forward 2074 * parses a string containing a port forwarding specification of the form: 2075 * dynamicfwd == 0 2076 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath 2077 * listenpath:connectpath 2078 * dynamicfwd == 1 2079 * [listenhost:]listenport 2080 * returns number of arguments parsed or zero on error 2081 */ 2082 int 2083 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 2084 { 2085 struct fwdarg fwdargs[4]; 2086 char *p, *cp; 2087 int i; 2088 2089 memset(fwd, 0, sizeof(*fwd)); 2090 memset(fwdargs, 0, sizeof(fwdargs)); 2091 2092 cp = p = xstrdup(fwdspec); 2093 2094 /* skip leading spaces */ 2095 while (isspace((u_char)*cp)) 2096 cp++; 2097 2098 for (i = 0; i < 4; ++i) { 2099 if (parse_fwd_field(&cp, &fwdargs[i]) != 0) 2100 break; 2101 } 2102 2103 /* Check for trailing garbage */ 2104 if (cp != NULL && *cp != '\0') { 2105 i = 0; /* failure */ 2106 } 2107 2108 switch (i) { 2109 case 1: 2110 if (fwdargs[0].ispath) { 2111 fwd->listen_path = xstrdup(fwdargs[0].arg); 2112 fwd->listen_port = PORT_STREAMLOCAL; 2113 } else { 2114 fwd->listen_host = NULL; 2115 fwd->listen_port = a2port(fwdargs[0].arg); 2116 } 2117 fwd->connect_host = xstrdup("socks"); 2118 break; 2119 2120 case 2: 2121 if (fwdargs[0].ispath && fwdargs[1].ispath) { 2122 fwd->listen_path = xstrdup(fwdargs[0].arg); 2123 fwd->listen_port = PORT_STREAMLOCAL; 2124 fwd->connect_path = xstrdup(fwdargs[1].arg); 2125 fwd->connect_port = PORT_STREAMLOCAL; 2126 } else if (fwdargs[1].ispath) { 2127 fwd->listen_host = NULL; 2128 fwd->listen_port = a2port(fwdargs[0].arg); 2129 fwd->connect_path = xstrdup(fwdargs[1].arg); 2130 fwd->connect_port = PORT_STREAMLOCAL; 2131 } else { 2132 fwd->listen_host = xstrdup(fwdargs[0].arg); 2133 fwd->listen_port = a2port(fwdargs[1].arg); 2134 fwd->connect_host = xstrdup("socks"); 2135 } 2136 break; 2137 2138 case 3: 2139 if (fwdargs[0].ispath) { 2140 fwd->listen_path = xstrdup(fwdargs[0].arg); 2141 fwd->listen_port = PORT_STREAMLOCAL; 2142 fwd->connect_host = xstrdup(fwdargs[1].arg); 2143 fwd->connect_port = a2port(fwdargs[2].arg); 2144 } else if (fwdargs[2].ispath) { 2145 fwd->listen_host = xstrdup(fwdargs[0].arg); 2146 fwd->listen_port = a2port(fwdargs[1].arg); 2147 fwd->connect_path = xstrdup(fwdargs[2].arg); 2148 fwd->connect_port = PORT_STREAMLOCAL; 2149 } else { 2150 fwd->listen_host = NULL; 2151 fwd->listen_port = a2port(fwdargs[0].arg); 2152 fwd->connect_host = xstrdup(fwdargs[1].arg); 2153 fwd->connect_port = a2port(fwdargs[2].arg); 2154 } 2155 break; 2156 2157 case 4: 2158 fwd->listen_host = xstrdup(fwdargs[0].arg); 2159 fwd->listen_port = a2port(fwdargs[1].arg); 2160 fwd->connect_host = xstrdup(fwdargs[2].arg); 2161 fwd->connect_port = a2port(fwdargs[3].arg); 2162 break; 2163 default: 2164 i = 0; /* failure */ 2165 } 2166 2167 free(p); 2168 2169 if (dynamicfwd) { 2170 if (!(i == 1 || i == 2)) 2171 goto fail_free; 2172 } else { 2173 if (!(i == 3 || i == 4)) { 2174 if (fwd->connect_path == NULL && 2175 fwd->listen_path == NULL) 2176 goto fail_free; 2177 } 2178 if (fwd->connect_port <= 0 && fwd->connect_path == NULL) 2179 goto fail_free; 2180 } 2181 2182 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || 2183 (!remotefwd && fwd->listen_port == 0)) 2184 goto fail_free; 2185 if (fwd->connect_host != NULL && 2186 strlen(fwd->connect_host) >= NI_MAXHOST) 2187 goto fail_free; 2188 /* XXX - if connecting to a remote socket, max sun len may not match this host */ 2189 if (fwd->connect_path != NULL && 2190 strlen(fwd->connect_path) >= PATH_MAX_SUN) 2191 goto fail_free; 2192 if (fwd->listen_host != NULL && 2193 strlen(fwd->listen_host) >= NI_MAXHOST) 2194 goto fail_free; 2195 if (fwd->listen_path != NULL && 2196 strlen(fwd->listen_path) >= PATH_MAX_SUN) 2197 goto fail_free; 2198 2199 return (i); 2200 2201 fail_free: 2202 free(fwd->connect_host); 2203 fwd->connect_host = NULL; 2204 free(fwd->connect_path); 2205 fwd->connect_path = NULL; 2206 free(fwd->listen_host); 2207 fwd->listen_host = NULL; 2208 free(fwd->listen_path); 2209 fwd->listen_path = NULL; 2210 return (0); 2211 } 2212 2213 /* XXX the following is a near-vebatim copy from servconf.c; refactor */ 2214 static const char * 2215 fmt_multistate_int(int val, const struct multistate *m) 2216 { 2217 u_int i; 2218 2219 for (i = 0; m[i].key != NULL; i++) { 2220 if (m[i].value == val) 2221 return m[i].key; 2222 } 2223 return "UNKNOWN"; 2224 } 2225 2226 static const char * 2227 fmt_intarg(OpCodes code, int val) 2228 { 2229 if (val == -1) 2230 return "unset"; 2231 switch (code) { 2232 case oAddressFamily: 2233 return fmt_multistate_int(val, multistate_addressfamily); 2234 case oVerifyHostKeyDNS: 2235 case oStrictHostKeyChecking: 2236 case oUpdateHostkeys: 2237 return fmt_multistate_int(val, multistate_yesnoask); 2238 case oControlMaster: 2239 return fmt_multistate_int(val, multistate_controlmaster); 2240 case oTunnel: 2241 return fmt_multistate_int(val, multistate_tunnel); 2242 case oRequestTTY: 2243 return fmt_multistate_int(val, multistate_requesttty); 2244 case oCanonicalizeHostname: 2245 return fmt_multistate_int(val, multistate_canonicalizehostname); 2246 case oFingerprintHash: 2247 return ssh_digest_alg_name(val); 2248 case oProtocol: 2249 switch (val) { 2250 case SSH_PROTO_1: 2251 return "1"; 2252 case SSH_PROTO_2: 2253 return "2"; 2254 case (SSH_PROTO_1|SSH_PROTO_2): 2255 return "2,1"; 2256 default: 2257 return "UNKNOWN"; 2258 } 2259 default: 2260 switch (val) { 2261 case 0: 2262 return "no"; 2263 case 1: 2264 return "yes"; 2265 default: 2266 return "UNKNOWN"; 2267 } 2268 } 2269 } 2270 2271 static const char * 2272 lookup_opcode_name(OpCodes code) 2273 { 2274 u_int i; 2275 2276 for (i = 0; keywords[i].name != NULL; i++) 2277 if (keywords[i].opcode == code) 2278 return(keywords[i].name); 2279 return "UNKNOWN"; 2280 } 2281 2282 static void 2283 dump_cfg_int(OpCodes code, int val) 2284 { 2285 printf("%s %d\n", lookup_opcode_name(code), val); 2286 } 2287 2288 static void 2289 dump_cfg_fmtint(OpCodes code, int val) 2290 { 2291 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2292 } 2293 2294 static void 2295 dump_cfg_string(OpCodes code, const char *val) 2296 { 2297 if (val == NULL) 2298 return; 2299 printf("%s %s\n", lookup_opcode_name(code), val); 2300 } 2301 2302 static void 2303 dump_cfg_strarray(OpCodes code, u_int count, char **vals) 2304 { 2305 u_int i; 2306 2307 for (i = 0; i < count; i++) 2308 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2309 } 2310 2311 static void 2312 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) 2313 { 2314 u_int i; 2315 2316 printf("%s", lookup_opcode_name(code)); 2317 for (i = 0; i < count; i++) 2318 printf(" %s", vals[i]); 2319 printf("\n"); 2320 } 2321 2322 static void 2323 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) 2324 { 2325 const struct Forward *fwd; 2326 u_int i; 2327 2328 /* oDynamicForward */ 2329 for (i = 0; i < count; i++) { 2330 fwd = &fwds[i]; 2331 if (code == oDynamicForward && 2332 strcmp(fwd->connect_host, "socks") != 0) 2333 continue; 2334 if (code == oLocalForward && 2335 strcmp(fwd->connect_host, "socks") == 0) 2336 continue; 2337 printf("%s", lookup_opcode_name(code)); 2338 if (fwd->listen_port == PORT_STREAMLOCAL) 2339 printf(" %s", fwd->listen_path); 2340 else if (fwd->listen_host == NULL) 2341 printf(" %d", fwd->listen_port); 2342 else { 2343 printf(" [%s]:%d", 2344 fwd->listen_host, fwd->listen_port); 2345 } 2346 if (code != oDynamicForward) { 2347 if (fwd->connect_port == PORT_STREAMLOCAL) 2348 printf(" %s", fwd->connect_path); 2349 else if (fwd->connect_host == NULL) 2350 printf(" %d", fwd->connect_port); 2351 else { 2352 printf(" [%s]:%d", 2353 fwd->connect_host, fwd->connect_port); 2354 } 2355 } 2356 printf("\n"); 2357 } 2358 } 2359 2360 void 2361 dump_client_config(Options *o, const char *host) 2362 { 2363 int i; 2364 char vbuf[5]; 2365 2366 /* Most interesting options first: user, host, port */ 2367 dump_cfg_string(oUser, o->user); 2368 dump_cfg_string(oHostName, host); 2369 dump_cfg_int(oPort, o->port); 2370 2371 /* Flag options */ 2372 dump_cfg_fmtint(oAddressFamily, o->address_family); 2373 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2374 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2375 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); 2376 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); 2377 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); 2378 dump_cfg_fmtint(oCompression, o->compression); 2379 dump_cfg_fmtint(oControlMaster, o->control_master); 2380 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); 2381 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2382 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2383 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2384 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2385 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2386 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2387 #ifdef GSSAPI 2388 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2389 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2390 #endif /* GSSAPI */ 2391 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2392 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2393 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); 2394 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); 2395 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2396 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2397 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2398 dump_cfg_fmtint(oProtocol, o->protocol); 2399 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2400 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2401 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2402 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2403 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); 2404 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2405 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2406 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2407 dump_cfg_fmtint(oTunnel, o->tun_open); 2408 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); 2409 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); 2410 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); 2411 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); 2412 2413 /* Integer options */ 2414 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2415 dump_cfg_int(oCompressionLevel, o->compression_level); 2416 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2417 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2418 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2419 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); 2420 dump_cfg_int(oServerAliveInterval, o->server_alive_interval); 2421 2422 /* String options */ 2423 dump_cfg_string(oBindAddress, o->bind_address); 2424 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); 2425 dump_cfg_string(oControlPath, o->control_path); 2426 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2427 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2428 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2429 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2430 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); 2431 dump_cfg_string(oLocalCommand, o->local_command); 2432 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2433 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); 2434 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2435 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2436 dump_cfg_string(oProxyCommand, o->proxy_command); 2437 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2438 dump_cfg_string(oXAuthLocation, o->xauth_location); 2439 2440 /* Forwards */ 2441 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2442 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2443 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); 2444 2445 /* String array options */ 2446 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); 2447 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); 2448 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); 2449 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); 2450 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); 2451 2452 /* Special cases */ 2453 2454 /* oConnectTimeout */ 2455 if (o->connection_timeout == -1) 2456 printf("connecttimeout none\n"); 2457 else 2458 dump_cfg_int(oConnectTimeout, o->connection_timeout); 2459 2460 /* oTunnelDevice */ 2461 printf("tunneldevice"); 2462 if (o->tun_local == SSH_TUNID_ANY) 2463 printf(" any"); 2464 else 2465 printf(" %d", o->tun_local); 2466 if (o->tun_remote == SSH_TUNID_ANY) 2467 printf(":any"); 2468 else 2469 printf(":%d", o->tun_remote); 2470 printf("\n"); 2471 2472 /* oCanonicalizePermittedCNAMEs */ 2473 if ( o->num_permitted_cnames > 0) { 2474 printf("canonicalizePermittedcnames"); 2475 for (i = 0; i < o->num_permitted_cnames; i++) { 2476 printf(" %s:%s", o->permitted_cnames[i].source_list, 2477 o->permitted_cnames[i].target_list); 2478 } 2479 printf("\n"); 2480 } 2481 2482 /* oCipher */ 2483 if (o->cipher != SSH_CIPHER_NOT_SET) 2484 printf("Cipher %s\n", cipher_name(o->cipher)); 2485 2486 /* oControlPersist */ 2487 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2488 dump_cfg_fmtint(oControlPersist, o->control_persist); 2489 else 2490 dump_cfg_int(oControlPersist, o->control_persist_timeout); 2491 2492 /* oEscapeChar */ 2493 if (o->escape_char == SSH_ESCAPECHAR_NONE) 2494 printf("escapechar none\n"); 2495 else { 2496 vis(vbuf, o->escape_char, VIS_WHITE, 0); 2497 printf("escapechar %s\n", vbuf); 2498 } 2499 2500 /* oIPQoS */ 2501 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2502 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2503 2504 /* oRekeyLimit */ 2505 printf("rekeylimit %lld %d\n", 2506 (long long)o->rekey_limit, o->rekey_interval); 2507 2508 /* oStreamLocalBindMask */ 2509 printf("streamlocalbindmask 0%o\n", 2510 o->fwd_opts.streamlocal_bind_mask); 2511 } 2512