1 /* $OpenBSD: readconf.c,v 1.260 2016/08/25 23:56:51 djm 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, oProxyJump, 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 { "proxyjump", oProxyJump }, 284 285 { NULL, oBadOption } 286 }; 287 288 /* 289 * Adds a local TCP/IP port forward to options. Never returns if there is an 290 * error. 291 */ 292 293 void 294 add_local_forward(Options *options, const struct Forward *newfwd) 295 { 296 struct Forward *fwd; 297 extern uid_t original_real_uid; 298 int i; 299 300 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && 301 newfwd->listen_path == NULL) 302 fatal("Privileged ports can only be forwarded by root."); 303 /* Don't add duplicates */ 304 for (i = 0; i < options->num_local_forwards; i++) { 305 if (forward_equals(newfwd, options->local_forwards + i)) 306 return; 307 } 308 options->local_forwards = xreallocarray(options->local_forwards, 309 options->num_local_forwards + 1, 310 sizeof(*options->local_forwards)); 311 fwd = &options->local_forwards[options->num_local_forwards++]; 312 313 fwd->listen_host = newfwd->listen_host; 314 fwd->listen_port = newfwd->listen_port; 315 fwd->listen_path = newfwd->listen_path; 316 fwd->connect_host = newfwd->connect_host; 317 fwd->connect_port = newfwd->connect_port; 318 fwd->connect_path = newfwd->connect_path; 319 } 320 321 /* 322 * Adds a remote TCP/IP port forward to options. Never returns if there is 323 * an error. 324 */ 325 326 void 327 add_remote_forward(Options *options, const struct Forward *newfwd) 328 { 329 struct Forward *fwd; 330 int i; 331 332 /* Don't add duplicates */ 333 for (i = 0; i < options->num_remote_forwards; i++) { 334 if (forward_equals(newfwd, options->remote_forwards + i)) 335 return; 336 } 337 options->remote_forwards = xreallocarray(options->remote_forwards, 338 options->num_remote_forwards + 1, 339 sizeof(*options->remote_forwards)); 340 fwd = &options->remote_forwards[options->num_remote_forwards++]; 341 342 fwd->listen_host = newfwd->listen_host; 343 fwd->listen_port = newfwd->listen_port; 344 fwd->listen_path = newfwd->listen_path; 345 fwd->connect_host = newfwd->connect_host; 346 fwd->connect_port = newfwd->connect_port; 347 fwd->connect_path = newfwd->connect_path; 348 fwd->handle = newfwd->handle; 349 fwd->allocated_port = 0; 350 } 351 352 static void 353 clear_forwardings(Options *options) 354 { 355 int i; 356 357 for (i = 0; i < options->num_local_forwards; i++) { 358 free(options->local_forwards[i].listen_host); 359 free(options->local_forwards[i].listen_path); 360 free(options->local_forwards[i].connect_host); 361 free(options->local_forwards[i].connect_path); 362 } 363 if (options->num_local_forwards > 0) { 364 free(options->local_forwards); 365 options->local_forwards = NULL; 366 } 367 options->num_local_forwards = 0; 368 for (i = 0; i < options->num_remote_forwards; i++) { 369 free(options->remote_forwards[i].listen_host); 370 free(options->remote_forwards[i].listen_path); 371 free(options->remote_forwards[i].connect_host); 372 free(options->remote_forwards[i].connect_path); 373 } 374 if (options->num_remote_forwards > 0) { 375 free(options->remote_forwards); 376 options->remote_forwards = NULL; 377 } 378 options->num_remote_forwards = 0; 379 options->tun_open = SSH_TUNMODE_NO; 380 } 381 382 void 383 add_certificate_file(Options *options, const char *path, int userprovided) 384 { 385 int i; 386 387 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES) 388 fatal("Too many certificate files specified (max %d)", 389 SSH_MAX_CERTIFICATE_FILES); 390 391 /* Avoid registering duplicates */ 392 for (i = 0; i < options->num_certificate_files; i++) { 393 if (options->certificate_file_userprovided[i] == userprovided && 394 strcmp(options->certificate_files[i], path) == 0) { 395 debug2("%s: ignoring duplicate key %s", __func__, path); 396 return; 397 } 398 } 399 400 options->certificate_file_userprovided[options->num_certificate_files] = 401 userprovided; 402 options->certificate_files[options->num_certificate_files++] = 403 xstrdup(path); 404 } 405 406 void 407 add_identity_file(Options *options, const char *dir, const char *filename, 408 int userprovided) 409 { 410 char *path; 411 int i; 412 413 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 414 fatal("Too many identity files specified (max %d)", 415 SSH_MAX_IDENTITY_FILES); 416 417 if (dir == NULL) /* no dir, filename is absolute */ 418 path = xstrdup(filename); 419 else 420 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 421 422 /* Avoid registering duplicates */ 423 for (i = 0; i < options->num_identity_files; i++) { 424 if (options->identity_file_userprovided[i] == userprovided && 425 strcmp(options->identity_files[i], path) == 0) { 426 debug2("%s: ignoring duplicate key %s", __func__, path); 427 free(path); 428 return; 429 } 430 } 431 432 options->identity_file_userprovided[options->num_identity_files] = 433 userprovided; 434 options->identity_files[options->num_identity_files++] = path; 435 } 436 437 int 438 default_ssh_port(void) 439 { 440 static int port; 441 struct servent *sp; 442 443 if (port == 0) { 444 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 445 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 446 } 447 return port; 448 } 449 450 /* 451 * Execute a command in a shell. 452 * Return its exit status or -1 on abnormal exit. 453 */ 454 static int 455 execute_in_shell(const char *cmd) 456 { 457 char *shell; 458 pid_t pid; 459 int devnull, status; 460 extern uid_t original_real_uid; 461 462 if ((shell = getenv("SHELL")) == NULL) 463 shell = _PATH_BSHELL; 464 465 /* Need this to redirect subprocess stdin/out */ 466 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 467 fatal("open(/dev/null): %s", strerror(errno)); 468 469 debug("Executing command: '%.500s'", cmd); 470 471 /* Fork and execute the command. */ 472 if ((pid = fork()) == 0) { 473 char *argv[4]; 474 475 /* Child. Permanently give up superuser privileges. */ 476 permanently_drop_suid(original_real_uid); 477 478 /* Redirect child stdin and stdout. Leave stderr */ 479 if (dup2(devnull, STDIN_FILENO) == -1) 480 fatal("dup2: %s", strerror(errno)); 481 if (dup2(devnull, STDOUT_FILENO) == -1) 482 fatal("dup2: %s", strerror(errno)); 483 if (devnull > STDERR_FILENO) 484 close(devnull); 485 closefrom(STDERR_FILENO + 1); 486 487 argv[0] = shell; 488 argv[1] = "-c"; 489 argv[2] = xstrdup(cmd); 490 argv[3] = NULL; 491 492 execv(argv[0], argv); 493 error("Unable to execute '%.100s': %s", cmd, strerror(errno)); 494 /* Die with signal to make this error apparent to parent. */ 495 signal(SIGTERM, SIG_DFL); 496 kill(getpid(), SIGTERM); 497 _exit(1); 498 } 499 /* Parent. */ 500 if (pid < 0) 501 fatal("%s: fork: %.100s", __func__, strerror(errno)); 502 503 close(devnull); 504 505 while (waitpid(pid, &status, 0) == -1) { 506 if (errno != EINTR && errno != EAGAIN) 507 fatal("%s: waitpid: %s", __func__, strerror(errno)); 508 } 509 if (!WIFEXITED(status)) { 510 error("command '%.100s' exited abnormally", cmd); 511 return -1; 512 } 513 debug3("command returned status %d", WEXITSTATUS(status)); 514 return WEXITSTATUS(status); 515 } 516 517 /* 518 * Parse and execute a Match directive. 519 */ 520 static int 521 match_cfg_line(Options *options, char **condition, struct passwd *pw, 522 const char *host_arg, const char *original_host, int post_canon, 523 const char *filename, int linenum) 524 { 525 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; 526 const char *ruser; 527 int r, port, this_result, result = 1, attributes = 0, negate; 528 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 529 530 /* 531 * Configuration is likely to be incomplete at this point so we 532 * must be prepared to use default values. 533 */ 534 port = options->port <= 0 ? default_ssh_port() : options->port; 535 ruser = options->user == NULL ? pw->pw_name : options->user; 536 if (post_canon) { 537 host = xstrdup(options->hostname); 538 } else if (options->hostname != NULL) { 539 /* NB. Please keep in sync with ssh.c:main() */ 540 host = percent_expand(options->hostname, 541 "h", host_arg, (char *)NULL); 542 } else { 543 host = xstrdup(host_arg); 544 } 545 546 debug2("checking match for '%s' host %s originally %s", 547 cp, host, original_host); 548 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { 549 criteria = NULL; 550 this_result = 1; 551 if ((negate = attrib[0] == '!')) 552 attrib++; 553 /* criteria "all" and "canonical" have no argument */ 554 if (strcasecmp(attrib, "all") == 0) { 555 if (attributes > 1 || 556 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 557 error("%.200s line %d: '%s' cannot be combined " 558 "with other Match attributes", 559 filename, linenum, oattrib); 560 result = -1; 561 goto out; 562 } 563 if (result) 564 result = negate ? 0 : 1; 565 goto out; 566 } 567 attributes++; 568 if (strcasecmp(attrib, "canonical") == 0) { 569 r = !!post_canon; /* force bitmask member to boolean */ 570 if (r == (negate ? 1 : 0)) 571 this_result = result = 0; 572 debug3("%.200s line %d: %smatched '%s'", 573 filename, linenum, 574 this_result ? "" : "not ", oattrib); 575 continue; 576 } 577 /* All other criteria require an argument */ 578 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 579 error("Missing Match criteria for %s", attrib); 580 result = -1; 581 goto out; 582 } 583 if (strcasecmp(attrib, "host") == 0) { 584 criteria = xstrdup(host); 585 r = match_hostname(host, arg) == 1; 586 if (r == (negate ? 1 : 0)) 587 this_result = result = 0; 588 } else if (strcasecmp(attrib, "originalhost") == 0) { 589 criteria = xstrdup(original_host); 590 r = match_hostname(original_host, arg) == 1; 591 if (r == (negate ? 1 : 0)) 592 this_result = result = 0; 593 } else if (strcasecmp(attrib, "user") == 0) { 594 criteria = xstrdup(ruser); 595 r = match_pattern_list(ruser, arg, 0) == 1; 596 if (r == (negate ? 1 : 0)) 597 this_result = result = 0; 598 } else if (strcasecmp(attrib, "localuser") == 0) { 599 criteria = xstrdup(pw->pw_name); 600 r = match_pattern_list(pw->pw_name, arg, 0) == 1; 601 if (r == (negate ? 1 : 0)) 602 this_result = result = 0; 603 } else if (strcasecmp(attrib, "exec") == 0) { 604 if (gethostname(thishost, sizeof(thishost)) == -1) 605 fatal("gethostname: %s", strerror(errno)); 606 strlcpy(shorthost, thishost, sizeof(shorthost)); 607 shorthost[strcspn(thishost, ".")] = '\0'; 608 snprintf(portstr, sizeof(portstr), "%d", port); 609 610 cmd = percent_expand(arg, 611 "L", shorthost, 612 "d", pw->pw_dir, 613 "h", host, 614 "l", thishost, 615 "n", original_host, 616 "p", portstr, 617 "r", ruser, 618 "u", pw->pw_name, 619 (char *)NULL); 620 if (result != 1) { 621 /* skip execution if prior predicate failed */ 622 debug3("%.200s line %d: skipped exec " 623 "\"%.100s\"", filename, linenum, cmd); 624 free(cmd); 625 continue; 626 } 627 r = execute_in_shell(cmd); 628 if (r == -1) { 629 fatal("%.200s line %d: match exec " 630 "'%.100s' error", filename, 631 linenum, cmd); 632 } 633 criteria = xstrdup(cmd); 634 free(cmd); 635 /* Force exit status to boolean */ 636 r = r == 0; 637 if (r == (negate ? 1 : 0)) 638 this_result = result = 0; 639 } else { 640 error("Unsupported Match attribute %s", attrib); 641 result = -1; 642 goto out; 643 } 644 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", 645 filename, linenum, this_result ? "": "not ", 646 oattrib, criteria); 647 free(criteria); 648 } 649 if (attributes == 0) { 650 error("One or more attributes required for Match"); 651 result = -1; 652 goto out; 653 } 654 out: 655 if (result != -1) 656 debug2("match %sfound", result ? "" : "not "); 657 *condition = cp; 658 free(host); 659 return result; 660 } 661 662 /* Check and prepare a domain name: removes trailing '.' and lowercases */ 663 static void 664 valid_domain(char *name, const char *filename, int linenum) 665 { 666 size_t i, l = strlen(name); 667 u_char c, last = '\0'; 668 669 if (l == 0) 670 fatal("%s line %d: empty hostname suffix", filename, linenum); 671 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) 672 fatal("%s line %d: hostname suffix \"%.100s\" " 673 "starts with invalid character", filename, linenum, name); 674 for (i = 0; i < l; i++) { 675 c = tolower((u_char)name[i]); 676 name[i] = (char)c; 677 if (last == '.' && c == '.') 678 fatal("%s line %d: hostname suffix \"%.100s\" contains " 679 "consecutive separators", filename, linenum, name); 680 if (c != '.' && c != '-' && !isalnum(c) && 681 c != '_') /* technically invalid, but common */ 682 fatal("%s line %d: hostname suffix \"%.100s\" contains " 683 "invalid characters", filename, linenum, name); 684 last = c; 685 } 686 if (name[l - 1] == '.') 687 name[l - 1] = '\0'; 688 } 689 690 /* 691 * Returns the number of the token pointed to by cp or oBadOption. 692 */ 693 static OpCodes 694 parse_token(const char *cp, const char *filename, int linenum, 695 const char *ignored_unknown) 696 { 697 int i; 698 699 for (i = 0; keywords[i].name; i++) 700 if (strcmp(cp, keywords[i].name) == 0) 701 return keywords[i].opcode; 702 if (ignored_unknown != NULL && 703 match_pattern_list(cp, ignored_unknown, 1) == 1) 704 return oIgnoredUnknownOption; 705 error("%s: line %d: Bad configuration option: %s", 706 filename, linenum, cp); 707 return oBadOption; 708 } 709 710 /* Multistate option parsing */ 711 struct multistate { 712 char *key; 713 int value; 714 }; 715 static const struct multistate multistate_flag[] = { 716 { "true", 1 }, 717 { "false", 0 }, 718 { "yes", 1 }, 719 { "no", 0 }, 720 { NULL, -1 } 721 }; 722 static const struct multistate multistate_yesnoask[] = { 723 { "true", 1 }, 724 { "false", 0 }, 725 { "yes", 1 }, 726 { "no", 0 }, 727 { "ask", 2 }, 728 { NULL, -1 } 729 }; 730 static const struct multistate multistate_yesnoaskconfirm[] = { 731 { "true", 1 }, 732 { "false", 0 }, 733 { "yes", 1 }, 734 { "no", 0 }, 735 { "ask", 2 }, 736 { "confirm", 3 }, 737 { NULL, -1 } 738 }; 739 static const struct multistate multistate_addressfamily[] = { 740 { "inet", AF_INET }, 741 { "inet6", AF_INET6 }, 742 { "any", AF_UNSPEC }, 743 { NULL, -1 } 744 }; 745 static const struct multistate multistate_controlmaster[] = { 746 { "true", SSHCTL_MASTER_YES }, 747 { "yes", SSHCTL_MASTER_YES }, 748 { "false", SSHCTL_MASTER_NO }, 749 { "no", SSHCTL_MASTER_NO }, 750 { "auto", SSHCTL_MASTER_AUTO }, 751 { "ask", SSHCTL_MASTER_ASK }, 752 { "autoask", SSHCTL_MASTER_AUTO_ASK }, 753 { NULL, -1 } 754 }; 755 static const struct multistate multistate_tunnel[] = { 756 { "ethernet", SSH_TUNMODE_ETHERNET }, 757 { "point-to-point", SSH_TUNMODE_POINTOPOINT }, 758 { "true", SSH_TUNMODE_DEFAULT }, 759 { "yes", SSH_TUNMODE_DEFAULT }, 760 { "false", SSH_TUNMODE_NO }, 761 { "no", SSH_TUNMODE_NO }, 762 { NULL, -1 } 763 }; 764 static const struct multistate multistate_requesttty[] = { 765 { "true", REQUEST_TTY_YES }, 766 { "yes", REQUEST_TTY_YES }, 767 { "false", REQUEST_TTY_NO }, 768 { "no", REQUEST_TTY_NO }, 769 { "force", REQUEST_TTY_FORCE }, 770 { "auto", REQUEST_TTY_AUTO }, 771 { NULL, -1 } 772 }; 773 static const struct multistate multistate_canonicalizehostname[] = { 774 { "true", SSH_CANONICALISE_YES }, 775 { "false", SSH_CANONICALISE_NO }, 776 { "yes", SSH_CANONICALISE_YES }, 777 { "no", SSH_CANONICALISE_NO }, 778 { "always", SSH_CANONICALISE_ALWAYS }, 779 { NULL, -1 } 780 }; 781 782 /* 783 * Processes a single option line as used in the configuration files. This 784 * only sets those values that have not already been set. 785 */ 786 int 787 process_config_line(Options *options, struct passwd *pw, const char *host, 788 const char *original_host, char *line, const char *filename, 789 int linenum, int *activep, int flags) 790 { 791 return process_config_line_depth(options, pw, host, original_host, 792 line, filename, linenum, activep, flags, 0); 793 } 794 795 #define WHITESPACE " \t\r\n" 796 static int 797 process_config_line_depth(Options *options, struct passwd *pw, const char *host, 798 const char *original_host, char *line, const char *filename, 799 int linenum, int *activep, int flags, int depth) 800 { 801 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 802 char **cpptr, fwdarg[256]; 803 u_int i, *uintptr, max_entries = 0; 804 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; 805 LogLevel *log_level_ptr; 806 long long val64; 807 size_t len; 808 struct Forward fwd; 809 const struct multistate *multistate_ptr; 810 struct allowed_cname *cname; 811 glob_t gl; 812 813 if (activep == NULL) { /* We are processing a command line directive */ 814 cmdline = 1; 815 activep = &cmdline; 816 } 817 818 /* Strip trailing whitespace */ 819 if ((len = strlen(line)) == 0) 820 return 0; 821 for (len--; len > 0; len--) { 822 if (strchr(WHITESPACE, line[len]) == NULL) 823 break; 824 line[len] = '\0'; 825 } 826 827 s = line; 828 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 829 if ((keyword = strdelim(&s)) == NULL) 830 return 0; 831 /* Ignore leading whitespace. */ 832 if (*keyword == '\0') 833 keyword = strdelim(&s); 834 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 835 return 0; 836 /* Match lowercase keyword */ 837 lowercase(keyword); 838 839 opcode = parse_token(keyword, filename, linenum, 840 options->ignored_unknown); 841 842 switch (opcode) { 843 case oBadOption: 844 /* don't panic, but count bad options */ 845 return -1; 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 /* Ignore ProxyCommand if ProxyJump already specified */ 1110 if (options->jump_host != NULL) 1111 charptr = &options->jump_host; /* Skip below */ 1112 parse_command: 1113 if (s == NULL) 1114 fatal("%.200s line %d: Missing argument.", filename, linenum); 1115 len = strspn(s, WHITESPACE "="); 1116 if (*activep && *charptr == NULL) 1117 *charptr = xstrdup(s + len); 1118 return 0; 1119 1120 case oProxyJump: 1121 if (s == NULL) { 1122 fatal("%.200s line %d: Missing argument.", 1123 filename, linenum); 1124 } 1125 len = strspn(s, WHITESPACE "="); 1126 if (parse_jump(s + len, options, *activep) == -1) { 1127 fatal("%.200s line %d: Invalid ProxyJump \"%s\"", 1128 filename, linenum, s + len); 1129 } 1130 return 0; 1131 1132 case oPort: 1133 intptr = &options->port; 1134 parse_int: 1135 arg = strdelim(&s); 1136 if (!arg || *arg == '\0') 1137 fatal("%.200s line %d: Missing argument.", filename, linenum); 1138 if (arg[0] < '0' || arg[0] > '9') 1139 fatal("%.200s line %d: Bad number.", filename, linenum); 1140 1141 /* Octal, decimal, or hex format? */ 1142 value = strtol(arg, &endofnumber, 0); 1143 if (arg == endofnumber) 1144 fatal("%.200s line %d: Bad number.", filename, linenum); 1145 if (*activep && *intptr == -1) 1146 *intptr = value; 1147 break; 1148 1149 case oConnectionAttempts: 1150 intptr = &options->connection_attempts; 1151 goto parse_int; 1152 1153 case oCipher: 1154 intptr = &options->cipher; 1155 arg = strdelim(&s); 1156 if (!arg || *arg == '\0') 1157 fatal("%.200s line %d: Missing argument.", filename, linenum); 1158 value = cipher_number(arg); 1159 if (value == -1) 1160 fatal("%.200s line %d: Bad cipher '%s'.", 1161 filename, linenum, arg ? arg : "<NONE>"); 1162 if (*activep && *intptr == -1) 1163 *intptr = value; 1164 break; 1165 1166 case oCiphers: 1167 arg = strdelim(&s); 1168 if (!arg || *arg == '\0') 1169 fatal("%.200s line %d: Missing argument.", filename, linenum); 1170 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) 1171 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 1172 filename, linenum, arg ? arg : "<NONE>"); 1173 if (*activep && options->ciphers == NULL) 1174 options->ciphers = xstrdup(arg); 1175 break; 1176 1177 case oMacs: 1178 arg = strdelim(&s); 1179 if (!arg || *arg == '\0') 1180 fatal("%.200s line %d: Missing argument.", filename, linenum); 1181 if (!mac_valid(*arg == '+' ? arg + 1 : arg)) 1182 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 1183 filename, linenum, arg ? arg : "<NONE>"); 1184 if (*activep && options->macs == NULL) 1185 options->macs = xstrdup(arg); 1186 break; 1187 1188 case oKexAlgorithms: 1189 arg = strdelim(&s); 1190 if (!arg || *arg == '\0') 1191 fatal("%.200s line %d: Missing argument.", 1192 filename, linenum); 1193 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) 1194 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 1195 filename, linenum, arg ? arg : "<NONE>"); 1196 if (*activep && options->kex_algorithms == NULL) 1197 options->kex_algorithms = xstrdup(arg); 1198 break; 1199 1200 case oHostKeyAlgorithms: 1201 charptr = &options->hostkeyalgorithms; 1202 parse_keytypes: 1203 arg = strdelim(&s); 1204 if (!arg || *arg == '\0') 1205 fatal("%.200s line %d: Missing argument.", 1206 filename, linenum); 1207 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) 1208 fatal("%s line %d: Bad key types '%s'.", 1209 filename, linenum, arg ? arg : "<NONE>"); 1210 if (*activep && *charptr == NULL) 1211 *charptr = xstrdup(arg); 1212 break; 1213 1214 case oProtocol: 1215 intptr = &options->protocol; 1216 arg = strdelim(&s); 1217 if (!arg || *arg == '\0') 1218 fatal("%.200s line %d: Missing argument.", filename, linenum); 1219 value = proto_spec(arg); 1220 if (value == SSH_PROTO_UNKNOWN) 1221 fatal("%.200s line %d: Bad protocol spec '%s'.", 1222 filename, linenum, arg ? arg : "<NONE>"); 1223 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 1224 *intptr = value; 1225 break; 1226 1227 case oLogLevel: 1228 log_level_ptr = &options->log_level; 1229 arg = strdelim(&s); 1230 value = log_level_number(arg); 1231 if (value == SYSLOG_LEVEL_NOT_SET) 1232 fatal("%.200s line %d: unsupported log level '%s'", 1233 filename, linenum, arg ? arg : "<NONE>"); 1234 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 1235 *log_level_ptr = (LogLevel) value; 1236 break; 1237 1238 case oLocalForward: 1239 case oRemoteForward: 1240 case oDynamicForward: 1241 arg = strdelim(&s); 1242 if (arg == NULL || *arg == '\0') 1243 fatal("%.200s line %d: Missing port argument.", 1244 filename, linenum); 1245 1246 if (opcode == oLocalForward || 1247 opcode == oRemoteForward) { 1248 arg2 = strdelim(&s); 1249 if (arg2 == NULL || *arg2 == '\0') 1250 fatal("%.200s line %d: Missing target argument.", 1251 filename, linenum); 1252 1253 /* construct a string for parse_forward */ 1254 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 1255 } else if (opcode == oDynamicForward) { 1256 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1257 } 1258 1259 if (parse_forward(&fwd, fwdarg, 1260 opcode == oDynamicForward ? 1 : 0, 1261 opcode == oRemoteForward ? 1 : 0) == 0) 1262 fatal("%.200s line %d: Bad forwarding specification.", 1263 filename, linenum); 1264 1265 if (*activep) { 1266 if (opcode == oLocalForward || 1267 opcode == oDynamicForward) 1268 add_local_forward(options, &fwd); 1269 else if (opcode == oRemoteForward) 1270 add_remote_forward(options, &fwd); 1271 } 1272 break; 1273 1274 case oClearAllForwardings: 1275 intptr = &options->clear_forwardings; 1276 goto parse_flag; 1277 1278 case oHost: 1279 if (cmdline) 1280 fatal("Host directive not supported as a command-line " 1281 "option"); 1282 *activep = 0; 1283 arg2 = NULL; 1284 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1285 if ((flags & SSHCONF_NEVERMATCH) != 0) 1286 break; 1287 negated = *arg == '!'; 1288 if (negated) 1289 arg++; 1290 if (match_pattern(host, arg)) { 1291 if (negated) { 1292 debug("%.200s line %d: Skipping Host " 1293 "block because of negated match " 1294 "for %.100s", filename, linenum, 1295 arg); 1296 *activep = 0; 1297 break; 1298 } 1299 if (!*activep) 1300 arg2 = arg; /* logged below */ 1301 *activep = 1; 1302 } 1303 } 1304 if (*activep) 1305 debug("%.200s line %d: Applying options for %.100s", 1306 filename, linenum, arg2); 1307 /* Avoid garbage check below, as strdelim is done. */ 1308 return 0; 1309 1310 case oMatch: 1311 if (cmdline) 1312 fatal("Host directive not supported as a command-line " 1313 "option"); 1314 value = match_cfg_line(options, &s, pw, host, original_host, 1315 flags & SSHCONF_POSTCANON, filename, linenum); 1316 if (value < 0) 1317 fatal("%.200s line %d: Bad Match condition", filename, 1318 linenum); 1319 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; 1320 break; 1321 1322 case oEscapeChar: 1323 intptr = &options->escape_char; 1324 arg = strdelim(&s); 1325 if (!arg || *arg == '\0') 1326 fatal("%.200s line %d: Missing argument.", filename, linenum); 1327 if (strcmp(arg, "none") == 0) 1328 value = SSH_ESCAPECHAR_NONE; 1329 else if (arg[1] == '\0') 1330 value = (u_char) arg[0]; 1331 else if (arg[0] == '^' && arg[2] == 0 && 1332 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 1333 value = (u_char) arg[1] & 31; 1334 else { 1335 fatal("%.200s line %d: Bad escape character.", 1336 filename, linenum); 1337 /* NOTREACHED */ 1338 value = 0; /* Avoid compiler warning. */ 1339 } 1340 if (*activep && *intptr == -1) 1341 *intptr = value; 1342 break; 1343 1344 case oAddressFamily: 1345 intptr = &options->address_family; 1346 multistate_ptr = multistate_addressfamily; 1347 goto parse_multistate; 1348 1349 case oEnableSSHKeysign: 1350 intptr = &options->enable_ssh_keysign; 1351 goto parse_flag; 1352 1353 case oIdentitiesOnly: 1354 intptr = &options->identities_only; 1355 goto parse_flag; 1356 1357 case oServerAliveInterval: 1358 intptr = &options->server_alive_interval; 1359 goto parse_time; 1360 1361 case oServerAliveCountMax: 1362 intptr = &options->server_alive_count_max; 1363 goto parse_int; 1364 1365 case oSendEnv: 1366 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1367 if (strchr(arg, '=') != NULL) 1368 fatal("%s line %d: Invalid environment name.", 1369 filename, linenum); 1370 if (!*activep) 1371 continue; 1372 if (options->num_send_env >= MAX_SEND_ENV) 1373 fatal("%s line %d: too many send env.", 1374 filename, linenum); 1375 options->send_env[options->num_send_env++] = 1376 xstrdup(arg); 1377 } 1378 break; 1379 1380 case oControlPath: 1381 charptr = &options->control_path; 1382 goto parse_string; 1383 1384 case oControlMaster: 1385 intptr = &options->control_master; 1386 multistate_ptr = multistate_controlmaster; 1387 goto parse_multistate; 1388 1389 case oControlPersist: 1390 /* no/false/yes/true, or a time spec */ 1391 intptr = &options->control_persist; 1392 arg = strdelim(&s); 1393 if (!arg || *arg == '\0') 1394 fatal("%.200s line %d: Missing ControlPersist" 1395 " argument.", filename, linenum); 1396 value = 0; 1397 value2 = 0; /* timeout */ 1398 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 1399 value = 0; 1400 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 1401 value = 1; 1402 else if ((value2 = convtime(arg)) >= 0) 1403 value = 1; 1404 else 1405 fatal("%.200s line %d: Bad ControlPersist argument.", 1406 filename, linenum); 1407 if (*activep && *intptr == -1) { 1408 *intptr = value; 1409 options->control_persist_timeout = value2; 1410 } 1411 break; 1412 1413 case oHashKnownHosts: 1414 intptr = &options->hash_known_hosts; 1415 goto parse_flag; 1416 1417 case oTunnel: 1418 intptr = &options->tun_open; 1419 multistate_ptr = multistate_tunnel; 1420 goto parse_multistate; 1421 1422 case oTunnelDevice: 1423 arg = strdelim(&s); 1424 if (!arg || *arg == '\0') 1425 fatal("%.200s line %d: Missing argument.", filename, linenum); 1426 value = a2tun(arg, &value2); 1427 if (value == SSH_TUNID_ERR) 1428 fatal("%.200s line %d: Bad tun device.", filename, linenum); 1429 if (*activep) { 1430 options->tun_local = value; 1431 options->tun_remote = value2; 1432 } 1433 break; 1434 1435 case oLocalCommand: 1436 charptr = &options->local_command; 1437 goto parse_command; 1438 1439 case oPermitLocalCommand: 1440 intptr = &options->permit_local_command; 1441 goto parse_flag; 1442 1443 case oVisualHostKey: 1444 intptr = &options->visual_host_key; 1445 goto parse_flag; 1446 1447 case oInclude: 1448 if (cmdline) 1449 fatal("Include directive not supported as a " 1450 "command-line option"); 1451 value = 0; 1452 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1453 /* 1454 * Ensure all paths are anchored. User configuration 1455 * files may begin with '~/' but system configurations 1456 * must not. If the path is relative, then treat it 1457 * as living in ~/.ssh for user configurations or 1458 * /etc/ssh for system ones. 1459 */ 1460 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) 1461 fatal("%.200s line %d: bad include path %s.", 1462 filename, linenum, arg); 1463 if (*arg != '/' && *arg != '~') { 1464 xasprintf(&arg2, "%s/%s", 1465 (flags & SSHCONF_USERCONF) ? 1466 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg); 1467 } else 1468 arg2 = xstrdup(arg); 1469 memset(&gl, 0, sizeof(gl)); 1470 r = glob(arg2, GLOB_TILDE, NULL, &gl); 1471 if (r == GLOB_NOMATCH) { 1472 debug("%.200s line %d: include %s matched no " 1473 "files",filename, linenum, arg2); 1474 continue; 1475 } else if (r != 0 || gl.gl_pathc < 0) 1476 fatal("%.200s line %d: glob failed for %s.", 1477 filename, linenum, arg2); 1478 free(arg2); 1479 oactive = *activep; 1480 for (i = 0; i < (u_int)gl.gl_pathc; i++) { 1481 debug3("%.200s line %d: Including file %s " 1482 "depth %d%s", filename, linenum, 1483 gl.gl_pathv[i], depth, 1484 oactive ? "" : " (parse only)"); 1485 r = read_config_file_depth(gl.gl_pathv[i], 1486 pw, host, original_host, options, 1487 flags | SSHCONF_CHECKPERM | 1488 (oactive ? 0 : SSHCONF_NEVERMATCH), 1489 activep, depth + 1); 1490 /* 1491 * don't let Match in includes clobber the 1492 * containing file's Match state. 1493 */ 1494 *activep = oactive; 1495 if (r != 1) 1496 value = -1; 1497 } 1498 globfree(&gl); 1499 } 1500 if (value != 0) 1501 return value; 1502 break; 1503 1504 case oIPQoS: 1505 arg = strdelim(&s); 1506 if ((value = parse_ipqos(arg)) == -1) 1507 fatal("%s line %d: Bad IPQoS value: %s", 1508 filename, linenum, arg); 1509 arg = strdelim(&s); 1510 if (arg == NULL) 1511 value2 = value; 1512 else if ((value2 = parse_ipqos(arg)) == -1) 1513 fatal("%s line %d: Bad IPQoS value: %s", 1514 filename, linenum, arg); 1515 if (*activep) { 1516 options->ip_qos_interactive = value; 1517 options->ip_qos_bulk = value2; 1518 } 1519 break; 1520 1521 case oRequestTTY: 1522 intptr = &options->request_tty; 1523 multistate_ptr = multistate_requesttty; 1524 goto parse_multistate; 1525 1526 case oIgnoreUnknown: 1527 charptr = &options->ignored_unknown; 1528 goto parse_string; 1529 1530 case oProxyUseFdpass: 1531 intptr = &options->proxy_use_fdpass; 1532 goto parse_flag; 1533 1534 case oCanonicalDomains: 1535 value = options->num_canonical_domains != 0; 1536 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1537 valid_domain(arg, filename, linenum); 1538 if (!*activep || value) 1539 continue; 1540 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1541 fatal("%s line %d: too many hostname suffixes.", 1542 filename, linenum); 1543 options->canonical_domains[ 1544 options->num_canonical_domains++] = xstrdup(arg); 1545 } 1546 break; 1547 1548 case oCanonicalizePermittedCNAMEs: 1549 value = options->num_permitted_cnames != 0; 1550 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1551 /* Either '*' for everything or 'list:list' */ 1552 if (strcmp(arg, "*") == 0) 1553 arg2 = arg; 1554 else { 1555 lowercase(arg); 1556 if ((arg2 = strchr(arg, ':')) == NULL || 1557 arg2[1] == '\0') { 1558 fatal("%s line %d: " 1559 "Invalid permitted CNAME \"%s\"", 1560 filename, linenum, arg); 1561 } 1562 *arg2 = '\0'; 1563 arg2++; 1564 } 1565 if (!*activep || value) 1566 continue; 1567 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1568 fatal("%s line %d: too many permitted CNAMEs.", 1569 filename, linenum); 1570 cname = options->permitted_cnames + 1571 options->num_permitted_cnames++; 1572 cname->source_list = xstrdup(arg); 1573 cname->target_list = xstrdup(arg2); 1574 } 1575 break; 1576 1577 case oCanonicalizeHostname: 1578 intptr = &options->canonicalize_hostname; 1579 multistate_ptr = multistate_canonicalizehostname; 1580 goto parse_multistate; 1581 1582 case oCanonicalizeMaxDots: 1583 intptr = &options->canonicalize_max_dots; 1584 goto parse_int; 1585 1586 case oCanonicalizeFallbackLocal: 1587 intptr = &options->canonicalize_fallback_local; 1588 goto parse_flag; 1589 1590 case oStreamLocalBindMask: 1591 arg = strdelim(&s); 1592 if (!arg || *arg == '\0') 1593 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); 1594 /* Parse mode in octal format */ 1595 value = strtol(arg, &endofnumber, 8); 1596 if (arg == endofnumber || value < 0 || value > 0777) 1597 fatal("%.200s line %d: Bad mask.", filename, linenum); 1598 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1599 break; 1600 1601 case oStreamLocalBindUnlink: 1602 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1603 goto parse_flag; 1604 1605 case oRevokedHostKeys: 1606 charptr = &options->revoked_host_keys; 1607 goto parse_string; 1608 1609 case oFingerprintHash: 1610 intptr = &options->fingerprint_hash; 1611 arg = strdelim(&s); 1612 if (!arg || *arg == '\0') 1613 fatal("%.200s line %d: Missing argument.", 1614 filename, linenum); 1615 if ((value = ssh_digest_alg_by_name(arg)) == -1) 1616 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1617 filename, linenum, arg); 1618 if (*activep && *intptr == -1) 1619 *intptr = value; 1620 break; 1621 1622 case oUpdateHostkeys: 1623 intptr = &options->update_hostkeys; 1624 multistate_ptr = multistate_yesnoask; 1625 goto parse_multistate; 1626 1627 case oHostbasedKeyTypes: 1628 charptr = &options->hostbased_key_types; 1629 goto parse_keytypes; 1630 1631 case oPubkeyAcceptedKeyTypes: 1632 charptr = &options->pubkey_key_types; 1633 goto parse_keytypes; 1634 1635 case oAddKeysToAgent: 1636 intptr = &options->add_keys_to_agent; 1637 multistate_ptr = multistate_yesnoaskconfirm; 1638 goto parse_multistate; 1639 1640 case oIdentityAgent: 1641 charptr = &options->identity_agent; 1642 goto parse_string; 1643 1644 case oDeprecated: 1645 debug("%s line %d: Deprecated option \"%s\"", 1646 filename, linenum, keyword); 1647 return 0; 1648 1649 case oUnsupported: 1650 error("%s line %d: Unsupported option \"%s\"", 1651 filename, linenum, keyword); 1652 return 0; 1653 1654 default: 1655 fatal("%s: Unimplemented opcode %d", __func__, opcode); 1656 } 1657 1658 /* Check that there is no garbage at end of line. */ 1659 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1660 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1661 filename, linenum, arg); 1662 } 1663 return 0; 1664 } 1665 1666 /* 1667 * Reads the config file and modifies the options accordingly. Options 1668 * should already be initialized before this call. This never returns if 1669 * there is an error. If the file does not exist, this returns 0. 1670 */ 1671 int 1672 read_config_file(const char *filename, struct passwd *pw, const char *host, 1673 const char *original_host, Options *options, int flags) 1674 { 1675 int active = 1; 1676 1677 return read_config_file_depth(filename, pw, host, original_host, 1678 options, flags, &active, 0); 1679 } 1680 1681 #define READCONF_MAX_DEPTH 16 1682 static int 1683 read_config_file_depth(const char *filename, struct passwd *pw, 1684 const char *host, const char *original_host, Options *options, 1685 int flags, int *activep, int depth) 1686 { 1687 FILE *f; 1688 char line[1024]; 1689 int linenum; 1690 int bad_options = 0; 1691 1692 if (depth < 0 || depth > READCONF_MAX_DEPTH) 1693 fatal("Too many recursive configuration includes"); 1694 1695 if ((f = fopen(filename, "r")) == NULL) 1696 return 0; 1697 1698 if (flags & SSHCONF_CHECKPERM) { 1699 struct stat sb; 1700 1701 if (fstat(fileno(f), &sb) == -1) 1702 fatal("fstat %s: %s", filename, strerror(errno)); 1703 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 1704 (sb.st_mode & 022) != 0)) 1705 fatal("Bad owner or permissions on %s", filename); 1706 } 1707 1708 debug("Reading configuration data %.200s", filename); 1709 1710 /* 1711 * Mark that we are now processing the options. This flag is turned 1712 * on/off by Host specifications. 1713 */ 1714 linenum = 0; 1715 while (fgets(line, sizeof(line), f)) { 1716 /* Update line number counter. */ 1717 linenum++; 1718 if (process_config_line_depth(options, pw, host, original_host, 1719 line, filename, linenum, activep, flags, depth) != 0) 1720 bad_options++; 1721 } 1722 fclose(f); 1723 if (bad_options > 0) 1724 fatal("%s: terminating, %d bad configuration options", 1725 filename, bad_options); 1726 return 1; 1727 } 1728 1729 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 1730 int 1731 option_clear_or_none(const char *o) 1732 { 1733 return o == NULL || strcasecmp(o, "none") == 0; 1734 } 1735 1736 /* 1737 * Initializes options to special values that indicate that they have not yet 1738 * been set. Read_config_file will only set options with this value. Options 1739 * are processed in the following order: command line, user config file, 1740 * system config file. Last, fill_default_options is called. 1741 */ 1742 1743 void 1744 initialize_options(Options * options) 1745 { 1746 memset(options, 'X', sizeof(*options)); 1747 options->forward_agent = -1; 1748 options->forward_x11 = -1; 1749 options->forward_x11_trusted = -1; 1750 options->forward_x11_timeout = -1; 1751 options->stdio_forward_host = NULL; 1752 options->stdio_forward_port = 0; 1753 options->clear_forwardings = -1; 1754 options->exit_on_forward_failure = -1; 1755 options->xauth_location = NULL; 1756 options->fwd_opts.gateway_ports = -1; 1757 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 1758 options->fwd_opts.streamlocal_bind_unlink = -1; 1759 options->use_privileged_port = -1; 1760 options->rsa_authentication = -1; 1761 options->pubkey_authentication = -1; 1762 options->challenge_response_authentication = -1; 1763 options->gss_authentication = -1; 1764 options->gss_deleg_creds = -1; 1765 options->password_authentication = -1; 1766 options->kbd_interactive_authentication = -1; 1767 options->kbd_interactive_devices = NULL; 1768 options->rhosts_rsa_authentication = -1; 1769 options->hostbased_authentication = -1; 1770 options->batch_mode = -1; 1771 options->check_host_ip = -1; 1772 options->strict_host_key_checking = -1; 1773 options->compression = -1; 1774 options->tcp_keep_alive = -1; 1775 options->compression_level = -1; 1776 options->port = -1; 1777 options->address_family = -1; 1778 options->connection_attempts = -1; 1779 options->connection_timeout = -1; 1780 options->number_of_password_prompts = -1; 1781 options->cipher = -1; 1782 options->ciphers = NULL; 1783 options->macs = NULL; 1784 options->kex_algorithms = NULL; 1785 options->hostkeyalgorithms = NULL; 1786 options->protocol = SSH_PROTO_UNKNOWN; 1787 options->num_identity_files = 0; 1788 options->num_certificate_files = 0; 1789 options->hostname = NULL; 1790 options->host_key_alias = NULL; 1791 options->proxy_command = NULL; 1792 options->jump_user = NULL; 1793 options->jump_host = NULL; 1794 options->jump_port = -1; 1795 options->jump_extra = NULL; 1796 options->user = NULL; 1797 options->escape_char = -1; 1798 options->num_system_hostfiles = 0; 1799 options->num_user_hostfiles = 0; 1800 options->local_forwards = NULL; 1801 options->num_local_forwards = 0; 1802 options->remote_forwards = NULL; 1803 options->num_remote_forwards = 0; 1804 options->log_level = SYSLOG_LEVEL_NOT_SET; 1805 options->preferred_authentications = NULL; 1806 options->bind_address = NULL; 1807 options->pkcs11_provider = NULL; 1808 options->enable_ssh_keysign = - 1; 1809 options->no_host_authentication_for_localhost = - 1; 1810 options->identities_only = - 1; 1811 options->rekey_limit = - 1; 1812 options->rekey_interval = -1; 1813 options->verify_host_key_dns = -1; 1814 options->server_alive_interval = -1; 1815 options->server_alive_count_max = -1; 1816 options->num_send_env = 0; 1817 options->control_path = NULL; 1818 options->control_master = -1; 1819 options->control_persist = -1; 1820 options->control_persist_timeout = 0; 1821 options->hash_known_hosts = -1; 1822 options->tun_open = -1; 1823 options->tun_local = -1; 1824 options->tun_remote = -1; 1825 options->local_command = NULL; 1826 options->permit_local_command = -1; 1827 options->add_keys_to_agent = -1; 1828 options->identity_agent = NULL; 1829 options->visual_host_key = -1; 1830 options->ip_qos_interactive = -1; 1831 options->ip_qos_bulk = -1; 1832 options->request_tty = -1; 1833 options->proxy_use_fdpass = -1; 1834 options->ignored_unknown = NULL; 1835 options->num_canonical_domains = 0; 1836 options->num_permitted_cnames = 0; 1837 options->canonicalize_max_dots = -1; 1838 options->canonicalize_fallback_local = -1; 1839 options->canonicalize_hostname = -1; 1840 options->revoked_host_keys = NULL; 1841 options->fingerprint_hash = -1; 1842 options->update_hostkeys = -1; 1843 options->hostbased_key_types = NULL; 1844 options->pubkey_key_types = NULL; 1845 } 1846 1847 /* 1848 * A petite version of fill_default_options() that just fills the options 1849 * needed for hostname canonicalization to proceed. 1850 */ 1851 void 1852 fill_default_options_for_canonicalization(Options *options) 1853 { 1854 if (options->canonicalize_max_dots == -1) 1855 options->canonicalize_max_dots = 1; 1856 if (options->canonicalize_fallback_local == -1) 1857 options->canonicalize_fallback_local = 1; 1858 if (options->canonicalize_hostname == -1) 1859 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1860 } 1861 1862 /* 1863 * Called after processing other sources of option data, this fills those 1864 * options for which no value has been specified with their default values. 1865 */ 1866 void 1867 fill_default_options(Options * options) 1868 { 1869 if (options->forward_agent == -1) 1870 options->forward_agent = 0; 1871 if (options->forward_x11 == -1) 1872 options->forward_x11 = 0; 1873 if (options->forward_x11_trusted == -1) 1874 options->forward_x11_trusted = 0; 1875 if (options->forward_x11_timeout == -1) 1876 options->forward_x11_timeout = 1200; 1877 /* 1878 * stdio forwarding (-W) changes the default for these but we defer 1879 * setting the values so they can be overridden. 1880 */ 1881 if (options->exit_on_forward_failure == -1) 1882 options->exit_on_forward_failure = 1883 options->stdio_forward_host != NULL ? 1 : 0; 1884 if (options->clear_forwardings == -1) 1885 options->clear_forwardings = 1886 options->stdio_forward_host != NULL ? 1 : 0; 1887 if (options->clear_forwardings == 1) 1888 clear_forwardings(options); 1889 1890 if (options->xauth_location == NULL) 1891 options->xauth_location = _PATH_XAUTH; 1892 if (options->fwd_opts.gateway_ports == -1) 1893 options->fwd_opts.gateway_ports = 0; 1894 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 1895 options->fwd_opts.streamlocal_bind_mask = 0177; 1896 if (options->fwd_opts.streamlocal_bind_unlink == -1) 1897 options->fwd_opts.streamlocal_bind_unlink = 0; 1898 if (options->use_privileged_port == -1) 1899 options->use_privileged_port = 0; 1900 if (options->rsa_authentication == -1) 1901 options->rsa_authentication = 1; 1902 if (options->pubkey_authentication == -1) 1903 options->pubkey_authentication = 1; 1904 if (options->challenge_response_authentication == -1) 1905 options->challenge_response_authentication = 1; 1906 if (options->gss_authentication == -1) 1907 options->gss_authentication = 0; 1908 if (options->gss_deleg_creds == -1) 1909 options->gss_deleg_creds = 0; 1910 if (options->password_authentication == -1) 1911 options->password_authentication = 1; 1912 if (options->kbd_interactive_authentication == -1) 1913 options->kbd_interactive_authentication = 1; 1914 if (options->rhosts_rsa_authentication == -1) 1915 options->rhosts_rsa_authentication = 0; 1916 if (options->hostbased_authentication == -1) 1917 options->hostbased_authentication = 0; 1918 if (options->batch_mode == -1) 1919 options->batch_mode = 0; 1920 if (options->check_host_ip == -1) 1921 options->check_host_ip = 1; 1922 if (options->strict_host_key_checking == -1) 1923 options->strict_host_key_checking = 2; /* 2 is default */ 1924 if (options->compression == -1) 1925 options->compression = 0; 1926 if (options->tcp_keep_alive == -1) 1927 options->tcp_keep_alive = 1; 1928 if (options->compression_level == -1) 1929 options->compression_level = 6; 1930 if (options->port == -1) 1931 options->port = 0; /* Filled in ssh_connect. */ 1932 if (options->address_family == -1) 1933 options->address_family = AF_UNSPEC; 1934 if (options->connection_attempts == -1) 1935 options->connection_attempts = 1; 1936 if (options->number_of_password_prompts == -1) 1937 options->number_of_password_prompts = 3; 1938 /* Selected in ssh_login(). */ 1939 if (options->cipher == -1) 1940 options->cipher = SSH_CIPHER_NOT_SET; 1941 /* options->hostkeyalgorithms, default set in myproposals.h */ 1942 if (options->protocol == SSH_PROTO_UNKNOWN) 1943 options->protocol = SSH_PROTO_2; 1944 if (options->add_keys_to_agent == -1) 1945 options->add_keys_to_agent = 0; 1946 if (options->num_identity_files == 0) { 1947 if (options->protocol & SSH_PROTO_1) { 1948 add_identity_file(options, "~/", 1949 _PATH_SSH_CLIENT_IDENTITY, 0); 1950 } 1951 if (options->protocol & SSH_PROTO_2) { 1952 add_identity_file(options, "~/", 1953 _PATH_SSH_CLIENT_ID_RSA, 0); 1954 add_identity_file(options, "~/", 1955 _PATH_SSH_CLIENT_ID_DSA, 0); 1956 add_identity_file(options, "~/", 1957 _PATH_SSH_CLIENT_ID_ECDSA, 0); 1958 add_identity_file(options, "~/", 1959 _PATH_SSH_CLIENT_ID_ED25519, 0); 1960 } 1961 } 1962 if (options->escape_char == -1) 1963 options->escape_char = '~'; 1964 if (options->num_system_hostfiles == 0) { 1965 options->system_hostfiles[options->num_system_hostfiles++] = 1966 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1967 options->system_hostfiles[options->num_system_hostfiles++] = 1968 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1969 } 1970 if (options->num_user_hostfiles == 0) { 1971 options->user_hostfiles[options->num_user_hostfiles++] = 1972 xstrdup(_PATH_SSH_USER_HOSTFILE); 1973 options->user_hostfiles[options->num_user_hostfiles++] = 1974 xstrdup(_PATH_SSH_USER_HOSTFILE2); 1975 } 1976 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1977 options->log_level = SYSLOG_LEVEL_INFO; 1978 if (options->no_host_authentication_for_localhost == - 1) 1979 options->no_host_authentication_for_localhost = 0; 1980 if (options->identities_only == -1) 1981 options->identities_only = 0; 1982 if (options->enable_ssh_keysign == -1) 1983 options->enable_ssh_keysign = 0; 1984 if (options->rekey_limit == -1) 1985 options->rekey_limit = 0; 1986 if (options->rekey_interval == -1) 1987 options->rekey_interval = 0; 1988 if (options->verify_host_key_dns == -1) 1989 options->verify_host_key_dns = 0; 1990 if (options->server_alive_interval == -1) 1991 options->server_alive_interval = 0; 1992 if (options->server_alive_count_max == -1) 1993 options->server_alive_count_max = 3; 1994 if (options->control_master == -1) 1995 options->control_master = 0; 1996 if (options->control_persist == -1) { 1997 options->control_persist = 0; 1998 options->control_persist_timeout = 0; 1999 } 2000 if (options->hash_known_hosts == -1) 2001 options->hash_known_hosts = 0; 2002 if (options->tun_open == -1) 2003 options->tun_open = SSH_TUNMODE_NO; 2004 if (options->tun_local == -1) 2005 options->tun_local = SSH_TUNID_ANY; 2006 if (options->tun_remote == -1) 2007 options->tun_remote = SSH_TUNID_ANY; 2008 if (options->permit_local_command == -1) 2009 options->permit_local_command = 0; 2010 if (options->visual_host_key == -1) 2011 options->visual_host_key = 0; 2012 if (options->ip_qos_interactive == -1) 2013 options->ip_qos_interactive = IPTOS_LOWDELAY; 2014 if (options->ip_qos_bulk == -1) 2015 options->ip_qos_bulk = IPTOS_THROUGHPUT; 2016 if (options->request_tty == -1) 2017 options->request_tty = REQUEST_TTY_AUTO; 2018 if (options->proxy_use_fdpass == -1) 2019 options->proxy_use_fdpass = 0; 2020 if (options->canonicalize_max_dots == -1) 2021 options->canonicalize_max_dots = 1; 2022 if (options->canonicalize_fallback_local == -1) 2023 options->canonicalize_fallback_local = 1; 2024 if (options->canonicalize_hostname == -1) 2025 options->canonicalize_hostname = SSH_CANONICALISE_NO; 2026 if (options->fingerprint_hash == -1) 2027 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 2028 if (options->update_hostkeys == -1) 2029 options->update_hostkeys = 0; 2030 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || 2031 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || 2032 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || 2033 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2034 &options->hostbased_key_types) != 0 || 2035 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2036 &options->pubkey_key_types) != 0) 2037 fatal("%s: kex_assemble_names failed", __func__); 2038 2039 #define CLEAR_ON_NONE(v) \ 2040 do { \ 2041 if (option_clear_or_none(v)) { \ 2042 free(v); \ 2043 v = NULL; \ 2044 } \ 2045 } while(0) 2046 CLEAR_ON_NONE(options->local_command); 2047 CLEAR_ON_NONE(options->proxy_command); 2048 CLEAR_ON_NONE(options->control_path); 2049 CLEAR_ON_NONE(options->revoked_host_keys); 2050 /* options->identity_agent distinguishes NULL from 'none' */ 2051 /* options->user will be set in the main program if appropriate */ 2052 /* options->hostname will be set in the main program if appropriate */ 2053 /* options->host_key_alias should not be set by default */ 2054 /* options->preferred_authentications will be set in ssh */ 2055 } 2056 2057 struct fwdarg { 2058 char *arg; 2059 int ispath; 2060 }; 2061 2062 /* 2063 * parse_fwd_field 2064 * parses the next field in a port forwarding specification. 2065 * sets fwd to the parsed field and advances p past the colon 2066 * or sets it to NULL at end of string. 2067 * returns 0 on success, else non-zero. 2068 */ 2069 static int 2070 parse_fwd_field(char **p, struct fwdarg *fwd) 2071 { 2072 char *ep, *cp = *p; 2073 int ispath = 0; 2074 2075 if (*cp == '\0') { 2076 *p = NULL; 2077 return -1; /* end of string */ 2078 } 2079 2080 /* 2081 * A field escaped with square brackets is used literally. 2082 * XXX - allow ']' to be escaped via backslash? 2083 */ 2084 if (*cp == '[') { 2085 /* find matching ']' */ 2086 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { 2087 if (*ep == '/') 2088 ispath = 1; 2089 } 2090 /* no matching ']' or not at end of field. */ 2091 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) 2092 return -1; 2093 /* NUL terminate the field and advance p past the colon */ 2094 *ep++ = '\0'; 2095 if (*ep != '\0') 2096 *ep++ = '\0'; 2097 fwd->arg = cp + 1; 2098 fwd->ispath = ispath; 2099 *p = ep; 2100 return 0; 2101 } 2102 2103 for (cp = *p; *cp != '\0'; cp++) { 2104 switch (*cp) { 2105 case '\\': 2106 memmove(cp, cp + 1, strlen(cp + 1) + 1); 2107 if (*cp == '\0') 2108 return -1; 2109 break; 2110 case '/': 2111 ispath = 1; 2112 break; 2113 case ':': 2114 *cp++ = '\0'; 2115 goto done; 2116 } 2117 } 2118 done: 2119 fwd->arg = *p; 2120 fwd->ispath = ispath; 2121 *p = cp; 2122 return 0; 2123 } 2124 2125 /* 2126 * parse_forward 2127 * parses a string containing a port forwarding specification of the form: 2128 * dynamicfwd == 0 2129 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath 2130 * listenpath:connectpath 2131 * dynamicfwd == 1 2132 * [listenhost:]listenport 2133 * returns number of arguments parsed or zero on error 2134 */ 2135 int 2136 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 2137 { 2138 struct fwdarg fwdargs[4]; 2139 char *p, *cp; 2140 int i; 2141 2142 memset(fwd, 0, sizeof(*fwd)); 2143 memset(fwdargs, 0, sizeof(fwdargs)); 2144 2145 cp = p = xstrdup(fwdspec); 2146 2147 /* skip leading spaces */ 2148 while (isspace((u_char)*cp)) 2149 cp++; 2150 2151 for (i = 0; i < 4; ++i) { 2152 if (parse_fwd_field(&cp, &fwdargs[i]) != 0) 2153 break; 2154 } 2155 2156 /* Check for trailing garbage */ 2157 if (cp != NULL && *cp != '\0') { 2158 i = 0; /* failure */ 2159 } 2160 2161 switch (i) { 2162 case 1: 2163 if (fwdargs[0].ispath) { 2164 fwd->listen_path = xstrdup(fwdargs[0].arg); 2165 fwd->listen_port = PORT_STREAMLOCAL; 2166 } else { 2167 fwd->listen_host = NULL; 2168 fwd->listen_port = a2port(fwdargs[0].arg); 2169 } 2170 fwd->connect_host = xstrdup("socks"); 2171 break; 2172 2173 case 2: 2174 if (fwdargs[0].ispath && fwdargs[1].ispath) { 2175 fwd->listen_path = xstrdup(fwdargs[0].arg); 2176 fwd->listen_port = PORT_STREAMLOCAL; 2177 fwd->connect_path = xstrdup(fwdargs[1].arg); 2178 fwd->connect_port = PORT_STREAMLOCAL; 2179 } else if (fwdargs[1].ispath) { 2180 fwd->listen_host = NULL; 2181 fwd->listen_port = a2port(fwdargs[0].arg); 2182 fwd->connect_path = xstrdup(fwdargs[1].arg); 2183 fwd->connect_port = PORT_STREAMLOCAL; 2184 } else { 2185 fwd->listen_host = xstrdup(fwdargs[0].arg); 2186 fwd->listen_port = a2port(fwdargs[1].arg); 2187 fwd->connect_host = xstrdup("socks"); 2188 } 2189 break; 2190 2191 case 3: 2192 if (fwdargs[0].ispath) { 2193 fwd->listen_path = xstrdup(fwdargs[0].arg); 2194 fwd->listen_port = PORT_STREAMLOCAL; 2195 fwd->connect_host = xstrdup(fwdargs[1].arg); 2196 fwd->connect_port = a2port(fwdargs[2].arg); 2197 } else if (fwdargs[2].ispath) { 2198 fwd->listen_host = xstrdup(fwdargs[0].arg); 2199 fwd->listen_port = a2port(fwdargs[1].arg); 2200 fwd->connect_path = xstrdup(fwdargs[2].arg); 2201 fwd->connect_port = PORT_STREAMLOCAL; 2202 } else { 2203 fwd->listen_host = NULL; 2204 fwd->listen_port = a2port(fwdargs[0].arg); 2205 fwd->connect_host = xstrdup(fwdargs[1].arg); 2206 fwd->connect_port = a2port(fwdargs[2].arg); 2207 } 2208 break; 2209 2210 case 4: 2211 fwd->listen_host = xstrdup(fwdargs[0].arg); 2212 fwd->listen_port = a2port(fwdargs[1].arg); 2213 fwd->connect_host = xstrdup(fwdargs[2].arg); 2214 fwd->connect_port = a2port(fwdargs[3].arg); 2215 break; 2216 default: 2217 i = 0; /* failure */ 2218 } 2219 2220 free(p); 2221 2222 if (dynamicfwd) { 2223 if (!(i == 1 || i == 2)) 2224 goto fail_free; 2225 } else { 2226 if (!(i == 3 || i == 4)) { 2227 if (fwd->connect_path == NULL && 2228 fwd->listen_path == NULL) 2229 goto fail_free; 2230 } 2231 if (fwd->connect_port <= 0 && fwd->connect_path == NULL) 2232 goto fail_free; 2233 } 2234 2235 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || 2236 (!remotefwd && fwd->listen_port == 0)) 2237 goto fail_free; 2238 if (fwd->connect_host != NULL && 2239 strlen(fwd->connect_host) >= NI_MAXHOST) 2240 goto fail_free; 2241 /* XXX - if connecting to a remote socket, max sun len may not match this host */ 2242 if (fwd->connect_path != NULL && 2243 strlen(fwd->connect_path) >= PATH_MAX_SUN) 2244 goto fail_free; 2245 if (fwd->listen_host != NULL && 2246 strlen(fwd->listen_host) >= NI_MAXHOST) 2247 goto fail_free; 2248 if (fwd->listen_path != NULL && 2249 strlen(fwd->listen_path) >= PATH_MAX_SUN) 2250 goto fail_free; 2251 2252 return (i); 2253 2254 fail_free: 2255 free(fwd->connect_host); 2256 fwd->connect_host = NULL; 2257 free(fwd->connect_path); 2258 fwd->connect_path = NULL; 2259 free(fwd->listen_host); 2260 fwd->listen_host = NULL; 2261 free(fwd->listen_path); 2262 fwd->listen_path = NULL; 2263 return (0); 2264 } 2265 2266 int 2267 parse_jump(const char *s, Options *o, int active) 2268 { 2269 char *orig, *sdup, *cp; 2270 char *host = NULL, *user = NULL; 2271 int ret = -1, port = -1, first; 2272 2273 active &= o->proxy_command == NULL && o->jump_host == NULL; 2274 2275 orig = sdup = xstrdup(s); 2276 first = active; 2277 do { 2278 if ((cp = strrchr(sdup, ',')) == NULL) 2279 cp = sdup; /* last */ 2280 else 2281 *cp++ = '\0'; 2282 2283 if (first) { 2284 /* First argument and configuration is active */ 2285 if (parse_user_host_port(cp, &user, &host, &port) != 0) 2286 goto out; 2287 } else { 2288 /* Subsequent argument or inactive configuration */ 2289 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) 2290 goto out; 2291 } 2292 first = 0; /* only check syntax for subsequent hosts */ 2293 } while (cp != sdup); 2294 /* success */ 2295 if (active) { 2296 o->jump_user = user; 2297 o->jump_host = host; 2298 o->jump_port = port; 2299 o->proxy_command = xstrdup("none"); 2300 user = host = NULL; 2301 if ((cp = strrchr(s, ',')) != NULL && cp != s) { 2302 o->jump_extra = xstrdup(s); 2303 o->jump_extra[cp - s] = '\0'; 2304 } 2305 } 2306 ret = 0; 2307 out: 2308 free(orig); 2309 free(user); 2310 free(host); 2311 return ret; 2312 } 2313 2314 /* XXX the following is a near-vebatim copy from servconf.c; refactor */ 2315 static const char * 2316 fmt_multistate_int(int val, const struct multistate *m) 2317 { 2318 u_int i; 2319 2320 for (i = 0; m[i].key != NULL; i++) { 2321 if (m[i].value == val) 2322 return m[i].key; 2323 } 2324 return "UNKNOWN"; 2325 } 2326 2327 static const char * 2328 fmt_intarg(OpCodes code, int val) 2329 { 2330 if (val == -1) 2331 return "unset"; 2332 switch (code) { 2333 case oAddressFamily: 2334 return fmt_multistate_int(val, multistate_addressfamily); 2335 case oVerifyHostKeyDNS: 2336 case oStrictHostKeyChecking: 2337 case oUpdateHostkeys: 2338 return fmt_multistate_int(val, multistate_yesnoask); 2339 case oControlMaster: 2340 return fmt_multistate_int(val, multistate_controlmaster); 2341 case oTunnel: 2342 return fmt_multistate_int(val, multistate_tunnel); 2343 case oRequestTTY: 2344 return fmt_multistate_int(val, multistate_requesttty); 2345 case oCanonicalizeHostname: 2346 return fmt_multistate_int(val, multistate_canonicalizehostname); 2347 case oFingerprintHash: 2348 return ssh_digest_alg_name(val); 2349 case oProtocol: 2350 switch (val) { 2351 case SSH_PROTO_1: 2352 return "1"; 2353 case SSH_PROTO_2: 2354 return "2"; 2355 case (SSH_PROTO_1|SSH_PROTO_2): 2356 return "2,1"; 2357 default: 2358 return "UNKNOWN"; 2359 } 2360 default: 2361 switch (val) { 2362 case 0: 2363 return "no"; 2364 case 1: 2365 return "yes"; 2366 default: 2367 return "UNKNOWN"; 2368 } 2369 } 2370 } 2371 2372 static const char * 2373 lookup_opcode_name(OpCodes code) 2374 { 2375 u_int i; 2376 2377 for (i = 0; keywords[i].name != NULL; i++) 2378 if (keywords[i].opcode == code) 2379 return(keywords[i].name); 2380 return "UNKNOWN"; 2381 } 2382 2383 static void 2384 dump_cfg_int(OpCodes code, int val) 2385 { 2386 printf("%s %d\n", lookup_opcode_name(code), val); 2387 } 2388 2389 static void 2390 dump_cfg_fmtint(OpCodes code, int val) 2391 { 2392 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2393 } 2394 2395 static void 2396 dump_cfg_string(OpCodes code, const char *val) 2397 { 2398 if (val == NULL) 2399 return; 2400 printf("%s %s\n", lookup_opcode_name(code), val); 2401 } 2402 2403 static void 2404 dump_cfg_strarray(OpCodes code, u_int count, char **vals) 2405 { 2406 u_int i; 2407 2408 for (i = 0; i < count; i++) 2409 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2410 } 2411 2412 static void 2413 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) 2414 { 2415 u_int i; 2416 2417 printf("%s", lookup_opcode_name(code)); 2418 for (i = 0; i < count; i++) 2419 printf(" %s", vals[i]); 2420 printf("\n"); 2421 } 2422 2423 static void 2424 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) 2425 { 2426 const struct Forward *fwd; 2427 u_int i; 2428 2429 /* oDynamicForward */ 2430 for (i = 0; i < count; i++) { 2431 fwd = &fwds[i]; 2432 if (code == oDynamicForward && 2433 strcmp(fwd->connect_host, "socks") != 0) 2434 continue; 2435 if (code == oLocalForward && 2436 strcmp(fwd->connect_host, "socks") == 0) 2437 continue; 2438 printf("%s", lookup_opcode_name(code)); 2439 if (fwd->listen_port == PORT_STREAMLOCAL) 2440 printf(" %s", fwd->listen_path); 2441 else if (fwd->listen_host == NULL) 2442 printf(" %d", fwd->listen_port); 2443 else { 2444 printf(" [%s]:%d", 2445 fwd->listen_host, fwd->listen_port); 2446 } 2447 if (code != oDynamicForward) { 2448 if (fwd->connect_port == PORT_STREAMLOCAL) 2449 printf(" %s", fwd->connect_path); 2450 else if (fwd->connect_host == NULL) 2451 printf(" %d", fwd->connect_port); 2452 else { 2453 printf(" [%s]:%d", 2454 fwd->connect_host, fwd->connect_port); 2455 } 2456 } 2457 printf("\n"); 2458 } 2459 } 2460 2461 void 2462 dump_client_config(Options *o, const char *host) 2463 { 2464 int i; 2465 char buf[8]; 2466 2467 /* This is normally prepared in ssh_kex2 */ 2468 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) 2469 fatal("%s: kex_assemble_names failed", __func__); 2470 2471 /* Most interesting options first: user, host, port */ 2472 dump_cfg_string(oUser, o->user); 2473 dump_cfg_string(oHostName, host); 2474 dump_cfg_int(oPort, o->port); 2475 2476 /* Flag options */ 2477 dump_cfg_fmtint(oAddressFamily, o->address_family); 2478 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2479 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2480 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); 2481 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); 2482 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); 2483 dump_cfg_fmtint(oCompression, o->compression); 2484 dump_cfg_fmtint(oControlMaster, o->control_master); 2485 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); 2486 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); 2487 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2488 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2489 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2490 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2491 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2492 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2493 #ifdef GSSAPI 2494 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2495 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2496 #endif /* GSSAPI */ 2497 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2498 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2499 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); 2500 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); 2501 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2502 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2503 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2504 dump_cfg_fmtint(oProtocol, o->protocol); 2505 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2506 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2507 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2508 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2509 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); 2510 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2511 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2512 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2513 dump_cfg_fmtint(oTunnel, o->tun_open); 2514 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); 2515 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); 2516 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); 2517 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); 2518 2519 /* Integer options */ 2520 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2521 dump_cfg_int(oCompressionLevel, o->compression_level); 2522 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2523 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2524 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2525 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); 2526 dump_cfg_int(oServerAliveInterval, o->server_alive_interval); 2527 2528 /* String options */ 2529 dump_cfg_string(oBindAddress, o->bind_address); 2530 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); 2531 dump_cfg_string(oControlPath, o->control_path); 2532 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); 2533 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2534 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2535 dump_cfg_string(oIdentityAgent, o->identity_agent); 2536 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2537 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); 2538 dump_cfg_string(oLocalCommand, o->local_command); 2539 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2540 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); 2541 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2542 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2543 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); 2544 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2545 dump_cfg_string(oXAuthLocation, o->xauth_location); 2546 2547 /* Forwards */ 2548 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2549 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2550 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); 2551 2552 /* String array options */ 2553 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); 2554 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); 2555 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); 2556 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); 2557 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); 2558 2559 /* Special cases */ 2560 2561 /* oConnectTimeout */ 2562 if (o->connection_timeout == -1) 2563 printf("connecttimeout none\n"); 2564 else 2565 dump_cfg_int(oConnectTimeout, o->connection_timeout); 2566 2567 /* oTunnelDevice */ 2568 printf("tunneldevice"); 2569 if (o->tun_local == SSH_TUNID_ANY) 2570 printf(" any"); 2571 else 2572 printf(" %d", o->tun_local); 2573 if (o->tun_remote == SSH_TUNID_ANY) 2574 printf(":any"); 2575 else 2576 printf(":%d", o->tun_remote); 2577 printf("\n"); 2578 2579 /* oCanonicalizePermittedCNAMEs */ 2580 if ( o->num_permitted_cnames > 0) { 2581 printf("canonicalizePermittedcnames"); 2582 for (i = 0; i < o->num_permitted_cnames; i++) { 2583 printf(" %s:%s", o->permitted_cnames[i].source_list, 2584 o->permitted_cnames[i].target_list); 2585 } 2586 printf("\n"); 2587 } 2588 2589 /* oCipher */ 2590 if (o->cipher != SSH_CIPHER_NOT_SET) 2591 printf("Cipher %s\n", cipher_name(o->cipher)); 2592 2593 /* oControlPersist */ 2594 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2595 dump_cfg_fmtint(oControlPersist, o->control_persist); 2596 else 2597 dump_cfg_int(oControlPersist, o->control_persist_timeout); 2598 2599 /* oEscapeChar */ 2600 if (o->escape_char == SSH_ESCAPECHAR_NONE) 2601 printf("escapechar none\n"); 2602 else { 2603 vis(buf, o->escape_char, VIS_WHITE, 0); 2604 printf("escapechar %s\n", buf); 2605 } 2606 2607 /* oIPQoS */ 2608 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2609 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2610 2611 /* oRekeyLimit */ 2612 printf("rekeylimit %llu %d\n", 2613 (unsigned long long)o->rekey_limit, o->rekey_interval); 2614 2615 /* oStreamLocalBindMask */ 2616 printf("streamlocalbindmask 0%o\n", 2617 o->fwd_opts.streamlocal_bind_mask); 2618 2619 /* oProxyCommand / oProxyJump */ 2620 if (o->jump_host == NULL) 2621 dump_cfg_string(oProxyCommand, o->proxy_command); 2622 else { 2623 /* Check for numeric addresses */ 2624 i = strchr(o->jump_host, ':') != NULL || 2625 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host); 2626 snprintf(buf, sizeof(buf), "%d", o->jump_port); 2627 printf("proxyjump %s%s%s%s%s%s%s%s%s\n", 2628 /* optional additional jump spec */ 2629 o->jump_extra == NULL ? "" : o->jump_extra, 2630 o->jump_extra == NULL ? "" : ",", 2631 /* optional user */ 2632 o->jump_user == NULL ? "" : o->jump_user, 2633 o->jump_user == NULL ? "" : "@", 2634 /* opening [ if hostname is numeric */ 2635 i ? "[" : "", 2636 /* mandatory hostname */ 2637 o->jump_host, 2638 /* closing ] if hostname is numeric */ 2639 i ? "]" : "", 2640 /* optional port number */ 2641 o->jump_port <= 0 ? "" : ":", 2642 o->jump_port <= 0 ? "" : buf); 2643 } 2644 } 2645