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