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