1 /* $OpenBSD: readconf.c,v 1.264 2017/01/06 09:27:52 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 (!bind_permitted(newfwd->listen_port, original_real_uid) && 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 if (r != 1 && errno != ENOENT) { 1491 fatal("Can't open user config file " 1492 "%.100s: %.100s", gl.gl_pathv[i], 1493 strerror(errno)); 1494 } 1495 /* 1496 * don't let Match in includes clobber the 1497 * containing file's Match state. 1498 */ 1499 *activep = oactive; 1500 if (r != 1) 1501 value = -1; 1502 } 1503 globfree(&gl); 1504 } 1505 if (value != 0) 1506 return value; 1507 break; 1508 1509 case oIPQoS: 1510 arg = strdelim(&s); 1511 if ((value = parse_ipqos(arg)) == -1) 1512 fatal("%s line %d: Bad IPQoS value: %s", 1513 filename, linenum, arg); 1514 arg = strdelim(&s); 1515 if (arg == NULL) 1516 value2 = value; 1517 else if ((value2 = parse_ipqos(arg)) == -1) 1518 fatal("%s line %d: Bad IPQoS value: %s", 1519 filename, linenum, arg); 1520 if (*activep) { 1521 options->ip_qos_interactive = value; 1522 options->ip_qos_bulk = value2; 1523 } 1524 break; 1525 1526 case oRequestTTY: 1527 intptr = &options->request_tty; 1528 multistate_ptr = multistate_requesttty; 1529 goto parse_multistate; 1530 1531 case oIgnoreUnknown: 1532 charptr = &options->ignored_unknown; 1533 goto parse_string; 1534 1535 case oProxyUseFdpass: 1536 intptr = &options->proxy_use_fdpass; 1537 goto parse_flag; 1538 1539 case oCanonicalDomains: 1540 value = options->num_canonical_domains != 0; 1541 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1542 valid_domain(arg, filename, linenum); 1543 if (!*activep || value) 1544 continue; 1545 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1546 fatal("%s line %d: too many hostname suffixes.", 1547 filename, linenum); 1548 options->canonical_domains[ 1549 options->num_canonical_domains++] = xstrdup(arg); 1550 } 1551 break; 1552 1553 case oCanonicalizePermittedCNAMEs: 1554 value = options->num_permitted_cnames != 0; 1555 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1556 /* Either '*' for everything or 'list:list' */ 1557 if (strcmp(arg, "*") == 0) 1558 arg2 = arg; 1559 else { 1560 lowercase(arg); 1561 if ((arg2 = strchr(arg, ':')) == NULL || 1562 arg2[1] == '\0') { 1563 fatal("%s line %d: " 1564 "Invalid permitted CNAME \"%s\"", 1565 filename, linenum, arg); 1566 } 1567 *arg2 = '\0'; 1568 arg2++; 1569 } 1570 if (!*activep || value) 1571 continue; 1572 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1573 fatal("%s line %d: too many permitted CNAMEs.", 1574 filename, linenum); 1575 cname = options->permitted_cnames + 1576 options->num_permitted_cnames++; 1577 cname->source_list = xstrdup(arg); 1578 cname->target_list = xstrdup(arg2); 1579 } 1580 break; 1581 1582 case oCanonicalizeHostname: 1583 intptr = &options->canonicalize_hostname; 1584 multistate_ptr = multistate_canonicalizehostname; 1585 goto parse_multistate; 1586 1587 case oCanonicalizeMaxDots: 1588 intptr = &options->canonicalize_max_dots; 1589 goto parse_int; 1590 1591 case oCanonicalizeFallbackLocal: 1592 intptr = &options->canonicalize_fallback_local; 1593 goto parse_flag; 1594 1595 case oStreamLocalBindMask: 1596 arg = strdelim(&s); 1597 if (!arg || *arg == '\0') 1598 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); 1599 /* Parse mode in octal format */ 1600 value = strtol(arg, &endofnumber, 8); 1601 if (arg == endofnumber || value < 0 || value > 0777) 1602 fatal("%.200s line %d: Bad mask.", filename, linenum); 1603 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1604 break; 1605 1606 case oStreamLocalBindUnlink: 1607 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1608 goto parse_flag; 1609 1610 case oRevokedHostKeys: 1611 charptr = &options->revoked_host_keys; 1612 goto parse_string; 1613 1614 case oFingerprintHash: 1615 intptr = &options->fingerprint_hash; 1616 arg = strdelim(&s); 1617 if (!arg || *arg == '\0') 1618 fatal("%.200s line %d: Missing argument.", 1619 filename, linenum); 1620 if ((value = ssh_digest_alg_by_name(arg)) == -1) 1621 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1622 filename, linenum, arg); 1623 if (*activep && *intptr == -1) 1624 *intptr = value; 1625 break; 1626 1627 case oUpdateHostkeys: 1628 intptr = &options->update_hostkeys; 1629 multistate_ptr = multistate_yesnoask; 1630 goto parse_multistate; 1631 1632 case oHostbasedKeyTypes: 1633 charptr = &options->hostbased_key_types; 1634 goto parse_keytypes; 1635 1636 case oPubkeyAcceptedKeyTypes: 1637 charptr = &options->pubkey_key_types; 1638 goto parse_keytypes; 1639 1640 case oAddKeysToAgent: 1641 intptr = &options->add_keys_to_agent; 1642 multistate_ptr = multistate_yesnoaskconfirm; 1643 goto parse_multistate; 1644 1645 case oIdentityAgent: 1646 charptr = &options->identity_agent; 1647 goto parse_string; 1648 1649 case oDeprecated: 1650 debug("%s line %d: Deprecated option \"%s\"", 1651 filename, linenum, keyword); 1652 return 0; 1653 1654 case oUnsupported: 1655 error("%s line %d: Unsupported option \"%s\"", 1656 filename, linenum, keyword); 1657 return 0; 1658 1659 default: 1660 fatal("%s: Unimplemented opcode %d", __func__, opcode); 1661 } 1662 1663 /* Check that there is no garbage at end of line. */ 1664 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1665 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1666 filename, linenum, arg); 1667 } 1668 return 0; 1669 } 1670 1671 /* 1672 * Reads the config file and modifies the options accordingly. Options 1673 * should already be initialized before this call. This never returns if 1674 * there is an error. If the file does not exist, this returns 0. 1675 */ 1676 int 1677 read_config_file(const char *filename, struct passwd *pw, const char *host, 1678 const char *original_host, Options *options, int flags) 1679 { 1680 int active = 1; 1681 1682 return read_config_file_depth(filename, pw, host, original_host, 1683 options, flags, &active, 0); 1684 } 1685 1686 #define READCONF_MAX_DEPTH 16 1687 static int 1688 read_config_file_depth(const char *filename, struct passwd *pw, 1689 const char *host, const char *original_host, Options *options, 1690 int flags, int *activep, int depth) 1691 { 1692 FILE *f; 1693 char line[1024]; 1694 int linenum; 1695 int bad_options = 0; 1696 1697 if (depth < 0 || depth > READCONF_MAX_DEPTH) 1698 fatal("Too many recursive configuration includes"); 1699 1700 if ((f = fopen(filename, "r")) == NULL) 1701 return 0; 1702 1703 if (flags & SSHCONF_CHECKPERM) { 1704 struct stat sb; 1705 1706 if (fstat(fileno(f), &sb) == -1) 1707 fatal("fstat %s: %s", filename, strerror(errno)); 1708 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 1709 (sb.st_mode & 022) != 0)) 1710 fatal("Bad owner or permissions on %s", filename); 1711 } 1712 1713 debug("Reading configuration data %.200s", filename); 1714 1715 /* 1716 * Mark that we are now processing the options. This flag is turned 1717 * on/off by Host specifications. 1718 */ 1719 linenum = 0; 1720 while (fgets(line, sizeof(line), f)) { 1721 /* Update line number counter. */ 1722 linenum++; 1723 if (process_config_line_depth(options, pw, host, original_host, 1724 line, filename, linenum, activep, flags, depth) != 0) 1725 bad_options++; 1726 } 1727 fclose(f); 1728 if (bad_options > 0) 1729 fatal("%s: terminating, %d bad configuration options", 1730 filename, bad_options); 1731 return 1; 1732 } 1733 1734 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 1735 int 1736 option_clear_or_none(const char *o) 1737 { 1738 return o == NULL || strcasecmp(o, "none") == 0; 1739 } 1740 1741 /* 1742 * Initializes options to special values that indicate that they have not yet 1743 * been set. Read_config_file will only set options with this value. Options 1744 * are processed in the following order: command line, user config file, 1745 * system config file. Last, fill_default_options is called. 1746 */ 1747 1748 void 1749 initialize_options(Options * options) 1750 { 1751 memset(options, 'X', sizeof(*options)); 1752 options->forward_agent = -1; 1753 options->forward_x11 = -1; 1754 options->forward_x11_trusted = -1; 1755 options->forward_x11_timeout = -1; 1756 options->stdio_forward_host = NULL; 1757 options->stdio_forward_port = 0; 1758 options->clear_forwardings = -1; 1759 options->exit_on_forward_failure = -1; 1760 options->xauth_location = NULL; 1761 options->fwd_opts.gateway_ports = -1; 1762 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 1763 options->fwd_opts.streamlocal_bind_unlink = -1; 1764 options->use_privileged_port = -1; 1765 options->rsa_authentication = -1; 1766 options->pubkey_authentication = -1; 1767 options->challenge_response_authentication = -1; 1768 options->gss_authentication = -1; 1769 options->gss_deleg_creds = -1; 1770 options->password_authentication = -1; 1771 options->kbd_interactive_authentication = -1; 1772 options->kbd_interactive_devices = NULL; 1773 options->rhosts_rsa_authentication = -1; 1774 options->hostbased_authentication = -1; 1775 options->batch_mode = -1; 1776 options->check_host_ip = -1; 1777 options->strict_host_key_checking = -1; 1778 options->compression = -1; 1779 options->tcp_keep_alive = -1; 1780 options->compression_level = -1; 1781 options->port = -1; 1782 options->address_family = -1; 1783 options->connection_attempts = -1; 1784 options->connection_timeout = -1; 1785 options->number_of_password_prompts = -1; 1786 options->cipher = -1; 1787 options->ciphers = NULL; 1788 options->macs = NULL; 1789 options->kex_algorithms = NULL; 1790 options->hostkeyalgorithms = NULL; 1791 options->protocol = SSH_PROTO_UNKNOWN; 1792 options->num_identity_files = 0; 1793 options->num_certificate_files = 0; 1794 options->hostname = NULL; 1795 options->host_key_alias = NULL; 1796 options->proxy_command = NULL; 1797 options->jump_user = NULL; 1798 options->jump_host = NULL; 1799 options->jump_port = -1; 1800 options->jump_extra = NULL; 1801 options->user = NULL; 1802 options->escape_char = -1; 1803 options->num_system_hostfiles = 0; 1804 options->num_user_hostfiles = 0; 1805 options->local_forwards = NULL; 1806 options->num_local_forwards = 0; 1807 options->remote_forwards = NULL; 1808 options->num_remote_forwards = 0; 1809 options->log_level = SYSLOG_LEVEL_NOT_SET; 1810 options->preferred_authentications = NULL; 1811 options->bind_address = NULL; 1812 options->pkcs11_provider = NULL; 1813 options->enable_ssh_keysign = - 1; 1814 options->no_host_authentication_for_localhost = - 1; 1815 options->identities_only = - 1; 1816 options->rekey_limit = - 1; 1817 options->rekey_interval = -1; 1818 options->verify_host_key_dns = -1; 1819 options->server_alive_interval = -1; 1820 options->server_alive_count_max = -1; 1821 options->num_send_env = 0; 1822 options->control_path = NULL; 1823 options->control_master = -1; 1824 options->control_persist = -1; 1825 options->control_persist_timeout = 0; 1826 options->hash_known_hosts = -1; 1827 options->tun_open = -1; 1828 options->tun_local = -1; 1829 options->tun_remote = -1; 1830 options->local_command = NULL; 1831 options->permit_local_command = -1; 1832 options->add_keys_to_agent = -1; 1833 options->identity_agent = NULL; 1834 options->visual_host_key = -1; 1835 options->ip_qos_interactive = -1; 1836 options->ip_qos_bulk = -1; 1837 options->request_tty = -1; 1838 options->proxy_use_fdpass = -1; 1839 options->ignored_unknown = NULL; 1840 options->num_canonical_domains = 0; 1841 options->num_permitted_cnames = 0; 1842 options->canonicalize_max_dots = -1; 1843 options->canonicalize_fallback_local = -1; 1844 options->canonicalize_hostname = -1; 1845 options->revoked_host_keys = NULL; 1846 options->fingerprint_hash = -1; 1847 options->update_hostkeys = -1; 1848 options->hostbased_key_types = NULL; 1849 options->pubkey_key_types = NULL; 1850 } 1851 1852 /* 1853 * A petite version of fill_default_options() that just fills the options 1854 * needed for hostname canonicalization to proceed. 1855 */ 1856 void 1857 fill_default_options_for_canonicalization(Options *options) 1858 { 1859 if (options->canonicalize_max_dots == -1) 1860 options->canonicalize_max_dots = 1; 1861 if (options->canonicalize_fallback_local == -1) 1862 options->canonicalize_fallback_local = 1; 1863 if (options->canonicalize_hostname == -1) 1864 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1865 } 1866 1867 /* 1868 * Called after processing other sources of option data, this fills those 1869 * options for which no value has been specified with their default values. 1870 */ 1871 void 1872 fill_default_options(Options * options) 1873 { 1874 if (options->forward_agent == -1) 1875 options->forward_agent = 0; 1876 if (options->forward_x11 == -1) 1877 options->forward_x11 = 0; 1878 if (options->forward_x11_trusted == -1) 1879 options->forward_x11_trusted = 0; 1880 if (options->forward_x11_timeout == -1) 1881 options->forward_x11_timeout = 1200; 1882 /* 1883 * stdio forwarding (-W) changes the default for these but we defer 1884 * setting the values so they can be overridden. 1885 */ 1886 if (options->exit_on_forward_failure == -1) 1887 options->exit_on_forward_failure = 1888 options->stdio_forward_host != NULL ? 1 : 0; 1889 if (options->clear_forwardings == -1) 1890 options->clear_forwardings = 1891 options->stdio_forward_host != NULL ? 1 : 0; 1892 if (options->clear_forwardings == 1) 1893 clear_forwardings(options); 1894 1895 if (options->xauth_location == NULL) 1896 options->xauth_location = _PATH_XAUTH; 1897 if (options->fwd_opts.gateway_ports == -1) 1898 options->fwd_opts.gateway_ports = 0; 1899 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 1900 options->fwd_opts.streamlocal_bind_mask = 0177; 1901 if (options->fwd_opts.streamlocal_bind_unlink == -1) 1902 options->fwd_opts.streamlocal_bind_unlink = 0; 1903 if (options->use_privileged_port == -1) 1904 options->use_privileged_port = 0; 1905 if (options->rsa_authentication == -1) 1906 options->rsa_authentication = 1; 1907 if (options->pubkey_authentication == -1) 1908 options->pubkey_authentication = 1; 1909 if (options->challenge_response_authentication == -1) 1910 options->challenge_response_authentication = 1; 1911 if (options->gss_authentication == -1) 1912 options->gss_authentication = 0; 1913 if (options->gss_deleg_creds == -1) 1914 options->gss_deleg_creds = 0; 1915 if (options->password_authentication == -1) 1916 options->password_authentication = 1; 1917 if (options->kbd_interactive_authentication == -1) 1918 options->kbd_interactive_authentication = 1; 1919 if (options->rhosts_rsa_authentication == -1) 1920 options->rhosts_rsa_authentication = 0; 1921 if (options->hostbased_authentication == -1) 1922 options->hostbased_authentication = 0; 1923 if (options->batch_mode == -1) 1924 options->batch_mode = 0; 1925 if (options->check_host_ip == -1) 1926 options->check_host_ip = 1; 1927 if (options->strict_host_key_checking == -1) 1928 options->strict_host_key_checking = 2; /* 2 is default */ 1929 if (options->compression == -1) 1930 options->compression = 0; 1931 if (options->tcp_keep_alive == -1) 1932 options->tcp_keep_alive = 1; 1933 if (options->compression_level == -1) 1934 options->compression_level = 6; 1935 if (options->port == -1) 1936 options->port = 0; /* Filled in ssh_connect. */ 1937 if (options->address_family == -1) 1938 options->address_family = AF_UNSPEC; 1939 if (options->connection_attempts == -1) 1940 options->connection_attempts = 1; 1941 if (options->number_of_password_prompts == -1) 1942 options->number_of_password_prompts = 3; 1943 /* Selected in ssh_login(). */ 1944 if (options->cipher == -1) 1945 options->cipher = SSH_CIPHER_NOT_SET; 1946 /* options->hostkeyalgorithms, default set in myproposals.h */ 1947 if (options->protocol == SSH_PROTO_UNKNOWN) 1948 options->protocol = SSH_PROTO_2; 1949 if (options->add_keys_to_agent == -1) 1950 options->add_keys_to_agent = 0; 1951 if (options->num_identity_files == 0) { 1952 if (options->protocol & SSH_PROTO_1) { 1953 add_identity_file(options, "~/", 1954 _PATH_SSH_CLIENT_IDENTITY, 0); 1955 } 1956 if (options->protocol & SSH_PROTO_2) { 1957 add_identity_file(options, "~/", 1958 _PATH_SSH_CLIENT_ID_RSA, 0); 1959 add_identity_file(options, "~/", 1960 _PATH_SSH_CLIENT_ID_DSA, 0); 1961 add_identity_file(options, "~/", 1962 _PATH_SSH_CLIENT_ID_ECDSA, 0); 1963 add_identity_file(options, "~/", 1964 _PATH_SSH_CLIENT_ID_ED25519, 0); 1965 } 1966 } 1967 if (options->escape_char == -1) 1968 options->escape_char = '~'; 1969 if (options->num_system_hostfiles == 0) { 1970 options->system_hostfiles[options->num_system_hostfiles++] = 1971 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1972 options->system_hostfiles[options->num_system_hostfiles++] = 1973 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1974 } 1975 if (options->num_user_hostfiles == 0) { 1976 options->user_hostfiles[options->num_user_hostfiles++] = 1977 xstrdup(_PATH_SSH_USER_HOSTFILE); 1978 options->user_hostfiles[options->num_user_hostfiles++] = 1979 xstrdup(_PATH_SSH_USER_HOSTFILE2); 1980 } 1981 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1982 options->log_level = SYSLOG_LEVEL_INFO; 1983 if (options->no_host_authentication_for_localhost == - 1) 1984 options->no_host_authentication_for_localhost = 0; 1985 if (options->identities_only == -1) 1986 options->identities_only = 0; 1987 if (options->enable_ssh_keysign == -1) 1988 options->enable_ssh_keysign = 0; 1989 if (options->rekey_limit == -1) 1990 options->rekey_limit = 0; 1991 if (options->rekey_interval == -1) 1992 options->rekey_interval = 0; 1993 if (options->verify_host_key_dns == -1) 1994 options->verify_host_key_dns = 0; 1995 if (options->server_alive_interval == -1) 1996 options->server_alive_interval = 0; 1997 if (options->server_alive_count_max == -1) 1998 options->server_alive_count_max = 3; 1999 if (options->control_master == -1) 2000 options->control_master = 0; 2001 if (options->control_persist == -1) { 2002 options->control_persist = 0; 2003 options->control_persist_timeout = 0; 2004 } 2005 if (options->hash_known_hosts == -1) 2006 options->hash_known_hosts = 0; 2007 if (options->tun_open == -1) 2008 options->tun_open = SSH_TUNMODE_NO; 2009 if (options->tun_local == -1) 2010 options->tun_local = SSH_TUNID_ANY; 2011 if (options->tun_remote == -1) 2012 options->tun_remote = SSH_TUNID_ANY; 2013 if (options->permit_local_command == -1) 2014 options->permit_local_command = 0; 2015 if (options->visual_host_key == -1) 2016 options->visual_host_key = 0; 2017 if (options->ip_qos_interactive == -1) 2018 options->ip_qos_interactive = IPTOS_LOWDELAY; 2019 if (options->ip_qos_bulk == -1) 2020 options->ip_qos_bulk = IPTOS_THROUGHPUT; 2021 if (options->request_tty == -1) 2022 options->request_tty = REQUEST_TTY_AUTO; 2023 if (options->proxy_use_fdpass == -1) 2024 options->proxy_use_fdpass = 0; 2025 if (options->canonicalize_max_dots == -1) 2026 options->canonicalize_max_dots = 1; 2027 if (options->canonicalize_fallback_local == -1) 2028 options->canonicalize_fallback_local = 1; 2029 if (options->canonicalize_hostname == -1) 2030 options->canonicalize_hostname = SSH_CANONICALISE_NO; 2031 if (options->fingerprint_hash == -1) 2032 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 2033 if (options->update_hostkeys == -1) 2034 options->update_hostkeys = 0; 2035 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || 2036 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || 2037 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || 2038 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2039 &options->hostbased_key_types) != 0 || 2040 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2041 &options->pubkey_key_types) != 0) 2042 fatal("%s: kex_assemble_names failed", __func__); 2043 2044 #define CLEAR_ON_NONE(v) \ 2045 do { \ 2046 if (option_clear_or_none(v)) { \ 2047 free(v); \ 2048 v = NULL; \ 2049 } \ 2050 } while(0) 2051 CLEAR_ON_NONE(options->local_command); 2052 CLEAR_ON_NONE(options->proxy_command); 2053 CLEAR_ON_NONE(options->control_path); 2054 CLEAR_ON_NONE(options->revoked_host_keys); 2055 /* options->identity_agent distinguishes NULL from 'none' */ 2056 /* options->user will be set in the main program if appropriate */ 2057 /* options->hostname will be set in the main program if appropriate */ 2058 /* options->host_key_alias should not be set by default */ 2059 /* options->preferred_authentications will be set in ssh */ 2060 } 2061 2062 struct fwdarg { 2063 char *arg; 2064 int ispath; 2065 }; 2066 2067 /* 2068 * parse_fwd_field 2069 * parses the next field in a port forwarding specification. 2070 * sets fwd to the parsed field and advances p past the colon 2071 * or sets it to NULL at end of string. 2072 * returns 0 on success, else non-zero. 2073 */ 2074 static int 2075 parse_fwd_field(char **p, struct fwdarg *fwd) 2076 { 2077 char *ep, *cp = *p; 2078 int ispath = 0; 2079 2080 if (*cp == '\0') { 2081 *p = NULL; 2082 return -1; /* end of string */ 2083 } 2084 2085 /* 2086 * A field escaped with square brackets is used literally. 2087 * XXX - allow ']' to be escaped via backslash? 2088 */ 2089 if (*cp == '[') { 2090 /* find matching ']' */ 2091 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { 2092 if (*ep == '/') 2093 ispath = 1; 2094 } 2095 /* no matching ']' or not at end of field. */ 2096 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) 2097 return -1; 2098 /* NUL terminate the field and advance p past the colon */ 2099 *ep++ = '\0'; 2100 if (*ep != '\0') 2101 *ep++ = '\0'; 2102 fwd->arg = cp + 1; 2103 fwd->ispath = ispath; 2104 *p = ep; 2105 return 0; 2106 } 2107 2108 for (cp = *p; *cp != '\0'; cp++) { 2109 switch (*cp) { 2110 case '\\': 2111 memmove(cp, cp + 1, strlen(cp + 1) + 1); 2112 if (*cp == '\0') 2113 return -1; 2114 break; 2115 case '/': 2116 ispath = 1; 2117 break; 2118 case ':': 2119 *cp++ = '\0'; 2120 goto done; 2121 } 2122 } 2123 done: 2124 fwd->arg = *p; 2125 fwd->ispath = ispath; 2126 *p = cp; 2127 return 0; 2128 } 2129 2130 /* 2131 * parse_forward 2132 * parses a string containing a port forwarding specification of the form: 2133 * dynamicfwd == 0 2134 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath 2135 * listenpath:connectpath 2136 * dynamicfwd == 1 2137 * [listenhost:]listenport 2138 * returns number of arguments parsed or zero on error 2139 */ 2140 int 2141 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 2142 { 2143 struct fwdarg fwdargs[4]; 2144 char *p, *cp; 2145 int i; 2146 2147 memset(fwd, 0, sizeof(*fwd)); 2148 memset(fwdargs, 0, sizeof(fwdargs)); 2149 2150 cp = p = xstrdup(fwdspec); 2151 2152 /* skip leading spaces */ 2153 while (isspace((u_char)*cp)) 2154 cp++; 2155 2156 for (i = 0; i < 4; ++i) { 2157 if (parse_fwd_field(&cp, &fwdargs[i]) != 0) 2158 break; 2159 } 2160 2161 /* Check for trailing garbage */ 2162 if (cp != NULL && *cp != '\0') { 2163 i = 0; /* failure */ 2164 } 2165 2166 switch (i) { 2167 case 1: 2168 if (fwdargs[0].ispath) { 2169 fwd->listen_path = xstrdup(fwdargs[0].arg); 2170 fwd->listen_port = PORT_STREAMLOCAL; 2171 } else { 2172 fwd->listen_host = NULL; 2173 fwd->listen_port = a2port(fwdargs[0].arg); 2174 } 2175 fwd->connect_host = xstrdup("socks"); 2176 break; 2177 2178 case 2: 2179 if (fwdargs[0].ispath && fwdargs[1].ispath) { 2180 fwd->listen_path = xstrdup(fwdargs[0].arg); 2181 fwd->listen_port = PORT_STREAMLOCAL; 2182 fwd->connect_path = xstrdup(fwdargs[1].arg); 2183 fwd->connect_port = PORT_STREAMLOCAL; 2184 } else if (fwdargs[1].ispath) { 2185 fwd->listen_host = NULL; 2186 fwd->listen_port = a2port(fwdargs[0].arg); 2187 fwd->connect_path = xstrdup(fwdargs[1].arg); 2188 fwd->connect_port = PORT_STREAMLOCAL; 2189 } else { 2190 fwd->listen_host = xstrdup(fwdargs[0].arg); 2191 fwd->listen_port = a2port(fwdargs[1].arg); 2192 fwd->connect_host = xstrdup("socks"); 2193 } 2194 break; 2195 2196 case 3: 2197 if (fwdargs[0].ispath) { 2198 fwd->listen_path = xstrdup(fwdargs[0].arg); 2199 fwd->listen_port = PORT_STREAMLOCAL; 2200 fwd->connect_host = xstrdup(fwdargs[1].arg); 2201 fwd->connect_port = a2port(fwdargs[2].arg); 2202 } else if (fwdargs[2].ispath) { 2203 fwd->listen_host = xstrdup(fwdargs[0].arg); 2204 fwd->listen_port = a2port(fwdargs[1].arg); 2205 fwd->connect_path = xstrdup(fwdargs[2].arg); 2206 fwd->connect_port = PORT_STREAMLOCAL; 2207 } else { 2208 fwd->listen_host = NULL; 2209 fwd->listen_port = a2port(fwdargs[0].arg); 2210 fwd->connect_host = xstrdup(fwdargs[1].arg); 2211 fwd->connect_port = a2port(fwdargs[2].arg); 2212 } 2213 break; 2214 2215 case 4: 2216 fwd->listen_host = xstrdup(fwdargs[0].arg); 2217 fwd->listen_port = a2port(fwdargs[1].arg); 2218 fwd->connect_host = xstrdup(fwdargs[2].arg); 2219 fwd->connect_port = a2port(fwdargs[3].arg); 2220 break; 2221 default: 2222 i = 0; /* failure */ 2223 } 2224 2225 free(p); 2226 2227 if (dynamicfwd) { 2228 if (!(i == 1 || i == 2)) 2229 goto fail_free; 2230 } else { 2231 if (!(i == 3 || i == 4)) { 2232 if (fwd->connect_path == NULL && 2233 fwd->listen_path == NULL) 2234 goto fail_free; 2235 } 2236 if (fwd->connect_port <= 0 && fwd->connect_path == NULL) 2237 goto fail_free; 2238 } 2239 2240 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || 2241 (!remotefwd && fwd->listen_port == 0)) 2242 goto fail_free; 2243 if (fwd->connect_host != NULL && 2244 strlen(fwd->connect_host) >= NI_MAXHOST) 2245 goto fail_free; 2246 /* XXX - if connecting to a remote socket, max sun len may not match this host */ 2247 if (fwd->connect_path != NULL && 2248 strlen(fwd->connect_path) >= PATH_MAX_SUN) 2249 goto fail_free; 2250 if (fwd->listen_host != NULL && 2251 strlen(fwd->listen_host) >= NI_MAXHOST) 2252 goto fail_free; 2253 if (fwd->listen_path != NULL && 2254 strlen(fwd->listen_path) >= PATH_MAX_SUN) 2255 goto fail_free; 2256 2257 return (i); 2258 2259 fail_free: 2260 free(fwd->connect_host); 2261 fwd->connect_host = NULL; 2262 free(fwd->connect_path); 2263 fwd->connect_path = NULL; 2264 free(fwd->listen_host); 2265 fwd->listen_host = NULL; 2266 free(fwd->listen_path); 2267 fwd->listen_path = NULL; 2268 return (0); 2269 } 2270 2271 int 2272 parse_jump(const char *s, Options *o, int active) 2273 { 2274 char *orig, *sdup, *cp; 2275 char *host = NULL, *user = NULL; 2276 int ret = -1, port = -1, first; 2277 2278 active &= o->proxy_command == NULL && o->jump_host == NULL; 2279 2280 orig = sdup = xstrdup(s); 2281 first = active; 2282 do { 2283 if ((cp = strrchr(sdup, ',')) == NULL) 2284 cp = sdup; /* last */ 2285 else 2286 *cp++ = '\0'; 2287 2288 if (first) { 2289 /* First argument and configuration is active */ 2290 if (parse_user_host_port(cp, &user, &host, &port) != 0) 2291 goto out; 2292 } else { 2293 /* Subsequent argument or inactive configuration */ 2294 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) 2295 goto out; 2296 } 2297 first = 0; /* only check syntax for subsequent hosts */ 2298 } while (cp != sdup); 2299 /* success */ 2300 if (active) { 2301 o->jump_user = user; 2302 o->jump_host = host; 2303 o->jump_port = port; 2304 o->proxy_command = xstrdup("none"); 2305 user = host = NULL; 2306 if ((cp = strrchr(s, ',')) != NULL && cp != s) { 2307 o->jump_extra = xstrdup(s); 2308 o->jump_extra[cp - s] = '\0'; 2309 } 2310 } 2311 ret = 0; 2312 out: 2313 free(orig); 2314 free(user); 2315 free(host); 2316 return ret; 2317 } 2318 2319 /* XXX the following is a near-vebatim copy from servconf.c; refactor */ 2320 static const char * 2321 fmt_multistate_int(int val, const struct multistate *m) 2322 { 2323 u_int i; 2324 2325 for (i = 0; m[i].key != NULL; i++) { 2326 if (m[i].value == val) 2327 return m[i].key; 2328 } 2329 return "UNKNOWN"; 2330 } 2331 2332 static const char * 2333 fmt_intarg(OpCodes code, int val) 2334 { 2335 if (val == -1) 2336 return "unset"; 2337 switch (code) { 2338 case oAddressFamily: 2339 return fmt_multistate_int(val, multistate_addressfamily); 2340 case oVerifyHostKeyDNS: 2341 case oStrictHostKeyChecking: 2342 case oUpdateHostkeys: 2343 return fmt_multistate_int(val, multistate_yesnoask); 2344 case oControlMaster: 2345 return fmt_multistate_int(val, multistate_controlmaster); 2346 case oTunnel: 2347 return fmt_multistate_int(val, multistate_tunnel); 2348 case oRequestTTY: 2349 return fmt_multistate_int(val, multistate_requesttty); 2350 case oCanonicalizeHostname: 2351 return fmt_multistate_int(val, multistate_canonicalizehostname); 2352 case oFingerprintHash: 2353 return ssh_digest_alg_name(val); 2354 case oProtocol: 2355 switch (val) { 2356 case SSH_PROTO_1: 2357 return "1"; 2358 case SSH_PROTO_2: 2359 return "2"; 2360 case (SSH_PROTO_1|SSH_PROTO_2): 2361 return "2,1"; 2362 default: 2363 return "UNKNOWN"; 2364 } 2365 default: 2366 switch (val) { 2367 case 0: 2368 return "no"; 2369 case 1: 2370 return "yes"; 2371 default: 2372 return "UNKNOWN"; 2373 } 2374 } 2375 } 2376 2377 static const char * 2378 lookup_opcode_name(OpCodes code) 2379 { 2380 u_int i; 2381 2382 for (i = 0; keywords[i].name != NULL; i++) 2383 if (keywords[i].opcode == code) 2384 return(keywords[i].name); 2385 return "UNKNOWN"; 2386 } 2387 2388 static void 2389 dump_cfg_int(OpCodes code, int val) 2390 { 2391 printf("%s %d\n", lookup_opcode_name(code), val); 2392 } 2393 2394 static void 2395 dump_cfg_fmtint(OpCodes code, int val) 2396 { 2397 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2398 } 2399 2400 static void 2401 dump_cfg_string(OpCodes code, const char *val) 2402 { 2403 if (val == NULL) 2404 return; 2405 printf("%s %s\n", lookup_opcode_name(code), val); 2406 } 2407 2408 static void 2409 dump_cfg_strarray(OpCodes code, u_int count, char **vals) 2410 { 2411 u_int i; 2412 2413 for (i = 0; i < count; i++) 2414 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2415 } 2416 2417 static void 2418 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) 2419 { 2420 u_int i; 2421 2422 printf("%s", lookup_opcode_name(code)); 2423 for (i = 0; i < count; i++) 2424 printf(" %s", vals[i]); 2425 printf("\n"); 2426 } 2427 2428 static void 2429 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) 2430 { 2431 const struct Forward *fwd; 2432 u_int i; 2433 2434 /* oDynamicForward */ 2435 for (i = 0; i < count; i++) { 2436 fwd = &fwds[i]; 2437 if (code == oDynamicForward && 2438 strcmp(fwd->connect_host, "socks") != 0) 2439 continue; 2440 if (code == oLocalForward && 2441 strcmp(fwd->connect_host, "socks") == 0) 2442 continue; 2443 printf("%s", lookup_opcode_name(code)); 2444 if (fwd->listen_port == PORT_STREAMLOCAL) 2445 printf(" %s", fwd->listen_path); 2446 else if (fwd->listen_host == NULL) 2447 printf(" %d", fwd->listen_port); 2448 else { 2449 printf(" [%s]:%d", 2450 fwd->listen_host, fwd->listen_port); 2451 } 2452 if (code != oDynamicForward) { 2453 if (fwd->connect_port == PORT_STREAMLOCAL) 2454 printf(" %s", fwd->connect_path); 2455 else if (fwd->connect_host == NULL) 2456 printf(" %d", fwd->connect_port); 2457 else { 2458 printf(" [%s]:%d", 2459 fwd->connect_host, fwd->connect_port); 2460 } 2461 } 2462 printf("\n"); 2463 } 2464 } 2465 2466 void 2467 dump_client_config(Options *o, const char *host) 2468 { 2469 int i; 2470 char buf[8]; 2471 2472 /* This is normally prepared in ssh_kex2 */ 2473 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) 2474 fatal("%s: kex_assemble_names failed", __func__); 2475 2476 /* Most interesting options first: user, host, port */ 2477 dump_cfg_string(oUser, o->user); 2478 dump_cfg_string(oHostName, host); 2479 dump_cfg_int(oPort, o->port); 2480 2481 /* Flag options */ 2482 dump_cfg_fmtint(oAddressFamily, o->address_family); 2483 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2484 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2485 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); 2486 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); 2487 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); 2488 dump_cfg_fmtint(oCompression, o->compression); 2489 dump_cfg_fmtint(oControlMaster, o->control_master); 2490 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); 2491 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); 2492 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2493 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2494 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2495 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2496 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2497 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2498 #ifdef GSSAPI 2499 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2500 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2501 #endif /* GSSAPI */ 2502 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2503 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2504 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); 2505 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); 2506 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2507 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2508 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2509 dump_cfg_fmtint(oProtocol, o->protocol); 2510 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2511 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2512 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2513 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2514 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); 2515 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2516 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2517 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2518 dump_cfg_fmtint(oTunnel, o->tun_open); 2519 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); 2520 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); 2521 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); 2522 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); 2523 2524 /* Integer options */ 2525 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2526 dump_cfg_int(oCompressionLevel, o->compression_level); 2527 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2528 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2529 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2530 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); 2531 dump_cfg_int(oServerAliveInterval, o->server_alive_interval); 2532 2533 /* String options */ 2534 dump_cfg_string(oBindAddress, o->bind_address); 2535 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); 2536 dump_cfg_string(oControlPath, o->control_path); 2537 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); 2538 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2539 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2540 dump_cfg_string(oIdentityAgent, o->identity_agent); 2541 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2542 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); 2543 dump_cfg_string(oLocalCommand, o->local_command); 2544 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2545 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); 2546 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2547 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2548 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); 2549 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2550 dump_cfg_string(oXAuthLocation, o->xauth_location); 2551 2552 /* Forwards */ 2553 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2554 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2555 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); 2556 2557 /* String array options */ 2558 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); 2559 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); 2560 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); 2561 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); 2562 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); 2563 2564 /* Special cases */ 2565 2566 /* oConnectTimeout */ 2567 if (o->connection_timeout == -1) 2568 printf("connecttimeout none\n"); 2569 else 2570 dump_cfg_int(oConnectTimeout, o->connection_timeout); 2571 2572 /* oTunnelDevice */ 2573 printf("tunneldevice"); 2574 if (o->tun_local == SSH_TUNID_ANY) 2575 printf(" any"); 2576 else 2577 printf(" %d", o->tun_local); 2578 if (o->tun_remote == SSH_TUNID_ANY) 2579 printf(":any"); 2580 else 2581 printf(":%d", o->tun_remote); 2582 printf("\n"); 2583 2584 /* oCanonicalizePermittedCNAMEs */ 2585 if ( o->num_permitted_cnames > 0) { 2586 printf("canonicalizePermittedcnames"); 2587 for (i = 0; i < o->num_permitted_cnames; i++) { 2588 printf(" %s:%s", o->permitted_cnames[i].source_list, 2589 o->permitted_cnames[i].target_list); 2590 } 2591 printf("\n"); 2592 } 2593 2594 /* oCipher */ 2595 if (o->cipher != SSH_CIPHER_NOT_SET) 2596 printf("Cipher %s\n", cipher_name(o->cipher)); 2597 2598 /* oControlPersist */ 2599 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2600 dump_cfg_fmtint(oControlPersist, o->control_persist); 2601 else 2602 dump_cfg_int(oControlPersist, o->control_persist_timeout); 2603 2604 /* oEscapeChar */ 2605 if (o->escape_char == SSH_ESCAPECHAR_NONE) 2606 printf("escapechar none\n"); 2607 else { 2608 vis(buf, o->escape_char, VIS_WHITE, 0); 2609 printf("escapechar %s\n", buf); 2610 } 2611 2612 /* oIPQoS */ 2613 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2614 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2615 2616 /* oRekeyLimit */ 2617 printf("rekeylimit %llu %d\n", 2618 (unsigned long long)o->rekey_limit, o->rekey_interval); 2619 2620 /* oStreamLocalBindMask */ 2621 printf("streamlocalbindmask 0%o\n", 2622 o->fwd_opts.streamlocal_bind_mask); 2623 2624 /* oProxyCommand / oProxyJump */ 2625 if (o->jump_host == NULL) 2626 dump_cfg_string(oProxyCommand, o->proxy_command); 2627 else { 2628 /* Check for numeric addresses */ 2629 i = strchr(o->jump_host, ':') != NULL || 2630 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host); 2631 snprintf(buf, sizeof(buf), "%d", o->jump_port); 2632 printf("proxyjump %s%s%s%s%s%s%s%s%s\n", 2633 /* optional additional jump spec */ 2634 o->jump_extra == NULL ? "" : o->jump_extra, 2635 o->jump_extra == NULL ? "" : ",", 2636 /* optional user */ 2637 o->jump_user == NULL ? "" : o->jump_user, 2638 o->jump_user == NULL ? "" : "@", 2639 /* opening [ if hostname is numeric */ 2640 i ? "[" : "", 2641 /* mandatory hostname */ 2642 o->jump_host, 2643 /* closing ] if hostname is numeric */ 2644 i ? "]" : "", 2645 /* optional port number */ 2646 o->jump_port <= 0 ? "" : ":", 2647 o->jump_port <= 0 ? "" : buf); 2648 } 2649 } 2650