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