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