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