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