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