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