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