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