readconf.c revision 294693
1/* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 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: stable/10/crypto/openssh/readconf.c 294693 2016-01-24 22:28:18Z des $"); 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 24#include <netinet/in.h> 25#include <netinet/in_systm.h> 26#include <netinet/ip.h> 27#include <arpa/inet.h> 28 29#include <ctype.h> 30#include <errno.h> 31#include <fcntl.h> 32#include <netdb.h> 33#ifdef HAVE_PATHS_H 34# include <paths.h> 35#endif 36#include <pwd.h> 37#include <signal.h> 38#include <stdarg.h> 39#include <stdio.h> 40#include <string.h> 41#include <unistd.h> 42#ifdef HAVE_UTIL_H 43#include <util.h> 44#endif 45 46#include "xmalloc.h" 47#include "ssh.h" 48#include "compat.h" 49#include "cipher.h" 50#include "pathnames.h" 51#include "log.h" 52#include "key.h" 53#include "readconf.h" 54#include "match.h" 55#include "misc.h" 56#include "buffer.h" 57#include "kex.h" 58#include "mac.h" 59#include "uidswap.h" 60#include "version.h" 61 62/* Format of the configuration file: 63 64 # Configuration data is parsed as follows: 65 # 1. command line options 66 # 2. user-specific file 67 # 3. system-wide file 68 # Any configuration value is only changed the first time it is set. 69 # Thus, host-specific definitions should be at the beginning of the 70 # configuration file, and defaults at the end. 71 72 # Host-specific declarations. These may override anything above. A single 73 # host may match multiple declarations; these are processed in the order 74 # that they are given in. 75 76 Host *.ngs.fi ngs.fi 77 User foo 78 79 Host fake.com 80 HostName another.host.name.real.org 81 User blaah 82 Port 34289 83 ForwardX11 no 84 ForwardAgent no 85 86 Host books.com 87 RemoteForward 9999 shadows.cs.hut.fi:9999 88 Cipher 3des 89 90 Host fascist.blob.com 91 Port 23123 92 User tylonen 93 PasswordAuthentication no 94 95 Host puukko.hut.fi 96 User t35124p 97 ProxyCommand ssh-proxy %h %p 98 99 Host *.fr 100 PublicKeyAuthentication no 101 102 Host *.su 103 Cipher none 104 PasswordAuthentication no 105 106 Host vpn.fake.com 107 Tunnel yes 108 TunnelDevice 3 109 110 # Defaults for various options 111 Host * 112 ForwardAgent no 113 ForwardX11 no 114 PasswordAuthentication yes 115 RSAAuthentication yes 116 RhostsRSAAuthentication yes 117 StrictHostKeyChecking yes 118 TcpKeepAlive no 119 IdentityFile ~/.ssh/identity 120 Port 22 121 EscapeChar ~ 122 123*/ 124 125/* Keyword tokens. */ 126 127typedef enum { 128 oBadOption, 129 oHost, oMatch, 130 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, 131 oGatewayPorts, oExitOnForwardFailure, 132 oPasswordAuthentication, oRSAAuthentication, 133 oChallengeResponseAuthentication, oXAuthLocation, 134 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 135 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 136 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 137 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 138 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 139 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 140 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 141 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 142 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 143 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 144 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 145 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 146 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 147 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 148 oSendEnv, oControlPath, oControlMaster, oControlPersist, 149 oHashKnownHosts, 150 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 151 oVisualHostKey, oUseRoaming, 152 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 153 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 154 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 155 oVersionAddendum, 156 oIgnoredUnknownOption, oDeprecated, oUnsupported 157} OpCodes; 158 159/* Textual representations of the tokens. */ 160 161static struct { 162 const char *name; 163 OpCodes opcode; 164} keywords[] = { 165 { "forwardagent", oForwardAgent }, 166 { "forwardx11", oForwardX11 }, 167 { "forwardx11trusted", oForwardX11Trusted }, 168 { "forwardx11timeout", oForwardX11Timeout }, 169 { "exitonforwardfailure", oExitOnForwardFailure }, 170 { "xauthlocation", oXAuthLocation }, 171 { "gatewayports", oGatewayPorts }, 172 { "useprivilegedport", oUsePrivilegedPort }, 173 { "rhostsauthentication", oDeprecated }, 174 { "passwordauthentication", oPasswordAuthentication }, 175 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 176 { "kbdinteractivedevices", oKbdInteractiveDevices }, 177 { "rsaauthentication", oRSAAuthentication }, 178 { "pubkeyauthentication", oPubkeyAuthentication }, 179 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 180 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 181 { "hostbasedauthentication", oHostbasedAuthentication }, 182 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 183 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 184 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 185 { "kerberosauthentication", oUnsupported }, 186 { "kerberostgtpassing", oUnsupported }, 187 { "afstokenpassing", oUnsupported }, 188#if defined(GSSAPI) 189 { "gssapiauthentication", oGssAuthentication }, 190 { "gssapidelegatecredentials", oGssDelegateCreds }, 191#else 192 { "gssapiauthentication", oUnsupported }, 193 { "gssapidelegatecredentials", oUnsupported }, 194#endif 195 { "fallbacktorsh", oDeprecated }, 196 { "usersh", oDeprecated }, 197 { "identityfile", oIdentityFile }, 198 { "identityfile2", oIdentityFile }, /* obsolete */ 199 { "identitiesonly", oIdentitiesOnly }, 200 { "hostname", oHostName }, 201 { "hostkeyalias", oHostKeyAlias }, 202 { "proxycommand", oProxyCommand }, 203 { "port", oPort }, 204 { "cipher", oCipher }, 205 { "ciphers", oCiphers }, 206 { "macs", oMacs }, 207 { "protocol", oProtocol }, 208 { "remoteforward", oRemoteForward }, 209 { "localforward", oLocalForward }, 210 { "user", oUser }, 211 { "host", oHost }, 212 { "match", oMatch }, 213 { "escapechar", oEscapeChar }, 214 { "globalknownhostsfile", oGlobalKnownHostsFile }, 215 { "globalknownhostsfile2", oDeprecated }, 216 { "userknownhostsfile", oUserKnownHostsFile }, 217 { "userknownhostsfile2", oDeprecated }, 218 { "connectionattempts", oConnectionAttempts }, 219 { "batchmode", oBatchMode }, 220 { "checkhostip", oCheckHostIP }, 221 { "stricthostkeychecking", oStrictHostKeyChecking }, 222 { "compression", oCompression }, 223 { "compressionlevel", oCompressionLevel }, 224 { "tcpkeepalive", oTCPKeepAlive }, 225 { "keepalive", oTCPKeepAlive }, /* obsolete */ 226 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 227 { "loglevel", oLogLevel }, 228 { "dynamicforward", oDynamicForward }, 229 { "preferredauthentications", oPreferredAuthentications }, 230 { "hostkeyalgorithms", oHostKeyAlgorithms }, 231 { "bindaddress", oBindAddress }, 232#ifdef ENABLE_PKCS11 233 { "smartcarddevice", oPKCS11Provider }, 234 { "pkcs11provider", oPKCS11Provider }, 235#else 236 { "smartcarddevice", oUnsupported }, 237 { "pkcs11provider", oUnsupported }, 238#endif 239 { "clearallforwardings", oClearAllForwardings }, 240 { "enablesshkeysign", oEnableSSHKeysign }, 241 { "verifyhostkeydns", oVerifyHostKeyDNS }, 242 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 243 { "rekeylimit", oRekeyLimit }, 244 { "connecttimeout", oConnectTimeout }, 245 { "addressfamily", oAddressFamily }, 246 { "serveraliveinterval", oServerAliveInterval }, 247 { "serveralivecountmax", oServerAliveCountMax }, 248 { "sendenv", oSendEnv }, 249 { "controlpath", oControlPath }, 250 { "controlmaster", oControlMaster }, 251 { "controlpersist", oControlPersist }, 252 { "hashknownhosts", oHashKnownHosts }, 253 { "tunnel", oTunnel }, 254 { "tunneldevice", oTunnelDevice }, 255 { "localcommand", oLocalCommand }, 256 { "permitlocalcommand", oPermitLocalCommand }, 257 { "visualhostkey", oVisualHostKey }, 258 { "useroaming", oUseRoaming }, 259 { "kexalgorithms", oKexAlgorithms }, 260 { "ipqos", oIPQoS }, 261 { "requesttty", oRequestTTY }, 262 { "proxyusefdpass", oProxyUseFdpass }, 263 { "canonicaldomains", oCanonicalDomains }, 264 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, 265 { "canonicalizehostname", oCanonicalizeHostname }, 266 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 267 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 268 { "ignoreunknown", oIgnoreUnknown }, 269 { "hpndisabled", oDeprecated }, 270 { "hpnbuffersize", oDeprecated }, 271 { "tcprcvbufpoll", oDeprecated }, 272 { "tcprcvbuf", oDeprecated }, 273 { "versionaddendum", oVersionAddendum }, 274 275 { NULL, oBadOption } 276}; 277 278/* 279 * Adds a local TCP/IP port forward to options. Never returns if there is an 280 * error. 281 */ 282 283void 284add_local_forward(Options *options, const Forward *newfwd) 285{ 286 Forward *fwd; 287#ifndef NO_IPPORT_RESERVED_CONCEPT 288 extern uid_t original_real_uid; 289 int ipport_reserved; 290#ifdef __FreeBSD__ 291 size_t len_ipport_reserved = sizeof(ipport_reserved); 292 293 if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 294 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 295 ipport_reserved = IPPORT_RESERVED; 296 else 297 ipport_reserved++; 298#else 299 ipport_reserved = IPPORT_RESERVED; 300#endif 301 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 302 fatal("Privileged ports can only be forwarded by root."); 303#endif 304 options->local_forwards = xrealloc(options->local_forwards, 305 options->num_local_forwards + 1, 306 sizeof(*options->local_forwards)); 307 fwd = &options->local_forwards[options->num_local_forwards++]; 308 309 fwd->listen_host = newfwd->listen_host; 310 fwd->listen_port = newfwd->listen_port; 311 fwd->connect_host = newfwd->connect_host; 312 fwd->connect_port = newfwd->connect_port; 313} 314 315/* 316 * Adds a remote TCP/IP port forward to options. Never returns if there is 317 * an error. 318 */ 319 320void 321add_remote_forward(Options *options, const Forward *newfwd) 322{ 323 Forward *fwd; 324 325 options->remote_forwards = xrealloc(options->remote_forwards, 326 options->num_remote_forwards + 1, 327 sizeof(*options->remote_forwards)); 328 fwd = &options->remote_forwards[options->num_remote_forwards++]; 329 330 fwd->listen_host = newfwd->listen_host; 331 fwd->listen_port = newfwd->listen_port; 332 fwd->connect_host = newfwd->connect_host; 333 fwd->connect_port = newfwd->connect_port; 334 fwd->handle = newfwd->handle; 335 fwd->allocated_port = 0; 336} 337 338static void 339clear_forwardings(Options *options) 340{ 341 int i; 342 343 for (i = 0; i < options->num_local_forwards; i++) { 344 free(options->local_forwards[i].listen_host); 345 free(options->local_forwards[i].connect_host); 346 } 347 if (options->num_local_forwards > 0) { 348 free(options->local_forwards); 349 options->local_forwards = NULL; 350 } 351 options->num_local_forwards = 0; 352 for (i = 0; i < options->num_remote_forwards; i++) { 353 free(options->remote_forwards[i].listen_host); 354 free(options->remote_forwards[i].connect_host); 355 } 356 if (options->num_remote_forwards > 0) { 357 free(options->remote_forwards); 358 options->remote_forwards = NULL; 359 } 360 options->num_remote_forwards = 0; 361 options->tun_open = SSH_TUNMODE_NO; 362} 363 364void 365add_identity_file(Options *options, const char *dir, const char *filename, 366 int userprovided) 367{ 368 char *path; 369 370 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 371 fatal("Too many identity files specified (max %d)", 372 SSH_MAX_IDENTITY_FILES); 373 374 if (dir == NULL) /* no dir, filename is absolute */ 375 path = xstrdup(filename); 376 else 377 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 378 379 options->identity_file_userprovided[options->num_identity_files] = 380 userprovided; 381 options->identity_files[options->num_identity_files++] = path; 382} 383 384int 385default_ssh_port(void) 386{ 387 static int port; 388 struct servent *sp; 389 390 if (port == 0) { 391 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 392 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 393 } 394 return port; 395} 396 397/* 398 * Execute a command in a shell. 399 * Return its exit status or -1 on abnormal exit. 400 */ 401static int 402execute_in_shell(const char *cmd) 403{ 404 char *shell, *command_string; 405 pid_t pid; 406 int devnull, status; 407 extern uid_t original_real_uid; 408 409 if ((shell = getenv("SHELL")) == NULL) 410 shell = _PATH_BSHELL; 411 412 /* 413 * Use "exec" to avoid "sh -c" processes on some platforms 414 * (e.g. Solaris) 415 */ 416 xasprintf(&command_string, "exec %s", cmd); 417 418 /* Need this to redirect subprocess stdin/out */ 419 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 420 fatal("open(/dev/null): %s", strerror(errno)); 421 422 debug("Executing command: '%.500s'", cmd); 423 424 /* Fork and execute the command. */ 425 if ((pid = fork()) == 0) { 426 char *argv[4]; 427 428 /* Child. Permanently give up superuser privileges. */ 429 permanently_drop_suid(original_real_uid); 430 431 /* Redirect child stdin and stdout. Leave stderr */ 432 if (dup2(devnull, STDIN_FILENO) == -1) 433 fatal("dup2: %s", strerror(errno)); 434 if (dup2(devnull, STDOUT_FILENO) == -1) 435 fatal("dup2: %s", strerror(errno)); 436 if (devnull > STDERR_FILENO) 437 close(devnull); 438 closefrom(STDERR_FILENO + 1); 439 440 argv[0] = shell; 441 argv[1] = "-c"; 442 argv[2] = command_string; 443 argv[3] = NULL; 444 445 execv(argv[0], argv); 446 error("Unable to execute '%.100s': %s", cmd, strerror(errno)); 447 /* Die with signal to make this error apparent to parent. */ 448 signal(SIGTERM, SIG_DFL); 449 kill(getpid(), SIGTERM); 450 _exit(1); 451 } 452 /* Parent. */ 453 if (pid < 0) 454 fatal("%s: fork: %.100s", __func__, strerror(errno)); 455 456 close(devnull); 457 free(command_string); 458 459 while (waitpid(pid, &status, 0) == -1) { 460 if (errno != EINTR && errno != EAGAIN) 461 fatal("%s: waitpid: %s", __func__, strerror(errno)); 462 } 463 if (!WIFEXITED(status)) { 464 error("command '%.100s' exited abnormally", cmd); 465 return -1; 466 } 467 debug3("command returned status %d", WEXITSTATUS(status)); 468 return WEXITSTATUS(status); 469} 470 471/* 472 * Parse and execute a Match directive. 473 */ 474static int 475match_cfg_line(Options *options, char **condition, struct passwd *pw, 476 const char *host_arg, const char *filename, int linenum) 477{ 478 char *arg, *attrib, *cmd, *cp = *condition, *host; 479 const char *ruser; 480 int r, port, result = 1, attributes = 0; 481 size_t len; 482 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 483 484 /* 485 * Configuration is likely to be incomplete at this point so we 486 * must be prepared to use default values. 487 */ 488 port = options->port <= 0 ? default_ssh_port() : options->port; 489 ruser = options->user == NULL ? pw->pw_name : options->user; 490 if (options->hostname != NULL) { 491 /* NB. Please keep in sync with ssh.c:main() */ 492 host = percent_expand(options->hostname, 493 "h", host_arg, (char *)NULL); 494 } else 495 host = xstrdup(host_arg); 496 497 debug3("checking match for '%s' host %s", cp, host); 498 while ((attrib = strdelim(&cp)) && *attrib != '\0') { 499 attributes++; 500 if (strcasecmp(attrib, "all") == 0) { 501 if (attributes != 1 || 502 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 503 error("'all' cannot be combined with other " 504 "Match attributes"); 505 result = -1; 506 goto out; 507 } 508 *condition = cp; 509 result = 1; 510 goto out; 511 } 512 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 513 error("Missing Match criteria for %s", attrib); 514 result = -1; 515 goto out; 516 } 517 len = strlen(arg); 518 if (strcasecmp(attrib, "host") == 0) { 519 if (match_hostname(host, arg, len) != 1) 520 result = 0; 521 else 522 debug("%.200s line %d: matched 'Host %.100s' ", 523 filename, linenum, host); 524 } else if (strcasecmp(attrib, "originalhost") == 0) { 525 if (match_hostname(host_arg, arg, len) != 1) 526 result = 0; 527 else 528 debug("%.200s line %d: matched " 529 "'OriginalHost %.100s' ", 530 filename, linenum, host_arg); 531 } else if (strcasecmp(attrib, "user") == 0) { 532 if (match_pattern_list(ruser, arg, len, 0) != 1) 533 result = 0; 534 else 535 debug("%.200s line %d: matched 'User %.100s' ", 536 filename, linenum, ruser); 537 } else if (strcasecmp(attrib, "localuser") == 0) { 538 if (match_pattern_list(pw->pw_name, arg, len, 0) != 1) 539 result = 0; 540 else 541 debug("%.200s line %d: matched " 542 "'LocalUser %.100s' ", 543 filename, linenum, pw->pw_name); 544 } else if (strcasecmp(attrib, "exec") == 0) { 545 if (gethostname(thishost, sizeof(thishost)) == -1) 546 fatal("gethostname: %s", strerror(errno)); 547 strlcpy(shorthost, thishost, sizeof(shorthost)); 548 shorthost[strcspn(thishost, ".")] = '\0'; 549 snprintf(portstr, sizeof(portstr), "%d", port); 550 551 cmd = percent_expand(arg, 552 "L", shorthost, 553 "d", pw->pw_dir, 554 "h", host, 555 "l", thishost, 556 "n", host_arg, 557 "p", portstr, 558 "r", ruser, 559 "u", pw->pw_name, 560 (char *)NULL); 561 if (result != 1) { 562 /* skip execution if prior predicate failed */ 563 debug("%.200s line %d: skipped exec \"%.100s\"", 564 filename, linenum, cmd); 565 } else { 566 r = execute_in_shell(cmd); 567 if (r == -1) { 568 fatal("%.200s line %d: match exec " 569 "'%.100s' error", filename, 570 linenum, cmd); 571 } else if (r == 0) { 572 debug("%.200s line %d: matched " 573 "'exec \"%.100s\"'", filename, 574 linenum, cmd); 575 } else { 576 debug("%.200s line %d: no match " 577 "'exec \"%.100s\"'", filename, 578 linenum, cmd); 579 result = 0; 580 } 581 } 582 free(cmd); 583 } else { 584 error("Unsupported Match attribute %s", attrib); 585 result = -1; 586 goto out; 587 } 588 } 589 if (attributes == 0) { 590 error("One or more attributes required for Match"); 591 result = -1; 592 goto out; 593 } 594 debug3("match %sfound", result ? "" : "not "); 595 *condition = cp; 596 out: 597 free(host); 598 return result; 599} 600 601/* Check and prepare a domain name: removes trailing '.' and lowercases */ 602static void 603valid_domain(char *name, const char *filename, int linenum) 604{ 605 size_t i, l = strlen(name); 606 u_char c, last = '\0'; 607 608 if (l == 0) 609 fatal("%s line %d: empty hostname suffix", filename, linenum); 610 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) 611 fatal("%s line %d: hostname suffix \"%.100s\" " 612 "starts with invalid character", filename, linenum, name); 613 for (i = 0; i < l; i++) { 614 c = tolower((u_char)name[i]); 615 name[i] = (char)c; 616 if (last == '.' && c == '.') 617 fatal("%s line %d: hostname suffix \"%.100s\" contains " 618 "consecutive separators", filename, linenum, name); 619 if (c != '.' && c != '-' && !isalnum(c) && 620 c != '_') /* technically invalid, but common */ 621 fatal("%s line %d: hostname suffix \"%.100s\" contains " 622 "invalid characters", filename, linenum, name); 623 last = c; 624 } 625 if (name[l - 1] == '.') 626 name[l - 1] = '\0'; 627} 628 629/* 630 * Returns the number of the token pointed to by cp or oBadOption. 631 */ 632static OpCodes 633parse_token(const char *cp, const char *filename, int linenum, 634 const char *ignored_unknown) 635{ 636 int i; 637 638 for (i = 0; keywords[i].name; i++) 639 if (strcmp(cp, keywords[i].name) == 0) 640 return keywords[i].opcode; 641 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown, 642 strlen(ignored_unknown), 1) == 1) 643 return oIgnoredUnknownOption; 644 error("%s: line %d: Bad configuration option: %s", 645 filename, linenum, cp); 646 return oBadOption; 647} 648 649/* Multistate option parsing */ 650struct multistate { 651 char *key; 652 int value; 653}; 654static const struct multistate multistate_flag[] = { 655 { "true", 1 }, 656 { "false", 0 }, 657 { "yes", 1 }, 658 { "no", 0 }, 659 { NULL, -1 } 660}; 661static const struct multistate multistate_yesnoask[] = { 662 { "true", 1 }, 663 { "false", 0 }, 664 { "yes", 1 }, 665 { "no", 0 }, 666 { "ask", 2 }, 667 { NULL, -1 } 668}; 669static const struct multistate multistate_addressfamily[] = { 670 { "inet", AF_INET }, 671 { "inet6", AF_INET6 }, 672 { "any", AF_UNSPEC }, 673 { NULL, -1 } 674}; 675static const struct multistate multistate_controlmaster[] = { 676 { "true", SSHCTL_MASTER_YES }, 677 { "yes", SSHCTL_MASTER_YES }, 678 { "false", SSHCTL_MASTER_NO }, 679 { "no", SSHCTL_MASTER_NO }, 680 { "auto", SSHCTL_MASTER_AUTO }, 681 { "ask", SSHCTL_MASTER_ASK }, 682 { "autoask", SSHCTL_MASTER_AUTO_ASK }, 683 { NULL, -1 } 684}; 685static const struct multistate multistate_tunnel[] = { 686 { "ethernet", SSH_TUNMODE_ETHERNET }, 687 { "point-to-point", SSH_TUNMODE_POINTOPOINT }, 688 { "true", SSH_TUNMODE_DEFAULT }, 689 { "yes", SSH_TUNMODE_DEFAULT }, 690 { "false", SSH_TUNMODE_NO }, 691 { "no", SSH_TUNMODE_NO }, 692 { NULL, -1 } 693}; 694static const struct multistate multistate_requesttty[] = { 695 { "true", REQUEST_TTY_YES }, 696 { "yes", REQUEST_TTY_YES }, 697 { "false", REQUEST_TTY_NO }, 698 { "no", REQUEST_TTY_NO }, 699 { "force", REQUEST_TTY_FORCE }, 700 { "auto", REQUEST_TTY_AUTO }, 701 { NULL, -1 } 702}; 703static const struct multistate multistate_canonicalizehostname[] = { 704 { "true", SSH_CANONICALISE_YES }, 705 { "false", SSH_CANONICALISE_NO }, 706 { "yes", SSH_CANONICALISE_YES }, 707 { "no", SSH_CANONICALISE_NO }, 708 { "always", SSH_CANONICALISE_ALWAYS }, 709 { NULL, -1 } 710}; 711 712/* 713 * Processes a single option line as used in the configuration files. This 714 * only sets those values that have not already been set. 715 */ 716#define WHITESPACE " \t\r\n" 717int 718process_config_line(Options *options, struct passwd *pw, const char *host, 719 char *line, const char *filename, int linenum, int *activep, int userconfig) 720{ 721 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 722 char **cpptr, fwdarg[256]; 723 u_int i, *uintptr, max_entries = 0; 724 int negated, opcode, *intptr, value, value2, cmdline = 0; 725 LogLevel *log_level_ptr; 726 long long val64; 727 size_t len; 728 Forward fwd; 729 const struct multistate *multistate_ptr; 730 struct allowed_cname *cname; 731 732 if (activep == NULL) { /* We are processing a command line directive */ 733 cmdline = 1; 734 activep = &cmdline; 735 } 736 737 /* Strip trailing whitespace */ 738 for (len = strlen(line) - 1; len > 0; len--) { 739 if (strchr(WHITESPACE, line[len]) == NULL) 740 break; 741 line[len] = '\0'; 742 } 743 744 s = line; 745 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 746 if ((keyword = strdelim(&s)) == NULL) 747 return 0; 748 /* Ignore leading whitespace. */ 749 if (*keyword == '\0') 750 keyword = strdelim(&s); 751 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 752 return 0; 753 /* Match lowercase keyword */ 754 lowercase(keyword); 755 756 opcode = parse_token(keyword, filename, linenum, 757 options->ignored_unknown); 758 759 switch (opcode) { 760 case oBadOption: 761 /* don't panic, but count bad options */ 762 return -1; 763 /* NOTREACHED */ 764 case oIgnoredUnknownOption: 765 debug("%s line %d: Ignored unknown option \"%s\"", 766 filename, linenum, keyword); 767 return 0; 768 case oConnectTimeout: 769 intptr = &options->connection_timeout; 770parse_time: 771 arg = strdelim(&s); 772 if (!arg || *arg == '\0') 773 fatal("%s line %d: missing time value.", 774 filename, linenum); 775 if ((value = convtime(arg)) == -1) 776 fatal("%s line %d: invalid time value.", 777 filename, linenum); 778 if (*activep && *intptr == -1) 779 *intptr = value; 780 break; 781 782 case oForwardAgent: 783 intptr = &options->forward_agent; 784 parse_flag: 785 multistate_ptr = multistate_flag; 786 parse_multistate: 787 arg = strdelim(&s); 788 if (!arg || *arg == '\0') 789 fatal("%s line %d: missing argument.", 790 filename, linenum); 791 value = -1; 792 for (i = 0; multistate_ptr[i].key != NULL; i++) { 793 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 794 value = multistate_ptr[i].value; 795 break; 796 } 797 } 798 if (value == -1) 799 fatal("%s line %d: unsupported option \"%s\".", 800 filename, linenum, arg); 801 if (*activep && *intptr == -1) 802 *intptr = value; 803 break; 804 805 case oForwardX11: 806 intptr = &options->forward_x11; 807 goto parse_flag; 808 809 case oForwardX11Trusted: 810 intptr = &options->forward_x11_trusted; 811 goto parse_flag; 812 813 case oForwardX11Timeout: 814 intptr = &options->forward_x11_timeout; 815 goto parse_time; 816 817 case oGatewayPorts: 818 intptr = &options->gateway_ports; 819 goto parse_flag; 820 821 case oExitOnForwardFailure: 822 intptr = &options->exit_on_forward_failure; 823 goto parse_flag; 824 825 case oUsePrivilegedPort: 826 intptr = &options->use_privileged_port; 827 goto parse_flag; 828 829 case oPasswordAuthentication: 830 intptr = &options->password_authentication; 831 goto parse_flag; 832 833 case oKbdInteractiveAuthentication: 834 intptr = &options->kbd_interactive_authentication; 835 goto parse_flag; 836 837 case oKbdInteractiveDevices: 838 charptr = &options->kbd_interactive_devices; 839 goto parse_string; 840 841 case oPubkeyAuthentication: 842 intptr = &options->pubkey_authentication; 843 goto parse_flag; 844 845 case oRSAAuthentication: 846 intptr = &options->rsa_authentication; 847 goto parse_flag; 848 849 case oRhostsRSAAuthentication: 850 intptr = &options->rhosts_rsa_authentication; 851 goto parse_flag; 852 853 case oHostbasedAuthentication: 854 intptr = &options->hostbased_authentication; 855 goto parse_flag; 856 857 case oChallengeResponseAuthentication: 858 intptr = &options->challenge_response_authentication; 859 goto parse_flag; 860 861 case oGssAuthentication: 862 intptr = &options->gss_authentication; 863 goto parse_flag; 864 865 case oGssDelegateCreds: 866 intptr = &options->gss_deleg_creds; 867 goto parse_flag; 868 869 case oBatchMode: 870 intptr = &options->batch_mode; 871 goto parse_flag; 872 873 case oCheckHostIP: 874 intptr = &options->check_host_ip; 875 goto parse_flag; 876 877 case oVerifyHostKeyDNS: 878 intptr = &options->verify_host_key_dns; 879 multistate_ptr = multistate_yesnoask; 880 goto parse_multistate; 881 882 case oStrictHostKeyChecking: 883 intptr = &options->strict_host_key_checking; 884 multistate_ptr = multistate_yesnoask; 885 goto parse_multistate; 886 887 case oCompression: 888 intptr = &options->compression; 889 goto parse_flag; 890 891 case oTCPKeepAlive: 892 intptr = &options->tcp_keep_alive; 893 goto parse_flag; 894 895 case oNoHostAuthenticationForLocalhost: 896 intptr = &options->no_host_authentication_for_localhost; 897 goto parse_flag; 898 899 case oNumberOfPasswordPrompts: 900 intptr = &options->number_of_password_prompts; 901 goto parse_int; 902 903 case oCompressionLevel: 904 intptr = &options->compression_level; 905 goto parse_int; 906 907 case oRekeyLimit: 908 arg = strdelim(&s); 909 if (!arg || *arg == '\0') 910 fatal("%.200s line %d: Missing argument.", filename, 911 linenum); 912 if (strcmp(arg, "default") == 0) { 913 val64 = 0; 914 } else { 915 if (scan_scaled(arg, &val64) == -1) 916 fatal("%.200s line %d: Bad number '%s': %s", 917 filename, linenum, arg, strerror(errno)); 918 /* check for too-large or too-small limits */ 919 if (val64 > UINT_MAX) 920 fatal("%.200s line %d: RekeyLimit too large", 921 filename, linenum); 922 if (val64 != 0 && val64 < 16) 923 fatal("%.200s line %d: RekeyLimit too small", 924 filename, linenum); 925 } 926 if (*activep && options->rekey_limit == -1) 927 options->rekey_limit = (u_int32_t)val64; 928 if (s != NULL) { /* optional rekey interval present */ 929 if (strcmp(s, "none") == 0) { 930 (void)strdelim(&s); /* discard */ 931 break; 932 } 933 intptr = &options->rekey_interval; 934 goto parse_time; 935 } 936 break; 937 938 case oIdentityFile: 939 arg = strdelim(&s); 940 if (!arg || *arg == '\0') 941 fatal("%.200s line %d: Missing argument.", filename, linenum); 942 if (*activep) { 943 intptr = &options->num_identity_files; 944 if (*intptr >= SSH_MAX_IDENTITY_FILES) 945 fatal("%.200s line %d: Too many identity files specified (max %d).", 946 filename, linenum, SSH_MAX_IDENTITY_FILES); 947 add_identity_file(options, NULL, arg, userconfig); 948 } 949 break; 950 951 case oXAuthLocation: 952 charptr=&options->xauth_location; 953 goto parse_string; 954 955 case oUser: 956 charptr = &options->user; 957parse_string: 958 arg = strdelim(&s); 959 if (!arg || *arg == '\0') 960 fatal("%.200s line %d: Missing argument.", 961 filename, linenum); 962 if (*activep && *charptr == NULL) 963 *charptr = xstrdup(arg); 964 break; 965 966 case oGlobalKnownHostsFile: 967 cpptr = (char **)&options->system_hostfiles; 968 uintptr = &options->num_system_hostfiles; 969 max_entries = SSH_MAX_HOSTS_FILES; 970parse_char_array: 971 if (*activep && *uintptr == 0) { 972 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 973 if ((*uintptr) >= max_entries) 974 fatal("%s line %d: " 975 "too many authorized keys files.", 976 filename, linenum); 977 cpptr[(*uintptr)++] = xstrdup(arg); 978 } 979 } 980 return 0; 981 982 case oUserKnownHostsFile: 983 cpptr = (char **)&options->user_hostfiles; 984 uintptr = &options->num_user_hostfiles; 985 max_entries = SSH_MAX_HOSTS_FILES; 986 goto parse_char_array; 987 988 case oHostName: 989 charptr = &options->hostname; 990 goto parse_string; 991 992 case oHostKeyAlias: 993 charptr = &options->host_key_alias; 994 goto parse_string; 995 996 case oPreferredAuthentications: 997 charptr = &options->preferred_authentications; 998 goto parse_string; 999 1000 case oBindAddress: 1001 charptr = &options->bind_address; 1002 goto parse_string; 1003 1004 case oPKCS11Provider: 1005 charptr = &options->pkcs11_provider; 1006 goto parse_string; 1007 1008 case oProxyCommand: 1009 charptr = &options->proxy_command; 1010parse_command: 1011 if (s == NULL) 1012 fatal("%.200s line %d: Missing argument.", filename, linenum); 1013 len = strspn(s, WHITESPACE "="); 1014 if (*activep && *charptr == NULL) 1015 *charptr = xstrdup(s + len); 1016 return 0; 1017 1018 case oPort: 1019 intptr = &options->port; 1020parse_int: 1021 arg = strdelim(&s); 1022 if (!arg || *arg == '\0') 1023 fatal("%.200s line %d: Missing argument.", filename, linenum); 1024 if (arg[0] < '0' || arg[0] > '9') 1025 fatal("%.200s line %d: Bad number.", filename, linenum); 1026 1027 /* Octal, decimal, or hex format? */ 1028 value = strtol(arg, &endofnumber, 0); 1029 if (arg == endofnumber) 1030 fatal("%.200s line %d: Bad number.", filename, linenum); 1031 if (*activep && *intptr == -1) 1032 *intptr = value; 1033 break; 1034 1035 case oConnectionAttempts: 1036 intptr = &options->connection_attempts; 1037 goto parse_int; 1038 1039 case oCipher: 1040 intptr = &options->cipher; 1041 arg = strdelim(&s); 1042 if (!arg || *arg == '\0') 1043 fatal("%.200s line %d: Missing argument.", filename, linenum); 1044 value = cipher_number(arg); 1045 if (value == -1) 1046 fatal("%.200s line %d: Bad cipher '%s'.", 1047 filename, linenum, arg ? arg : "<NONE>"); 1048 if (*activep && *intptr == -1) 1049 *intptr = value; 1050 break; 1051 1052 case oCiphers: 1053 arg = strdelim(&s); 1054 if (!arg || *arg == '\0') 1055 fatal("%.200s line %d: Missing argument.", filename, linenum); 1056 if (!ciphers_valid(arg)) 1057 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 1058 filename, linenum, arg ? arg : "<NONE>"); 1059 if (*activep && options->ciphers == NULL) 1060 options->ciphers = xstrdup(arg); 1061 break; 1062 1063 case oMacs: 1064 arg = strdelim(&s); 1065 if (!arg || *arg == '\0') 1066 fatal("%.200s line %d: Missing argument.", filename, linenum); 1067 if (!mac_valid(arg)) 1068 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 1069 filename, linenum, arg ? arg : "<NONE>"); 1070 if (*activep && options->macs == NULL) 1071 options->macs = xstrdup(arg); 1072 break; 1073 1074 case oKexAlgorithms: 1075 arg = strdelim(&s); 1076 if (!arg || *arg == '\0') 1077 fatal("%.200s line %d: Missing argument.", 1078 filename, linenum); 1079 if (!kex_names_valid(arg)) 1080 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 1081 filename, linenum, arg ? arg : "<NONE>"); 1082 if (*activep && options->kex_algorithms == NULL) 1083 options->kex_algorithms = xstrdup(arg); 1084 break; 1085 1086 case oHostKeyAlgorithms: 1087 arg = strdelim(&s); 1088 if (!arg || *arg == '\0') 1089 fatal("%.200s line %d: Missing argument.", filename, linenum); 1090 if (!key_names_valid2(arg)) 1091 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 1092 filename, linenum, arg ? arg : "<NONE>"); 1093 if (*activep && options->hostkeyalgorithms == NULL) 1094 options->hostkeyalgorithms = xstrdup(arg); 1095 break; 1096 1097 case oProtocol: 1098 intptr = &options->protocol; 1099 arg = strdelim(&s); 1100 if (!arg || *arg == '\0') 1101 fatal("%.200s line %d: Missing argument.", filename, linenum); 1102 value = proto_spec(arg); 1103 if (value == SSH_PROTO_UNKNOWN) 1104 fatal("%.200s line %d: Bad protocol spec '%s'.", 1105 filename, linenum, arg ? arg : "<NONE>"); 1106 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 1107 *intptr = value; 1108 break; 1109 1110 case oLogLevel: 1111 log_level_ptr = &options->log_level; 1112 arg = strdelim(&s); 1113 value = log_level_number(arg); 1114 if (value == SYSLOG_LEVEL_NOT_SET) 1115 fatal("%.200s line %d: unsupported log level '%s'", 1116 filename, linenum, arg ? arg : "<NONE>"); 1117 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 1118 *log_level_ptr = (LogLevel) value; 1119 break; 1120 1121 case oLocalForward: 1122 case oRemoteForward: 1123 case oDynamicForward: 1124 arg = strdelim(&s); 1125 if (arg == NULL || *arg == '\0') 1126 fatal("%.200s line %d: Missing port argument.", 1127 filename, linenum); 1128 1129 if (opcode == oLocalForward || 1130 opcode == oRemoteForward) { 1131 arg2 = strdelim(&s); 1132 if (arg2 == NULL || *arg2 == '\0') 1133 fatal("%.200s line %d: Missing target argument.", 1134 filename, linenum); 1135 1136 /* construct a string for parse_forward */ 1137 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 1138 } else if (opcode == oDynamicForward) { 1139 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1140 } 1141 1142 if (parse_forward(&fwd, fwdarg, 1143 opcode == oDynamicForward ? 1 : 0, 1144 opcode == oRemoteForward ? 1 : 0) == 0) 1145 fatal("%.200s line %d: Bad forwarding specification.", 1146 filename, linenum); 1147 1148 if (*activep) { 1149 if (opcode == oLocalForward || 1150 opcode == oDynamicForward) 1151 add_local_forward(options, &fwd); 1152 else if (opcode == oRemoteForward) 1153 add_remote_forward(options, &fwd); 1154 } 1155 break; 1156 1157 case oClearAllForwardings: 1158 intptr = &options->clear_forwardings; 1159 goto parse_flag; 1160 1161 case oHost: 1162 if (cmdline) 1163 fatal("Host directive not supported as a command-line " 1164 "option"); 1165 *activep = 0; 1166 arg2 = NULL; 1167 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1168 negated = *arg == '!'; 1169 if (negated) 1170 arg++; 1171 if (match_pattern(host, arg)) { 1172 if (negated) { 1173 debug("%.200s line %d: Skipping Host " 1174 "block because of negated match " 1175 "for %.100s", filename, linenum, 1176 arg); 1177 *activep = 0; 1178 break; 1179 } 1180 if (!*activep) 1181 arg2 = arg; /* logged below */ 1182 *activep = 1; 1183 } 1184 } 1185 if (*activep) 1186 debug("%.200s line %d: Applying options for %.100s", 1187 filename, linenum, arg2); 1188 /* Avoid garbage check below, as strdelim is done. */ 1189 return 0; 1190 1191 case oMatch: 1192 if (cmdline) 1193 fatal("Host directive not supported as a command-line " 1194 "option"); 1195 value = match_cfg_line(options, &s, pw, host, 1196 filename, linenum); 1197 if (value < 0) 1198 fatal("%.200s line %d: Bad Match condition", filename, 1199 linenum); 1200 *activep = value; 1201 break; 1202 1203 case oEscapeChar: 1204 intptr = &options->escape_char; 1205 arg = strdelim(&s); 1206 if (!arg || *arg == '\0') 1207 fatal("%.200s line %d: Missing argument.", filename, linenum); 1208 if (arg[0] == '^' && arg[2] == 0 && 1209 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 1210 value = (u_char) arg[1] & 31; 1211 else if (strlen(arg) == 1) 1212 value = (u_char) arg[0]; 1213 else if (strcmp(arg, "none") == 0) 1214 value = SSH_ESCAPECHAR_NONE; 1215 else { 1216 fatal("%.200s line %d: Bad escape character.", 1217 filename, linenum); 1218 /* NOTREACHED */ 1219 value = 0; /* Avoid compiler warning. */ 1220 } 1221 if (*activep && *intptr == -1) 1222 *intptr = value; 1223 break; 1224 1225 case oAddressFamily: 1226 intptr = &options->address_family; 1227 multistate_ptr = multistate_addressfamily; 1228 goto parse_multistate; 1229 1230 case oEnableSSHKeysign: 1231 intptr = &options->enable_ssh_keysign; 1232 goto parse_flag; 1233 1234 case oIdentitiesOnly: 1235 intptr = &options->identities_only; 1236 goto parse_flag; 1237 1238 case oServerAliveInterval: 1239 intptr = &options->server_alive_interval; 1240 goto parse_time; 1241 1242 case oServerAliveCountMax: 1243 intptr = &options->server_alive_count_max; 1244 goto parse_int; 1245 1246 case oSendEnv: 1247 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1248 if (strchr(arg, '=') != NULL) 1249 fatal("%s line %d: Invalid environment name.", 1250 filename, linenum); 1251 if (!*activep) 1252 continue; 1253 if (options->num_send_env >= MAX_SEND_ENV) 1254 fatal("%s line %d: too many send env.", 1255 filename, linenum); 1256 options->send_env[options->num_send_env++] = 1257 xstrdup(arg); 1258 } 1259 break; 1260 1261 case oControlPath: 1262 charptr = &options->control_path; 1263 goto parse_string; 1264 1265 case oControlMaster: 1266 intptr = &options->control_master; 1267 multistate_ptr = multistate_controlmaster; 1268 goto parse_multistate; 1269 1270 case oControlPersist: 1271 /* no/false/yes/true, or a time spec */ 1272 intptr = &options->control_persist; 1273 arg = strdelim(&s); 1274 if (!arg || *arg == '\0') 1275 fatal("%.200s line %d: Missing ControlPersist" 1276 " argument.", filename, linenum); 1277 value = 0; 1278 value2 = 0; /* timeout */ 1279 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 1280 value = 0; 1281 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 1282 value = 1; 1283 else if ((value2 = convtime(arg)) >= 0) 1284 value = 1; 1285 else 1286 fatal("%.200s line %d: Bad ControlPersist argument.", 1287 filename, linenum); 1288 if (*activep && *intptr == -1) { 1289 *intptr = value; 1290 options->control_persist_timeout = value2; 1291 } 1292 break; 1293 1294 case oHashKnownHosts: 1295 intptr = &options->hash_known_hosts; 1296 goto parse_flag; 1297 1298 case oTunnel: 1299 intptr = &options->tun_open; 1300 multistate_ptr = multistate_tunnel; 1301 goto parse_multistate; 1302 1303 case oTunnelDevice: 1304 arg = strdelim(&s); 1305 if (!arg || *arg == '\0') 1306 fatal("%.200s line %d: Missing argument.", filename, linenum); 1307 value = a2tun(arg, &value2); 1308 if (value == SSH_TUNID_ERR) 1309 fatal("%.200s line %d: Bad tun device.", filename, linenum); 1310 if (*activep) { 1311 options->tun_local = value; 1312 options->tun_remote = value2; 1313 } 1314 break; 1315 1316 case oLocalCommand: 1317 charptr = &options->local_command; 1318 goto parse_command; 1319 1320 case oPermitLocalCommand: 1321 intptr = &options->permit_local_command; 1322 goto parse_flag; 1323 1324 case oVisualHostKey: 1325 intptr = &options->visual_host_key; 1326 goto parse_flag; 1327 1328 case oIPQoS: 1329 arg = strdelim(&s); 1330 if ((value = parse_ipqos(arg)) == -1) 1331 fatal("%s line %d: Bad IPQoS value: %s", 1332 filename, linenum, arg); 1333 arg = strdelim(&s); 1334 if (arg == NULL) 1335 value2 = value; 1336 else if ((value2 = parse_ipqos(arg)) == -1) 1337 fatal("%s line %d: Bad IPQoS value: %s", 1338 filename, linenum, arg); 1339 if (*activep) { 1340 options->ip_qos_interactive = value; 1341 options->ip_qos_bulk = value2; 1342 } 1343 break; 1344 1345 case oUseRoaming: 1346 intptr = &options->use_roaming; 1347 goto parse_flag; 1348 1349 case oRequestTTY: 1350 intptr = &options->request_tty; 1351 multistate_ptr = multistate_requesttty; 1352 goto parse_multistate; 1353 1354 case oVersionAddendum: 1355 if (s == NULL) 1356 fatal("%.200s line %d: Missing argument.", filename, 1357 linenum); 1358 len = strspn(s, WHITESPACE); 1359 if (*activep && options->version_addendum == NULL) { 1360 if (strcasecmp(s + len, "none") == 0) 1361 options->version_addendum = xstrdup(""); 1362 else if (strchr(s + len, '\r') != NULL) 1363 fatal("%.200s line %d: Invalid argument", 1364 filename, linenum); 1365 else 1366 options->version_addendum = xstrdup(s + len); 1367 } 1368 return 0; 1369 1370 case oIgnoreUnknown: 1371 charptr = &options->ignored_unknown; 1372 goto parse_string; 1373 1374 case oProxyUseFdpass: 1375 intptr = &options->proxy_use_fdpass; 1376 goto parse_flag; 1377 1378 case oCanonicalDomains: 1379 value = options->num_canonical_domains != 0; 1380 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1381 valid_domain(arg, filename, linenum); 1382 if (!*activep || value) 1383 continue; 1384 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1385 fatal("%s line %d: too many hostname suffixes.", 1386 filename, linenum); 1387 options->canonical_domains[ 1388 options->num_canonical_domains++] = xstrdup(arg); 1389 } 1390 break; 1391 1392 case oCanonicalizePermittedCNAMEs: 1393 value = options->num_permitted_cnames != 0; 1394 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1395 /* Either '*' for everything or 'list:list' */ 1396 if (strcmp(arg, "*") == 0) 1397 arg2 = arg; 1398 else { 1399 lowercase(arg); 1400 if ((arg2 = strchr(arg, ':')) == NULL || 1401 arg2[1] == '\0') { 1402 fatal("%s line %d: " 1403 "Invalid permitted CNAME \"%s\"", 1404 filename, linenum, arg); 1405 } 1406 *arg2 = '\0'; 1407 arg2++; 1408 } 1409 if (!*activep || value) 1410 continue; 1411 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1412 fatal("%s line %d: too many permitted CNAMEs.", 1413 filename, linenum); 1414 cname = options->permitted_cnames + 1415 options->num_permitted_cnames++; 1416 cname->source_list = xstrdup(arg); 1417 cname->target_list = xstrdup(arg2); 1418 } 1419 break; 1420 1421 case oCanonicalizeHostname: 1422 intptr = &options->canonicalize_hostname; 1423 multistate_ptr = multistate_canonicalizehostname; 1424 goto parse_multistate; 1425 1426 case oCanonicalizeMaxDots: 1427 intptr = &options->canonicalize_max_dots; 1428 goto parse_int; 1429 1430 case oCanonicalizeFallbackLocal: 1431 intptr = &options->canonicalize_fallback_local; 1432 goto parse_flag; 1433 1434 case oDeprecated: 1435 debug("%s line %d: Deprecated option \"%s\"", 1436 filename, linenum, keyword); 1437 return 0; 1438 1439 case oUnsupported: 1440 error("%s line %d: Unsupported option \"%s\"", 1441 filename, linenum, keyword); 1442 return 0; 1443 1444 default: 1445 fatal("process_config_line: Unimplemented opcode %d", opcode); 1446 } 1447 1448 /* Check that there is no garbage at end of line. */ 1449 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1450 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1451 filename, linenum, arg); 1452 } 1453 return 0; 1454} 1455 1456 1457/* 1458 * Reads the config file and modifies the options accordingly. Options 1459 * should already be initialized before this call. This never returns if 1460 * there is an error. If the file does not exist, this returns 0. 1461 */ 1462 1463int 1464read_config_file(const char *filename, struct passwd *pw, const char *host, 1465 Options *options, int flags) 1466{ 1467 FILE *f; 1468 char line[1024]; 1469 int active, linenum; 1470 int bad_options = 0; 1471 1472 if ((f = fopen(filename, "r")) == NULL) 1473 return 0; 1474 1475 if (flags & SSHCONF_CHECKPERM) { 1476 struct stat sb; 1477 1478 if (fstat(fileno(f), &sb) == -1) 1479 fatal("fstat %s: %s", filename, strerror(errno)); 1480 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 1481 (sb.st_mode & 022) != 0)) 1482 fatal("Bad owner or permissions on %s", filename); 1483 } 1484 1485 debug("Reading configuration data %.200s", filename); 1486 1487 /* 1488 * Mark that we are now processing the options. This flag is turned 1489 * on/off by Host specifications. 1490 */ 1491 active = 1; 1492 linenum = 0; 1493 while (fgets(line, sizeof(line), f)) { 1494 /* Update line number counter. */ 1495 linenum++; 1496 if (process_config_line(options, pw, host, line, filename, 1497 linenum, &active, flags & SSHCONF_USERCONF) != 0) 1498 bad_options++; 1499 } 1500 fclose(f); 1501 if (bad_options > 0) 1502 fatal("%s: terminating, %d bad configuration options", 1503 filename, bad_options); 1504 return 1; 1505} 1506 1507/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 1508int 1509option_clear_or_none(const char *o) 1510{ 1511 return o == NULL || strcasecmp(o, "none") == 0; 1512} 1513 1514/* 1515 * Initializes options to special values that indicate that they have not yet 1516 * been set. Read_config_file will only set options with this value. Options 1517 * are processed in the following order: command line, user config file, 1518 * system config file. Last, fill_default_options is called. 1519 */ 1520 1521void 1522initialize_options(Options * options) 1523{ 1524 memset(options, 'X', sizeof(*options)); 1525 options->forward_agent = -1; 1526 options->forward_x11 = -1; 1527 options->forward_x11_trusted = -1; 1528 options->forward_x11_timeout = -1; 1529 options->exit_on_forward_failure = -1; 1530 options->xauth_location = NULL; 1531 options->gateway_ports = -1; 1532 options->use_privileged_port = -1; 1533 options->rsa_authentication = -1; 1534 options->pubkey_authentication = -1; 1535 options->challenge_response_authentication = -1; 1536 options->gss_authentication = -1; 1537 options->gss_deleg_creds = -1; 1538 options->password_authentication = -1; 1539 options->kbd_interactive_authentication = -1; 1540 options->kbd_interactive_devices = NULL; 1541 options->rhosts_rsa_authentication = -1; 1542 options->hostbased_authentication = -1; 1543 options->batch_mode = -1; 1544 options->check_host_ip = -1; 1545 options->strict_host_key_checking = -1; 1546 options->compression = -1; 1547 options->tcp_keep_alive = -1; 1548 options->compression_level = -1; 1549 options->port = -1; 1550 options->address_family = -1; 1551 options->connection_attempts = -1; 1552 options->connection_timeout = -1; 1553 options->number_of_password_prompts = -1; 1554 options->cipher = -1; 1555 options->ciphers = NULL; 1556 options->macs = NULL; 1557 options->kex_algorithms = NULL; 1558 options->hostkeyalgorithms = NULL; 1559 options->protocol = SSH_PROTO_UNKNOWN; 1560 options->num_identity_files = 0; 1561 options->hostname = NULL; 1562 options->host_key_alias = NULL; 1563 options->proxy_command = NULL; 1564 options->user = NULL; 1565 options->escape_char = -1; 1566 options->num_system_hostfiles = 0; 1567 options->num_user_hostfiles = 0; 1568 options->local_forwards = NULL; 1569 options->num_local_forwards = 0; 1570 options->remote_forwards = NULL; 1571 options->num_remote_forwards = 0; 1572 options->clear_forwardings = -1; 1573 options->log_level = SYSLOG_LEVEL_NOT_SET; 1574 options->preferred_authentications = NULL; 1575 options->bind_address = NULL; 1576 options->pkcs11_provider = NULL; 1577 options->enable_ssh_keysign = - 1; 1578 options->no_host_authentication_for_localhost = - 1; 1579 options->identities_only = - 1; 1580 options->rekey_limit = - 1; 1581 options->rekey_interval = -1; 1582 options->verify_host_key_dns = -1; 1583 options->server_alive_interval = -1; 1584 options->server_alive_count_max = -1; 1585 options->num_send_env = 0; 1586 options->control_path = NULL; 1587 options->control_master = -1; 1588 options->control_persist = -1; 1589 options->control_persist_timeout = 0; 1590 options->hash_known_hosts = -1; 1591 options->tun_open = -1; 1592 options->tun_local = -1; 1593 options->tun_remote = -1; 1594 options->local_command = NULL; 1595 options->permit_local_command = -1; 1596 options->use_roaming = 0; 1597 options->visual_host_key = -1; 1598 options->ip_qos_interactive = -1; 1599 options->ip_qos_bulk = -1; 1600 options->request_tty = -1; 1601 options->proxy_use_fdpass = -1; 1602 options->ignored_unknown = NULL; 1603 options->num_canonical_domains = 0; 1604 options->num_permitted_cnames = 0; 1605 options->canonicalize_max_dots = -1; 1606 options->canonicalize_fallback_local = -1; 1607 options->canonicalize_hostname = -1; 1608 options->version_addendum = NULL; 1609} 1610 1611/* 1612 * A petite version of fill_default_options() that just fills the options 1613 * needed for hostname canonicalization to proceed. 1614 */ 1615void 1616fill_default_options_for_canonicalization(Options *options) 1617{ 1618 if (options->canonicalize_max_dots == -1) 1619 options->canonicalize_max_dots = 1; 1620 if (options->canonicalize_fallback_local == -1) 1621 options->canonicalize_fallback_local = 1; 1622 if (options->canonicalize_hostname == -1) 1623 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1624} 1625 1626/* 1627 * Called after processing other sources of option data, this fills those 1628 * options for which no value has been specified with their default values. 1629 */ 1630void 1631fill_default_options(Options * options) 1632{ 1633 if (options->forward_agent == -1) 1634 options->forward_agent = 0; 1635 if (options->forward_x11 == -1) 1636 options->forward_x11 = 0; 1637 if (options->forward_x11_trusted == -1) 1638 options->forward_x11_trusted = 0; 1639 if (options->forward_x11_timeout == -1) 1640 options->forward_x11_timeout = 1200; 1641 if (options->exit_on_forward_failure == -1) 1642 options->exit_on_forward_failure = 0; 1643 if (options->xauth_location == NULL) 1644 options->xauth_location = _PATH_XAUTH; 1645 if (options->gateway_ports == -1) 1646 options->gateway_ports = 0; 1647 if (options->use_privileged_port == -1) 1648 options->use_privileged_port = 0; 1649 if (options->rsa_authentication == -1) 1650 options->rsa_authentication = 1; 1651 if (options->pubkey_authentication == -1) 1652 options->pubkey_authentication = 1; 1653 if (options->challenge_response_authentication == -1) 1654 options->challenge_response_authentication = 1; 1655 if (options->gss_authentication == -1) 1656 options->gss_authentication = 0; 1657 if (options->gss_deleg_creds == -1) 1658 options->gss_deleg_creds = 0; 1659 if (options->password_authentication == -1) 1660 options->password_authentication = 1; 1661 if (options->kbd_interactive_authentication == -1) 1662 options->kbd_interactive_authentication = 1; 1663 if (options->rhosts_rsa_authentication == -1) 1664 options->rhosts_rsa_authentication = 0; 1665 if (options->hostbased_authentication == -1) 1666 options->hostbased_authentication = 0; 1667 if (options->batch_mode == -1) 1668 options->batch_mode = 0; 1669 if (options->check_host_ip == -1) 1670 options->check_host_ip = 0; 1671 if (options->strict_host_key_checking == -1) 1672 options->strict_host_key_checking = 2; /* 2 is default */ 1673 if (options->compression == -1) 1674 options->compression = 0; 1675 if (options->tcp_keep_alive == -1) 1676 options->tcp_keep_alive = 1; 1677 if (options->compression_level == -1) 1678 options->compression_level = 6; 1679 if (options->port == -1) 1680 options->port = 0; /* Filled in ssh_connect. */ 1681 if (options->address_family == -1) 1682 options->address_family = AF_UNSPEC; 1683 if (options->connection_attempts == -1) 1684 options->connection_attempts = 1; 1685 if (options->number_of_password_prompts == -1) 1686 options->number_of_password_prompts = 3; 1687 /* Selected in ssh_login(). */ 1688 if (options->cipher == -1) 1689 options->cipher = SSH_CIPHER_NOT_SET; 1690 /* options->ciphers, default set in myproposals.h */ 1691 /* options->macs, default set in myproposals.h */ 1692 /* options->kex_algorithms, default set in myproposals.h */ 1693 /* options->hostkeyalgorithms, default set in myproposals.h */ 1694 if (options->protocol == SSH_PROTO_UNKNOWN) 1695 options->protocol = SSH_PROTO_2; 1696 if (options->num_identity_files == 0) { 1697 if (options->protocol & SSH_PROTO_1) { 1698 add_identity_file(options, "~/", 1699 _PATH_SSH_CLIENT_IDENTITY, 0); 1700 } 1701 if (options->protocol & SSH_PROTO_2) { 1702 add_identity_file(options, "~/", 1703 _PATH_SSH_CLIENT_ID_RSA, 0); 1704 add_identity_file(options, "~/", 1705 _PATH_SSH_CLIENT_ID_DSA, 0); 1706#ifdef OPENSSL_HAS_ECC 1707 add_identity_file(options, "~/", 1708 _PATH_SSH_CLIENT_ID_ECDSA, 0); 1709#endif 1710 add_identity_file(options, "~/", 1711 _PATH_SSH_CLIENT_ID_ED25519, 0); 1712 } 1713 } 1714 if (options->escape_char == -1) 1715 options->escape_char = '~'; 1716 if (options->num_system_hostfiles == 0) { 1717 options->system_hostfiles[options->num_system_hostfiles++] = 1718 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1719 options->system_hostfiles[options->num_system_hostfiles++] = 1720 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1721 } 1722 if (options->num_user_hostfiles == 0) { 1723 options->user_hostfiles[options->num_user_hostfiles++] = 1724 xstrdup(_PATH_SSH_USER_HOSTFILE); 1725 options->user_hostfiles[options->num_user_hostfiles++] = 1726 xstrdup(_PATH_SSH_USER_HOSTFILE2); 1727 } 1728 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1729 options->log_level = SYSLOG_LEVEL_INFO; 1730 if (options->clear_forwardings == 1) 1731 clear_forwardings(options); 1732 if (options->no_host_authentication_for_localhost == - 1) 1733 options->no_host_authentication_for_localhost = 0; 1734 if (options->identities_only == -1) 1735 options->identities_only = 0; 1736 if (options->enable_ssh_keysign == -1) 1737 options->enable_ssh_keysign = 0; 1738 if (options->rekey_limit == -1) 1739 options->rekey_limit = 0; 1740 if (options->rekey_interval == -1) 1741 options->rekey_interval = 0; 1742#if HAVE_LDNS 1743 if (options->verify_host_key_dns == -1) 1744 /* automatically trust a verified SSHFP record */ 1745 options->verify_host_key_dns = 1; 1746#else 1747 if (options->verify_host_key_dns == -1) 1748 options->verify_host_key_dns = 0; 1749#endif 1750 if (options->server_alive_interval == -1) 1751 options->server_alive_interval = 0; 1752 if (options->server_alive_count_max == -1) 1753 options->server_alive_count_max = 3; 1754 if (options->control_master == -1) 1755 options->control_master = 0; 1756 if (options->control_persist == -1) { 1757 options->control_persist = 0; 1758 options->control_persist_timeout = 0; 1759 } 1760 if (options->hash_known_hosts == -1) 1761 options->hash_known_hosts = 0; 1762 if (options->tun_open == -1) 1763 options->tun_open = SSH_TUNMODE_NO; 1764 if (options->tun_local == -1) 1765 options->tun_local = SSH_TUNID_ANY; 1766 if (options->tun_remote == -1) 1767 options->tun_remote = SSH_TUNID_ANY; 1768 if (options->permit_local_command == -1) 1769 options->permit_local_command = 0; 1770 options->use_roaming = 0; 1771 if (options->visual_host_key == -1) 1772 options->visual_host_key = 0; 1773 if (options->ip_qos_interactive == -1) 1774 options->ip_qos_interactive = IPTOS_LOWDELAY; 1775 if (options->ip_qos_bulk == -1) 1776 options->ip_qos_bulk = IPTOS_THROUGHPUT; 1777 if (options->request_tty == -1) 1778 options->request_tty = REQUEST_TTY_AUTO; 1779 if (options->proxy_use_fdpass == -1) 1780 options->proxy_use_fdpass = 0; 1781 if (options->canonicalize_max_dots == -1) 1782 options->canonicalize_max_dots = 1; 1783 if (options->canonicalize_fallback_local == -1) 1784 options->canonicalize_fallback_local = 1; 1785 if (options->canonicalize_hostname == -1) 1786 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1787#define CLEAR_ON_NONE(v) \ 1788 do { \ 1789 if (option_clear_or_none(v)) { \ 1790 free(v); \ 1791 v = NULL; \ 1792 } \ 1793 } while(0) 1794 CLEAR_ON_NONE(options->local_command); 1795 CLEAR_ON_NONE(options->proxy_command); 1796 CLEAR_ON_NONE(options->control_path); 1797 /* options->user will be set in the main program if appropriate */ 1798 /* options->hostname will be set in the main program if appropriate */ 1799 /* options->host_key_alias should not be set by default */ 1800 /* options->preferred_authentications will be set in ssh */ 1801 if (options->version_addendum == NULL) 1802 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 1803} 1804 1805/* 1806 * parse_forward 1807 * parses a string containing a port forwarding specification of the form: 1808 * dynamicfwd == 0 1809 * [listenhost:]listenport:connecthost:connectport 1810 * dynamicfwd == 1 1811 * [listenhost:]listenport 1812 * returns number of arguments parsed or zero on error 1813 */ 1814int 1815parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1816{ 1817 int i; 1818 char *p, *cp, *fwdarg[4]; 1819 1820 memset(fwd, '\0', sizeof(*fwd)); 1821 1822 cp = p = xstrdup(fwdspec); 1823 1824 /* skip leading spaces */ 1825 while (isspace((u_char)*cp)) 1826 cp++; 1827 1828 for (i = 0; i < 4; ++i) 1829 if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1830 break; 1831 1832 /* Check for trailing garbage */ 1833 if (cp != NULL) 1834 i = 0; /* failure */ 1835 1836 switch (i) { 1837 case 1: 1838 fwd->listen_host = NULL; 1839 fwd->listen_port = a2port(fwdarg[0]); 1840 fwd->connect_host = xstrdup("socks"); 1841 break; 1842 1843 case 2: 1844 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1845 fwd->listen_port = a2port(fwdarg[1]); 1846 fwd->connect_host = xstrdup("socks"); 1847 break; 1848 1849 case 3: 1850 fwd->listen_host = NULL; 1851 fwd->listen_port = a2port(fwdarg[0]); 1852 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1853 fwd->connect_port = a2port(fwdarg[2]); 1854 break; 1855 1856 case 4: 1857 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1858 fwd->listen_port = a2port(fwdarg[1]); 1859 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1860 fwd->connect_port = a2port(fwdarg[3]); 1861 break; 1862 default: 1863 i = 0; /* failure */ 1864 } 1865 1866 free(p); 1867 1868 if (dynamicfwd) { 1869 if (!(i == 1 || i == 2)) 1870 goto fail_free; 1871 } else { 1872 if (!(i == 3 || i == 4)) 1873 goto fail_free; 1874 if (fwd->connect_port <= 0) 1875 goto fail_free; 1876 } 1877 1878 if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1879 goto fail_free; 1880 1881 if (fwd->connect_host != NULL && 1882 strlen(fwd->connect_host) >= NI_MAXHOST) 1883 goto fail_free; 1884 if (fwd->listen_host != NULL && 1885 strlen(fwd->listen_host) >= NI_MAXHOST) 1886 goto fail_free; 1887 1888 1889 return (i); 1890 1891 fail_free: 1892 free(fwd->connect_host); 1893 fwd->connect_host = NULL; 1894 free(fwd->listen_host); 1895 fwd->listen_host = NULL; 1896 return (0); 1897} 1898