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