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