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