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