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