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