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