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