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