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