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