1/* $OpenBSD: readconf.c,v 1.232 2015/02/16 22:13:32 djm Exp $ */ 2/* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * Functions for reading the configuration files. 7 * 8 * As far as I am concerned, the code I have written for this software 9 * can be used freely for any purpose. Any derived versions of this 10 * software must be clearly marked as such, and if the derived work is 11 * incompatible with the protocol description in the RFC file, it must be 12 * called by a name other than "ssh" or "Secure Shell". 13 */ 14 15#include "includes.h" 16 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 130typedef 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 oIgnoredUnknownOption, oDeprecated, oUnsupported 161} OpCodes; 162 163/* Textual representations of the tokens. */ 164 165static struct { 166 const char *name; 167 OpCodes opcode; 168} keywords[] = { 169 { "forwardagent", oForwardAgent }, 170 { "forwardx11", oForwardX11 }, 171 { "forwardx11trusted", oForwardX11Trusted }, 172 { "forwardx11timeout", oForwardX11Timeout }, 173 { "exitonforwardfailure", oExitOnForwardFailure }, 174 { "xauthlocation", oXAuthLocation }, 175 { "gatewayports", oGatewayPorts }, 176 { "useprivilegedport", oUsePrivilegedPort }, 177 { "rhostsauthentication", oDeprecated }, 178 { "passwordauthentication", oPasswordAuthentication }, 179 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 180 { "kbdinteractivedevices", oKbdInteractiveDevices }, 181 { "rsaauthentication", oRSAAuthentication }, 182 { "pubkeyauthentication", oPubkeyAuthentication }, 183 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 184 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 185 { "hostbasedauthentication", oHostbasedAuthentication }, 186 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 187 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 188 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 189 { "kerberosauthentication", oUnsupported }, 190 { "kerberostgtpassing", oUnsupported }, 191 { "afstokenpassing", oUnsupported }, 192#if defined(GSSAPI) 193 { "gssapiauthentication", oGssAuthentication }, 194 { "gssapidelegatecredentials", oGssDelegateCreds }, 195#else 196 { "gssapiauthentication", oUnsupported }, 197 { "gssapidelegatecredentials", oUnsupported }, 198#endif 199 { "fallbacktorsh", oDeprecated }, 200 { "usersh", oDeprecated }, 201 { "identityfile", oIdentityFile }, 202 { "identityfile2", oIdentityFile }, /* obsolete */ 203 { "identitiesonly", oIdentitiesOnly }, 204 { "hostname", oHostName }, 205 { "hostkeyalias", oHostKeyAlias }, 206 { "proxycommand", oProxyCommand }, 207 { "port", oPort }, 208 { "cipher", oCipher }, 209 { "ciphers", oCiphers }, 210 { "macs", oMacs }, 211 { "protocol", oProtocol }, 212 { "remoteforward", oRemoteForward }, 213 { "localforward", oLocalForward }, 214 { "user", oUser }, 215 { "host", oHost }, 216 { "match", oMatch }, 217 { "escapechar", oEscapeChar }, 218 { "globalknownhostsfile", oGlobalKnownHostsFile }, 219 { "globalknownhostsfile2", oDeprecated }, 220 { "userknownhostsfile", oUserKnownHostsFile }, 221 { "userknownhostsfile2", oDeprecated }, 222 { "connectionattempts", oConnectionAttempts }, 223 { "batchmode", oBatchMode }, 224 { "checkhostip", oCheckHostIP }, 225 { "stricthostkeychecking", oStrictHostKeyChecking }, 226 { "compression", oCompression }, 227 { "compressionlevel", oCompressionLevel }, 228 { "tcpkeepalive", oTCPKeepAlive }, 229 { "keepalive", oTCPKeepAlive }, /* obsolete */ 230 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 231 { "loglevel", oLogLevel }, 232 { "dynamicforward", oDynamicForward }, 233 { "preferredauthentications", oPreferredAuthentications }, 234 { "hostkeyalgorithms", oHostKeyAlgorithms }, 235 { "bindaddress", oBindAddress }, 236#ifdef ENABLE_PKCS11 237 { "smartcarddevice", oPKCS11Provider }, 238 { "pkcs11provider", oPKCS11Provider }, 239#else 240 { "smartcarddevice", oUnsupported }, 241 { "pkcs11provider", oUnsupported }, 242#endif 243 { "clearallforwardings", oClearAllForwardings }, 244 { "enablesshkeysign", oEnableSSHKeysign }, 245 { "verifyhostkeydns", oVerifyHostKeyDNS }, 246 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 247 { "rekeylimit", oRekeyLimit }, 248 { "connecttimeout", oConnectTimeout }, 249 { "addressfamily", oAddressFamily }, 250 { "serveraliveinterval", oServerAliveInterval }, 251 { "serveralivecountmax", oServerAliveCountMax }, 252 { "sendenv", oSendEnv }, 253 { "controlpath", oControlPath }, 254 { "controlmaster", oControlMaster }, 255 { "controlpersist", oControlPersist }, 256 { "hashknownhosts", oHashKnownHosts }, 257 { "tunnel", oTunnel }, 258 { "tunneldevice", oTunnelDevice }, 259 { "localcommand", oLocalCommand }, 260 { "permitlocalcommand", oPermitLocalCommand }, 261 { "visualhostkey", oVisualHostKey }, 262 { "useroaming", oUseRoaming }, 263 { "kexalgorithms", oKexAlgorithms }, 264 { "ipqos", oIPQoS }, 265 { "requesttty", oRequestTTY }, 266 { "proxyusefdpass", oProxyUseFdpass }, 267 { "canonicaldomains", oCanonicalDomains }, 268 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, 269 { "canonicalizehostname", oCanonicalizeHostname }, 270 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 271 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 272 { "streamlocalbindmask", oStreamLocalBindMask }, 273 { "streamlocalbindunlink", oStreamLocalBindUnlink }, 274 { "revokedhostkeys", oRevokedHostKeys }, 275 { "fingerprinthash", oFingerprintHash }, 276 { "updatehostkeys", oUpdateHostkeys }, 277 { "hostbasedkeytypes", oHostbasedKeyTypes }, 278 { "ignoreunknown", oIgnoreUnknown }, 279 280 { NULL, oBadOption } 281}; 282 283/* 284 * Adds a local TCP/IP port forward to options. Never returns if there is an 285 * error. 286 */ 287 288void 289add_local_forward(Options *options, const struct Forward *newfwd) 290{ 291 struct Forward *fwd; 292#ifndef NO_IPPORT_RESERVED_CONCEPT 293 extern uid_t original_real_uid; 294 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && 295 newfwd->listen_path == NULL) 296 fatal("Privileged ports can only be forwarded by root."); 297#endif 298 options->local_forwards = xrealloc(options->local_forwards, 299 options->num_local_forwards + 1, 300 sizeof(*options->local_forwards)); 301 fwd = &options->local_forwards[options->num_local_forwards++]; 302 303 fwd->listen_host = newfwd->listen_host; 304 fwd->listen_port = newfwd->listen_port; 305 fwd->listen_path = newfwd->listen_path; 306 fwd->connect_host = newfwd->connect_host; 307 fwd->connect_port = newfwd->connect_port; 308 fwd->connect_path = newfwd->connect_path; 309} 310 311/* 312 * Adds a remote TCP/IP port forward to options. Never returns if there is 313 * an error. 314 */ 315 316void 317add_remote_forward(Options *options, const struct Forward *newfwd) 318{ 319 struct Forward *fwd; 320 321 options->remote_forwards = xrealloc(options->remote_forwards, 322 options->num_remote_forwards + 1, 323 sizeof(*options->remote_forwards)); 324 fwd = &options->remote_forwards[options->num_remote_forwards++]; 325 326 fwd->listen_host = newfwd->listen_host; 327 fwd->listen_port = newfwd->listen_port; 328 fwd->listen_path = newfwd->listen_path; 329 fwd->connect_host = newfwd->connect_host; 330 fwd->connect_port = newfwd->connect_port; 331 fwd->connect_path = newfwd->connect_path; 332 fwd->handle = newfwd->handle; 333 fwd->allocated_port = 0; 334} 335 336static void 337clear_forwardings(Options *options) 338{ 339 int i; 340 341 for (i = 0; i < options->num_local_forwards; i++) { 342 free(options->local_forwards[i].listen_host); 343 free(options->local_forwards[i].listen_path); 344 free(options->local_forwards[i].connect_host); 345 free(options->local_forwards[i].connect_path); 346 } 347 if (options->num_local_forwards > 0) { 348 free(options->local_forwards); 349 options->local_forwards = NULL; 350 } 351 options->num_local_forwards = 0; 352 for (i = 0; i < options->num_remote_forwards; i++) { 353 free(options->remote_forwards[i].listen_host); 354 free(options->remote_forwards[i].listen_path); 355 free(options->remote_forwards[i].connect_host); 356 free(options->remote_forwards[i].connect_path); 357 } 358 if (options->num_remote_forwards > 0) { 359 free(options->remote_forwards); 360 options->remote_forwards = NULL; 361 } 362 options->num_remote_forwards = 0; 363 options->tun_open = SSH_TUNMODE_NO; 364} 365 366void 367add_identity_file(Options *options, const char *dir, const char *filename, 368 int userprovided) 369{ 370 char *path; 371 int i; 372 373 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 374 fatal("Too many identity files specified (max %d)", 375 SSH_MAX_IDENTITY_FILES); 376 377 if (dir == NULL) /* no dir, filename is absolute */ 378 path = xstrdup(filename); 379 else 380 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 381 382 /* Avoid registering duplicates */ 383 for (i = 0; i < options->num_identity_files; i++) { 384 if (options->identity_file_userprovided[i] == userprovided && 385 strcmp(options->identity_files[i], path) == 0) { 386 debug2("%s: ignoring duplicate key %s", __func__, path); 387 free(path); 388 return; 389 } 390 } 391 392 options->identity_file_userprovided[options->num_identity_files] = 393 userprovided; 394 options->identity_files[options->num_identity_files++] = path; 395} 396 397int 398default_ssh_port(void) 399{ 400 static int port; 401 struct servent *sp; 402 403 if (port == 0) { 404 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 405 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 406 } 407 return port; 408} 409 410/* 411 * Execute a command in a shell. 412 * Return its exit status or -1 on abnormal exit. 413 */ 414static int 415execute_in_shell(const char *cmd) 416{ 417 char *shell, *command_string; 418 pid_t pid; 419 int devnull, status; 420 extern uid_t original_real_uid; 421 422 if ((shell = getenv("SHELL")) == NULL) 423 shell = _PATH_BSHELL; 424 425 /* 426 * Use "exec" to avoid "sh -c" processes on some platforms 427 * (e.g. Solaris) 428 */ 429 xasprintf(&command_string, "exec %s", cmd); 430 431 /* Need this to redirect subprocess stdin/out */ 432 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 433 fatal("open(/dev/null): %s", strerror(errno)); 434 435 debug("Executing command: '%.500s'", cmd); 436 437 /* Fork and execute the command. */ 438 if ((pid = fork()) == 0) { 439 char *argv[4]; 440 441 /* Child. Permanently give up superuser privileges. */ 442 permanently_drop_suid(original_real_uid); 443 444 /* Redirect child stdin and stdout. Leave stderr */ 445 if (dup2(devnull, STDIN_FILENO) == -1) 446 fatal("dup2: %s", strerror(errno)); 447 if (dup2(devnull, STDOUT_FILENO) == -1) 448 fatal("dup2: %s", strerror(errno)); 449 if (devnull > STDERR_FILENO) 450 close(devnull); 451 closefrom(STDERR_FILENO + 1); 452 453 argv[0] = shell; 454 argv[1] = "-c"; 455 argv[2] = command_string; 456 argv[3] = NULL; 457 458 execv(argv[0], argv); 459 error("Unable to execute '%.100s': %s", cmd, strerror(errno)); 460 /* Die with signal to make this error apparent to parent. */ 461 signal(SIGTERM, SIG_DFL); 462 kill(getpid(), SIGTERM); 463 _exit(1); 464 } 465 /* Parent. */ 466 if (pid < 0) 467 fatal("%s: fork: %.100s", __func__, strerror(errno)); 468 469 close(devnull); 470 free(command_string); 471 472 while (waitpid(pid, &status, 0) == -1) { 473 if (errno != EINTR && errno != EAGAIN) 474 fatal("%s: waitpid: %s", __func__, strerror(errno)); 475 } 476 if (!WIFEXITED(status)) { 477 error("command '%.100s' exited abnormally", cmd); 478 return -1; 479 } 480 debug3("command returned status %d", WEXITSTATUS(status)); 481 return WEXITSTATUS(status); 482} 483 484/* 485 * Parse and execute a Match directive. 486 */ 487static int 488match_cfg_line(Options *options, char **condition, struct passwd *pw, 489 const char *host_arg, const char *original_host, int post_canon, 490 const char *filename, int linenum) 491{ 492 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; 493 const char *ruser; 494 int r, port, this_result, result = 1, attributes = 0, negate; 495 size_t len; 496 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 497 498 /* 499 * Configuration is likely to be incomplete at this point so we 500 * must be prepared to use default values. 501 */ 502 port = options->port <= 0 ? default_ssh_port() : options->port; 503 ruser = options->user == NULL ? pw->pw_name : options->user; 504 if (options->hostname != NULL) { 505 /* NB. Please keep in sync with ssh.c:main() */ 506 host = percent_expand(options->hostname, 507 "h", host_arg, (char *)NULL); 508 } else 509 host = xstrdup(host_arg); 510 511 debug2("checking match for '%s' host %s originally %s", 512 cp, host, original_host); 513 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { 514 criteria = NULL; 515 this_result = 1; 516 if ((negate = attrib[0] == '!')) 517 attrib++; 518 /* criteria "all" and "canonical" have no argument */ 519 if (strcasecmp(attrib, "all") == 0) { 520 if (attributes > 1 || 521 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 522 error("%.200s line %d: '%s' cannot be combined " 523 "with other Match attributes", 524 filename, linenum, oattrib); 525 result = -1; 526 goto out; 527 } 528 if (result) 529 result = negate ? 0 : 1; 530 goto out; 531 } 532 attributes++; 533 if (strcasecmp(attrib, "canonical") == 0) { 534 r = !!post_canon; /* force bitmask member to boolean */ 535 if (r == (negate ? 1 : 0)) 536 this_result = result = 0; 537 debug3("%.200s line %d: %smatched '%s'", 538 filename, linenum, 539 this_result ? "" : "not ", oattrib); 540 continue; 541 } 542 /* All other criteria require an argument */ 543 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 544 error("Missing Match criteria for %s", attrib); 545 result = -1; 546 goto out; 547 } 548 len = strlen(arg); 549 if (strcasecmp(attrib, "host") == 0) { 550 criteria = xstrdup(host); 551 r = match_hostname(host, arg, len) == 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, len) == 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, len, 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, len, 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 */ 629static void 630valid_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 */ 659static OpCodes 660parse_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 && match_pattern_list(cp, ignored_unknown, 669 strlen(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 */ 677struct multistate { 678 char *key; 679 int value; 680}; 681static const struct multistate multistate_flag[] = { 682 { "true", 1 }, 683 { "false", 0 }, 684 { "yes", 1 }, 685 { "no", 0 }, 686 { NULL, -1 } 687}; 688static const struct multistate multistate_yesnoask[] = { 689 { "true", 1 }, 690 { "false", 0 }, 691 { "yes", 1 }, 692 { "no", 0 }, 693 { "ask", 2 }, 694 { NULL, -1 } 695}; 696static const struct multistate multistate_addressfamily[] = { 697 { "inet", AF_INET }, 698 { "inet6", AF_INET6 }, 699 { "any", AF_UNSPEC }, 700 { NULL, -1 } 701}; 702static 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}; 712static 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}; 721static 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}; 730static 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" 744int 745process_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 for (len = strlen(line) - 1; len > 0; len--) { 767 if (strchr(WHITESPACE, line[len]) == NULL) 768 break; 769 line[len] = '\0'; 770 } 771 772 s = line; 773 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 774 if ((keyword = strdelim(&s)) == NULL) 775 return 0; 776 /* Ignore leading whitespace. */ 777 if (*keyword == '\0') 778 keyword = strdelim(&s); 779 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 780 return 0; 781 /* Match lowercase keyword */ 782 lowercase(keyword); 783 784 opcode = parse_token(keyword, filename, linenum, 785 options->ignored_unknown); 786 787 switch (opcode) { 788 case oBadOption: 789 /* don't panic, but count bad options */ 790 return -1; 791 /* NOTREACHED */ 792 case oIgnoredUnknownOption: 793 debug("%s line %d: Ignored unknown option \"%s\"", 794 filename, linenum, keyword); 795 return 0; 796 case oConnectTimeout: 797 intptr = &options->connection_timeout; 798parse_time: 799 arg = strdelim(&s); 800 if (!arg || *arg == '\0') 801 fatal("%s line %d: missing time value.", 802 filename, linenum); 803 if (strcmp(arg, "none") == 0) 804 value = -1; 805 else if ((value = convtime(arg)) == -1) 806 fatal("%s line %d: invalid time value.", 807 filename, linenum); 808 if (*activep && *intptr == -1) 809 *intptr = value; 810 break; 811 812 case oForwardAgent: 813 intptr = &options->forward_agent; 814 parse_flag: 815 multistate_ptr = multistate_flag; 816 parse_multistate: 817 arg = strdelim(&s); 818 if (!arg || *arg == '\0') 819 fatal("%s line %d: missing argument.", 820 filename, linenum); 821 value = -1; 822 for (i = 0; multistate_ptr[i].key != NULL; i++) { 823 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 824 value = multistate_ptr[i].value; 825 break; 826 } 827 } 828 if (value == -1) 829 fatal("%s line %d: unsupported option \"%s\".", 830 filename, linenum, arg); 831 if (*activep && *intptr == -1) 832 *intptr = value; 833 break; 834 835 case oForwardX11: 836 intptr = &options->forward_x11; 837 goto parse_flag; 838 839 case oForwardX11Trusted: 840 intptr = &options->forward_x11_trusted; 841 goto parse_flag; 842 843 case oForwardX11Timeout: 844 intptr = &options->forward_x11_timeout; 845 goto parse_time; 846 847 case oGatewayPorts: 848 intptr = &options->fwd_opts.gateway_ports; 849 goto parse_flag; 850 851 case oExitOnForwardFailure: 852 intptr = &options->exit_on_forward_failure; 853 goto parse_flag; 854 855 case oUsePrivilegedPort: 856 intptr = &options->use_privileged_port; 857 goto parse_flag; 858 859 case oPasswordAuthentication: 860 intptr = &options->password_authentication; 861 goto parse_flag; 862 863 case oKbdInteractiveAuthentication: 864 intptr = &options->kbd_interactive_authentication; 865 goto parse_flag; 866 867 case oKbdInteractiveDevices: 868 charptr = &options->kbd_interactive_devices; 869 goto parse_string; 870 871 case oPubkeyAuthentication: 872 intptr = &options->pubkey_authentication; 873 goto parse_flag; 874 875 case oRSAAuthentication: 876 intptr = &options->rsa_authentication; 877 goto parse_flag; 878 879 case oRhostsRSAAuthentication: 880 intptr = &options->rhosts_rsa_authentication; 881 goto parse_flag; 882 883 case oHostbasedAuthentication: 884 intptr = &options->hostbased_authentication; 885 goto parse_flag; 886 887 case oChallengeResponseAuthentication: 888 intptr = &options->challenge_response_authentication; 889 goto parse_flag; 890 891 case oGssAuthentication: 892 intptr = &options->gss_authentication; 893 goto parse_flag; 894 895 case oGssDelegateCreds: 896 intptr = &options->gss_deleg_creds; 897 goto parse_flag; 898 899 case oBatchMode: 900 intptr = &options->batch_mode; 901 goto parse_flag; 902 903 case oCheckHostIP: 904 intptr = &options->check_host_ip; 905 goto parse_flag; 906 907 case oVerifyHostKeyDNS: 908 intptr = &options->verify_host_key_dns; 909 multistate_ptr = multistate_yesnoask; 910 goto parse_multistate; 911 912 case oStrictHostKeyChecking: 913 intptr = &options->strict_host_key_checking; 914 multistate_ptr = multistate_yesnoask; 915 goto parse_multistate; 916 917 case oCompression: 918 intptr = &options->compression; 919 goto parse_flag; 920 921 case oTCPKeepAlive: 922 intptr = &options->tcp_keep_alive; 923 goto parse_flag; 924 925 case oNoHostAuthenticationForLocalhost: 926 intptr = &options->no_host_authentication_for_localhost; 927 goto parse_flag; 928 929 case oNumberOfPasswordPrompts: 930 intptr = &options->number_of_password_prompts; 931 goto parse_int; 932 933 case oCompressionLevel: 934 intptr = &options->compression_level; 935 goto parse_int; 936 937 case oRekeyLimit: 938 arg = strdelim(&s); 939 if (!arg || *arg == '\0') 940 fatal("%.200s line %d: Missing argument.", filename, 941 linenum); 942 if (strcmp(arg, "default") == 0) { 943 val64 = 0; 944 } else { 945 if (scan_scaled(arg, &val64) == -1) 946 fatal("%.200s line %d: Bad number '%s': %s", 947 filename, linenum, arg, strerror(errno)); 948 /* check for too-large or too-small limits */ 949 if (val64 > UINT_MAX) 950 fatal("%.200s line %d: RekeyLimit too large", 951 filename, linenum); 952 if (val64 != 0 && val64 < 16) 953 fatal("%.200s line %d: RekeyLimit too small", 954 filename, linenum); 955 } 956 if (*activep && options->rekey_limit == -1) 957 options->rekey_limit = (u_int32_t)val64; 958 if (s != NULL) { /* optional rekey interval present */ 959 if (strcmp(s, "none") == 0) { 960 (void)strdelim(&s); /* discard */ 961 break; 962 } 963 intptr = &options->rekey_interval; 964 goto parse_time; 965 } 966 break; 967 968 case oIdentityFile: 969 arg = strdelim(&s); 970 if (!arg || *arg == '\0') 971 fatal("%.200s line %d: Missing argument.", filename, linenum); 972 if (*activep) { 973 intptr = &options->num_identity_files; 974 if (*intptr >= SSH_MAX_IDENTITY_FILES) 975 fatal("%.200s line %d: Too many identity files specified (max %d).", 976 filename, linenum, SSH_MAX_IDENTITY_FILES); 977 add_identity_file(options, NULL, 978 arg, flags & SSHCONF_USERCONF); 979 } 980 break; 981 982 case oXAuthLocation: 983 charptr=&options->xauth_location; 984 goto parse_string; 985 986 case oUser: 987 charptr = &options->user; 988parse_string: 989 arg = strdelim(&s); 990 if (!arg || *arg == '\0') 991 fatal("%.200s line %d: Missing argument.", 992 filename, linenum); 993 if (*activep && *charptr == NULL) 994 *charptr = xstrdup(arg); 995 break; 996 997 case oGlobalKnownHostsFile: 998 cpptr = (char **)&options->system_hostfiles; 999 uintptr = &options->num_system_hostfiles; 1000 max_entries = SSH_MAX_HOSTS_FILES; 1001parse_char_array: 1002 if (*activep && *uintptr == 0) { 1003 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1004 if ((*uintptr) >= max_entries) 1005 fatal("%s line %d: " 1006 "too many authorized keys files.", 1007 filename, linenum); 1008 cpptr[(*uintptr)++] = xstrdup(arg); 1009 } 1010 } 1011 return 0; 1012 1013 case oUserKnownHostsFile: 1014 cpptr = (char **)&options->user_hostfiles; 1015 uintptr = &options->num_user_hostfiles; 1016 max_entries = SSH_MAX_HOSTS_FILES; 1017 goto parse_char_array; 1018 1019 case oHostName: 1020 charptr = &options->hostname; 1021 goto parse_string; 1022 1023 case oHostKeyAlias: 1024 charptr = &options->host_key_alias; 1025 goto parse_string; 1026 1027 case oPreferredAuthentications: 1028 charptr = &options->preferred_authentications; 1029 goto parse_string; 1030 1031 case oBindAddress: 1032 charptr = &options->bind_address; 1033 goto parse_string; 1034 1035 case oPKCS11Provider: 1036 charptr = &options->pkcs11_provider; 1037 goto parse_string; 1038 1039 case oProxyCommand: 1040 charptr = &options->proxy_command; 1041parse_command: 1042 if (s == NULL) 1043 fatal("%.200s line %d: Missing argument.", filename, linenum); 1044 len = strspn(s, WHITESPACE "="); 1045 if (*activep && *charptr == NULL) 1046 *charptr = xstrdup(s + len); 1047 return 0; 1048 1049 case oPort: 1050 intptr = &options->port; 1051parse_int: 1052 arg = strdelim(&s); 1053 if (!arg || *arg == '\0') 1054 fatal("%.200s line %d: Missing argument.", filename, linenum); 1055 if (arg[0] < '0' || arg[0] > '9') 1056 fatal("%.200s line %d: Bad number.", filename, linenum); 1057 1058 /* Octal, decimal, or hex format? */ 1059 value = strtol(arg, &endofnumber, 0); 1060 if (arg == endofnumber) 1061 fatal("%.200s line %d: Bad number.", filename, linenum); 1062 if (*activep && *intptr == -1) 1063 *intptr = value; 1064 break; 1065 1066 case oConnectionAttempts: 1067 intptr = &options->connection_attempts; 1068 goto parse_int; 1069 1070 case oCipher: 1071 intptr = &options->cipher; 1072 arg = strdelim(&s); 1073 if (!arg || *arg == '\0') 1074 fatal("%.200s line %d: Missing argument.", filename, linenum); 1075 value = cipher_number(arg); 1076 if (value == -1) 1077 fatal("%.200s line %d: Bad cipher '%s'.", 1078 filename, linenum, arg ? arg : "<NONE>"); 1079 if (*activep && *intptr == -1) 1080 *intptr = value; 1081 break; 1082 1083 case oCiphers: 1084 arg = strdelim(&s); 1085 if (!arg || *arg == '\0') 1086 fatal("%.200s line %d: Missing argument.", filename, linenum); 1087 if (!ciphers_valid(arg)) 1088 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 1089 filename, linenum, arg ? arg : "<NONE>"); 1090 if (*activep && options->ciphers == NULL) 1091 options->ciphers = xstrdup(arg); 1092 break; 1093 1094 case oMacs: 1095 arg = strdelim(&s); 1096 if (!arg || *arg == '\0') 1097 fatal("%.200s line %d: Missing argument.", filename, linenum); 1098 if (!mac_valid(arg)) 1099 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 1100 filename, linenum, arg ? arg : "<NONE>"); 1101 if (*activep && options->macs == NULL) 1102 options->macs = xstrdup(arg); 1103 break; 1104 1105 case oKexAlgorithms: 1106 arg = strdelim(&s); 1107 if (!arg || *arg == '\0') 1108 fatal("%.200s line %d: Missing argument.", 1109 filename, linenum); 1110 if (!kex_names_valid(arg)) 1111 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 1112 filename, linenum, arg ? arg : "<NONE>"); 1113 if (*activep && options->kex_algorithms == NULL) 1114 options->kex_algorithms = xstrdup(arg); 1115 break; 1116 1117 case oHostKeyAlgorithms: 1118 arg = strdelim(&s); 1119 if (!arg || *arg == '\0') 1120 fatal("%.200s line %d: Missing argument.", filename, linenum); 1121 if (!sshkey_names_valid2(arg, 1)) 1122 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 1123 filename, linenum, arg ? arg : "<NONE>"); 1124 if (*activep && options->hostkeyalgorithms == NULL) 1125 options->hostkeyalgorithms = xstrdup(arg); 1126 break; 1127 1128 case oProtocol: 1129 intptr = &options->protocol; 1130 arg = strdelim(&s); 1131 if (!arg || *arg == '\0') 1132 fatal("%.200s line %d: Missing argument.", filename, linenum); 1133 value = proto_spec(arg); 1134 if (value == SSH_PROTO_UNKNOWN) 1135 fatal("%.200s line %d: Bad protocol spec '%s'.", 1136 filename, linenum, arg ? arg : "<NONE>"); 1137 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 1138 *intptr = value; 1139 break; 1140 1141 case oLogLevel: 1142 log_level_ptr = &options->log_level; 1143 arg = strdelim(&s); 1144 value = log_level_number(arg); 1145 if (value == SYSLOG_LEVEL_NOT_SET) 1146 fatal("%.200s line %d: unsupported log level '%s'", 1147 filename, linenum, arg ? arg : "<NONE>"); 1148 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 1149 *log_level_ptr = (LogLevel) value; 1150 break; 1151 1152 case oLocalForward: 1153 case oRemoteForward: 1154 case oDynamicForward: 1155 arg = strdelim(&s); 1156 if (arg == NULL || *arg == '\0') 1157 fatal("%.200s line %d: Missing port argument.", 1158 filename, linenum); 1159 1160 if (opcode == oLocalForward || 1161 opcode == oRemoteForward) { 1162 arg2 = strdelim(&s); 1163 if (arg2 == NULL || *arg2 == '\0') 1164 fatal("%.200s line %d: Missing target argument.", 1165 filename, linenum); 1166 1167 /* construct a string for parse_forward */ 1168 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 1169 } else if (opcode == oDynamicForward) { 1170 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1171 } 1172 1173 if (parse_forward(&fwd, fwdarg, 1174 opcode == oDynamicForward ? 1 : 0, 1175 opcode == oRemoteForward ? 1 : 0) == 0) 1176 fatal("%.200s line %d: Bad forwarding specification.", 1177 filename, linenum); 1178 1179 if (*activep) { 1180 if (opcode == oLocalForward || 1181 opcode == oDynamicForward) 1182 add_local_forward(options, &fwd); 1183 else if (opcode == oRemoteForward) 1184 add_remote_forward(options, &fwd); 1185 } 1186 break; 1187 1188 case oClearAllForwardings: 1189 intptr = &options->clear_forwardings; 1190 goto parse_flag; 1191 1192 case oHost: 1193 if (cmdline) 1194 fatal("Host directive not supported as a command-line " 1195 "option"); 1196 *activep = 0; 1197 arg2 = NULL; 1198 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1199 negated = *arg == '!'; 1200 if (negated) 1201 arg++; 1202 if (match_pattern(host, arg)) { 1203 if (negated) { 1204 debug("%.200s line %d: Skipping Host " 1205 "block because of negated match " 1206 "for %.100s", filename, linenum, 1207 arg); 1208 *activep = 0; 1209 break; 1210 } 1211 if (!*activep) 1212 arg2 = arg; /* logged below */ 1213 *activep = 1; 1214 } 1215 } 1216 if (*activep) 1217 debug("%.200s line %d: Applying options for %.100s", 1218 filename, linenum, arg2); 1219 /* Avoid garbage check below, as strdelim is done. */ 1220 return 0; 1221 1222 case oMatch: 1223 if (cmdline) 1224 fatal("Host directive not supported as a command-line " 1225 "option"); 1226 value = match_cfg_line(options, &s, pw, host, original_host, 1227 flags & SSHCONF_POSTCANON, filename, linenum); 1228 if (value < 0) 1229 fatal("%.200s line %d: Bad Match condition", filename, 1230 linenum); 1231 *activep = value; 1232 break; 1233 1234 case oEscapeChar: 1235 intptr = &options->escape_char; 1236 arg = strdelim(&s); 1237 if (!arg || *arg == '\0') 1238 fatal("%.200s line %d: Missing argument.", filename, linenum); 1239 if (arg[0] == '^' && arg[2] == 0 && 1240 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 1241 value = (u_char) arg[1] & 31; 1242 else if (strlen(arg) == 1) 1243 value = (u_char) arg[0]; 1244 else if (strcmp(arg, "none") == 0) 1245 value = SSH_ESCAPECHAR_NONE; 1246 else { 1247 fatal("%.200s line %d: Bad escape character.", 1248 filename, linenum); 1249 /* NOTREACHED */ 1250 value = 0; /* Avoid compiler warning. */ 1251 } 1252 if (*activep && *intptr == -1) 1253 *intptr = value; 1254 break; 1255 1256 case oAddressFamily: 1257 intptr = &options->address_family; 1258 multistate_ptr = multistate_addressfamily; 1259 goto parse_multistate; 1260 1261 case oEnableSSHKeysign: 1262 intptr = &options->enable_ssh_keysign; 1263 goto parse_flag; 1264 1265 case oIdentitiesOnly: 1266 intptr = &options->identities_only; 1267 goto parse_flag; 1268 1269 case oServerAliveInterval: 1270 intptr = &options->server_alive_interval; 1271 goto parse_time; 1272 1273 case oServerAliveCountMax: 1274 intptr = &options->server_alive_count_max; 1275 goto parse_int; 1276 1277 case oSendEnv: 1278 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1279 if (strchr(arg, '=') != NULL) 1280 fatal("%s line %d: Invalid environment name.", 1281 filename, linenum); 1282 if (!*activep) 1283 continue; 1284 if (options->num_send_env >= MAX_SEND_ENV) 1285 fatal("%s line %d: too many send env.", 1286 filename, linenum); 1287 options->send_env[options->num_send_env++] = 1288 xstrdup(arg); 1289 } 1290 break; 1291 1292 case oControlPath: 1293 charptr = &options->control_path; 1294 goto parse_string; 1295 1296 case oControlMaster: 1297 intptr = &options->control_master; 1298 multistate_ptr = multistate_controlmaster; 1299 goto parse_multistate; 1300 1301 case oControlPersist: 1302 /* no/false/yes/true, or a time spec */ 1303 intptr = &options->control_persist; 1304 arg = strdelim(&s); 1305 if (!arg || *arg == '\0') 1306 fatal("%.200s line %d: Missing ControlPersist" 1307 " argument.", filename, linenum); 1308 value = 0; 1309 value2 = 0; /* timeout */ 1310 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 1311 value = 0; 1312 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 1313 value = 1; 1314 else if ((value2 = convtime(arg)) >= 0) 1315 value = 1; 1316 else 1317 fatal("%.200s line %d: Bad ControlPersist argument.", 1318 filename, linenum); 1319 if (*activep && *intptr == -1) { 1320 *intptr = value; 1321 options->control_persist_timeout = value2; 1322 } 1323 break; 1324 1325 case oHashKnownHosts: 1326 intptr = &options->hash_known_hosts; 1327 goto parse_flag; 1328 1329 case oTunnel: 1330 intptr = &options->tun_open; 1331 multistate_ptr = multistate_tunnel; 1332 goto parse_multistate; 1333 1334 case oTunnelDevice: 1335 arg = strdelim(&s); 1336 if (!arg || *arg == '\0') 1337 fatal("%.200s line %d: Missing argument.", filename, linenum); 1338 value = a2tun(arg, &value2); 1339 if (value == SSH_TUNID_ERR) 1340 fatal("%.200s line %d: Bad tun device.", filename, linenum); 1341 if (*activep) { 1342 options->tun_local = value; 1343 options->tun_remote = value2; 1344 } 1345 break; 1346 1347 case oLocalCommand: 1348 charptr = &options->local_command; 1349 goto parse_command; 1350 1351 case oPermitLocalCommand: 1352 intptr = &options->permit_local_command; 1353 goto parse_flag; 1354 1355 case oVisualHostKey: 1356 intptr = &options->visual_host_key; 1357 goto parse_flag; 1358 1359 case oIPQoS: 1360 arg = strdelim(&s); 1361 if ((value = parse_ipqos(arg)) == -1) 1362 fatal("%s line %d: Bad IPQoS value: %s", 1363 filename, linenum, arg); 1364 arg = strdelim(&s); 1365 if (arg == NULL) 1366 value2 = value; 1367 else if ((value2 = parse_ipqos(arg)) == -1) 1368 fatal("%s line %d: Bad IPQoS value: %s", 1369 filename, linenum, arg); 1370 if (*activep) { 1371 options->ip_qos_interactive = value; 1372 options->ip_qos_bulk = value2; 1373 } 1374 break; 1375 1376 case oUseRoaming: 1377 intptr = &options->use_roaming; 1378 goto parse_flag; 1379 1380 case oRequestTTY: 1381 intptr = &options->request_tty; 1382 multistate_ptr = multistate_requesttty; 1383 goto parse_multistate; 1384 1385 case oIgnoreUnknown: 1386 charptr = &options->ignored_unknown; 1387 goto parse_string; 1388 1389 case oProxyUseFdpass: 1390 intptr = &options->proxy_use_fdpass; 1391 goto parse_flag; 1392 1393 case oCanonicalDomains: 1394 value = options->num_canonical_domains != 0; 1395 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1396 valid_domain(arg, filename, linenum); 1397 if (!*activep || value) 1398 continue; 1399 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1400 fatal("%s line %d: too many hostname suffixes.", 1401 filename, linenum); 1402 options->canonical_domains[ 1403 options->num_canonical_domains++] = xstrdup(arg); 1404 } 1405 break; 1406 1407 case oCanonicalizePermittedCNAMEs: 1408 value = options->num_permitted_cnames != 0; 1409 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1410 /* Either '*' for everything or 'list:list' */ 1411 if (strcmp(arg, "*") == 0) 1412 arg2 = arg; 1413 else { 1414 lowercase(arg); 1415 if ((arg2 = strchr(arg, ':')) == NULL || 1416 arg2[1] == '\0') { 1417 fatal("%s line %d: " 1418 "Invalid permitted CNAME \"%s\"", 1419 filename, linenum, arg); 1420 } 1421 *arg2 = '\0'; 1422 arg2++; 1423 } 1424 if (!*activep || value) 1425 continue; 1426 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1427 fatal("%s line %d: too many permitted CNAMEs.", 1428 filename, linenum); 1429 cname = options->permitted_cnames + 1430 options->num_permitted_cnames++; 1431 cname->source_list = xstrdup(arg); 1432 cname->target_list = xstrdup(arg2); 1433 } 1434 break; 1435 1436 case oCanonicalizeHostname: 1437 intptr = &options->canonicalize_hostname; 1438 multistate_ptr = multistate_canonicalizehostname; 1439 goto parse_multistate; 1440 1441 case oCanonicalizeMaxDots: 1442 intptr = &options->canonicalize_max_dots; 1443 goto parse_int; 1444 1445 case oCanonicalizeFallbackLocal: 1446 intptr = &options->canonicalize_fallback_local; 1447 goto parse_flag; 1448 1449 case oStreamLocalBindMask: 1450 arg = strdelim(&s); 1451 if (!arg || *arg == '\0') 1452 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); 1453 /* Parse mode in octal format */ 1454 value = strtol(arg, &endofnumber, 8); 1455 if (arg == endofnumber || value < 0 || value > 0777) 1456 fatal("%.200s line %d: Bad mask.", filename, linenum); 1457 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1458 break; 1459 1460 case oStreamLocalBindUnlink: 1461 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1462 goto parse_flag; 1463 1464 case oRevokedHostKeys: 1465 charptr = &options->revoked_host_keys; 1466 goto parse_string; 1467 1468 case oFingerprintHash: 1469 intptr = &options->fingerprint_hash; 1470 arg = strdelim(&s); 1471 if (!arg || *arg == '\0') 1472 fatal("%.200s line %d: Missing argument.", 1473 filename, linenum); 1474 if ((value = ssh_digest_alg_by_name(arg)) == -1) 1475 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1476 filename, linenum, arg); 1477 if (*activep && *intptr == -1) 1478 *intptr = value; 1479 break; 1480 1481 case oUpdateHostkeys: 1482 intptr = &options->update_hostkeys; 1483 multistate_ptr = multistate_yesnoask; 1484 goto parse_multistate; 1485 1486 case oHostbasedKeyTypes: 1487 charptr = &options->hostbased_key_types; 1488 arg = strdelim(&s); 1489 if (!arg || *arg == '\0') 1490 fatal("%.200s line %d: Missing argument.", 1491 filename, linenum); 1492 if (!sshkey_names_valid2(arg, 1)) 1493 fatal("%s line %d: Bad key types '%s'.", 1494 filename, linenum, arg ? arg : "<NONE>"); 1495 if (*activep && *charptr == NULL) 1496 *charptr = xstrdup(arg); 1497 break; 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 1528int 1529read_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. */ 1573int 1574option_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 1586void 1587initialize_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 = -1; 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} 1680 1681/* 1682 * A petite version of fill_default_options() that just fills the options 1683 * needed for hostname canonicalization to proceed. 1684 */ 1685void 1686fill_default_options_for_canonicalization(Options *options) 1687{ 1688 if (options->canonicalize_max_dots == -1) 1689 options->canonicalize_max_dots = 1; 1690 if (options->canonicalize_fallback_local == -1) 1691 options->canonicalize_fallback_local = 1; 1692 if (options->canonicalize_hostname == -1) 1693 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1694} 1695 1696/* 1697 * Called after processing other sources of option data, this fills those 1698 * options for which no value has been specified with their default values. 1699 */ 1700void 1701fill_default_options(Options * options) 1702{ 1703 if (options->forward_agent == -1) 1704 options->forward_agent = 0; 1705 if (options->forward_x11 == -1) 1706 options->forward_x11 = 0; 1707 if (options->forward_x11_trusted == -1) 1708 options->forward_x11_trusted = 0; 1709 if (options->forward_x11_timeout == -1) 1710 options->forward_x11_timeout = 1200; 1711 if (options->exit_on_forward_failure == -1) 1712 options->exit_on_forward_failure = 0; 1713 if (options->xauth_location == NULL) 1714 options->xauth_location = _PATH_XAUTH; 1715 if (options->fwd_opts.gateway_ports == -1) 1716 options->fwd_opts.gateway_ports = 0; 1717 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 1718 options->fwd_opts.streamlocal_bind_mask = 0177; 1719 if (options->fwd_opts.streamlocal_bind_unlink == -1) 1720 options->fwd_opts.streamlocal_bind_unlink = 0; 1721 if (options->use_privileged_port == -1) 1722 options->use_privileged_port = 0; 1723 if (options->rsa_authentication == -1) 1724 options->rsa_authentication = 1; 1725 if (options->pubkey_authentication == -1) 1726 options->pubkey_authentication = 1; 1727 if (options->challenge_response_authentication == -1) 1728 options->challenge_response_authentication = 1; 1729 if (options->gss_authentication == -1) 1730 options->gss_authentication = 0; 1731 if (options->gss_deleg_creds == -1) 1732 options->gss_deleg_creds = 0; 1733 if (options->password_authentication == -1) 1734 options->password_authentication = 1; 1735 if (options->kbd_interactive_authentication == -1) 1736 options->kbd_interactive_authentication = 1; 1737 if (options->rhosts_rsa_authentication == -1) 1738 options->rhosts_rsa_authentication = 0; 1739 if (options->hostbased_authentication == -1) 1740 options->hostbased_authentication = 0; 1741 if (options->batch_mode == -1) 1742 options->batch_mode = 0; 1743 if (options->check_host_ip == -1) 1744 options->check_host_ip = 1; 1745 if (options->strict_host_key_checking == -1) 1746 options->strict_host_key_checking = 2; /* 2 is default */ 1747 if (options->compression == -1) 1748 options->compression = 0; 1749 if (options->tcp_keep_alive == -1) 1750 options->tcp_keep_alive = 1; 1751 if (options->compression_level == -1) 1752 options->compression_level = 6; 1753 if (options->port == -1) 1754 options->port = 0; /* Filled in ssh_connect. */ 1755 if (options->address_family == -1) 1756 options->address_family = AF_UNSPEC; 1757 if (options->connection_attempts == -1) 1758 options->connection_attempts = 1; 1759 if (options->number_of_password_prompts == -1) 1760 options->number_of_password_prompts = 3; 1761 /* Selected in ssh_login(). */ 1762 if (options->cipher == -1) 1763 options->cipher = SSH_CIPHER_NOT_SET; 1764 /* options->ciphers, default set in myproposals.h */ 1765 /* options->macs, default set in myproposals.h */ 1766 /* options->kex_algorithms, default set in myproposals.h */ 1767 /* options->hostkeyalgorithms, default set in myproposals.h */ 1768 if (options->protocol == SSH_PROTO_UNKNOWN) 1769 options->protocol = SSH_PROTO_2; 1770 if (options->num_identity_files == 0) { 1771 if (options->protocol & SSH_PROTO_1) { 1772 add_identity_file(options, "~/", 1773 _PATH_SSH_CLIENT_IDENTITY, 0); 1774 } 1775 if (options->protocol & SSH_PROTO_2) { 1776 add_identity_file(options, "~/", 1777 _PATH_SSH_CLIENT_ID_RSA, 0); 1778 add_identity_file(options, "~/", 1779 _PATH_SSH_CLIENT_ID_DSA, 0); 1780#ifdef OPENSSL_HAS_ECC 1781 add_identity_file(options, "~/", 1782 _PATH_SSH_CLIENT_ID_ECDSA, 0); 1783#endif 1784 add_identity_file(options, "~/", 1785 _PATH_SSH_CLIENT_ID_ED25519, 0); 1786 } 1787 } 1788 if (options->escape_char == -1) 1789 options->escape_char = '~'; 1790 if (options->num_system_hostfiles == 0) { 1791 options->system_hostfiles[options->num_system_hostfiles++] = 1792 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1793 options->system_hostfiles[options->num_system_hostfiles++] = 1794 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1795 } 1796 if (options->num_user_hostfiles == 0) { 1797 options->user_hostfiles[options->num_user_hostfiles++] = 1798 xstrdup(_PATH_SSH_USER_HOSTFILE); 1799 options->user_hostfiles[options->num_user_hostfiles++] = 1800 xstrdup(_PATH_SSH_USER_HOSTFILE2); 1801 } 1802 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1803 options->log_level = SYSLOG_LEVEL_INFO; 1804 if (options->clear_forwardings == 1) 1805 clear_forwardings(options); 1806 if (options->no_host_authentication_for_localhost == - 1) 1807 options->no_host_authentication_for_localhost = 0; 1808 if (options->identities_only == -1) 1809 options->identities_only = 0; 1810 if (options->enable_ssh_keysign == -1) 1811 options->enable_ssh_keysign = 0; 1812 if (options->rekey_limit == -1) 1813 options->rekey_limit = 0; 1814 if (options->rekey_interval == -1) 1815 options->rekey_interval = 0; 1816 if (options->verify_host_key_dns == -1) 1817 options->verify_host_key_dns = 0; 1818 if (options->server_alive_interval == -1) 1819 options->server_alive_interval = 0; 1820 if (options->server_alive_count_max == -1) 1821 options->server_alive_count_max = 3; 1822 if (options->control_master == -1) 1823 options->control_master = 0; 1824 if (options->control_persist == -1) { 1825 options->control_persist = 0; 1826 options->control_persist_timeout = 0; 1827 } 1828 if (options->hash_known_hosts == -1) 1829 options->hash_known_hosts = 0; 1830 if (options->tun_open == -1) 1831 options->tun_open = SSH_TUNMODE_NO; 1832 if (options->tun_local == -1) 1833 options->tun_local = SSH_TUNID_ANY; 1834 if (options->tun_remote == -1) 1835 options->tun_remote = SSH_TUNID_ANY; 1836 if (options->permit_local_command == -1) 1837 options->permit_local_command = 0; 1838 if (options->use_roaming == -1) 1839 options->use_roaming = 1; 1840 if (options->visual_host_key == -1) 1841 options->visual_host_key = 0; 1842 if (options->ip_qos_interactive == -1) 1843 options->ip_qos_interactive = IPTOS_LOWDELAY; 1844 if (options->ip_qos_bulk == -1) 1845 options->ip_qos_bulk = IPTOS_THROUGHPUT; 1846 if (options->request_tty == -1) 1847 options->request_tty = REQUEST_TTY_AUTO; 1848 if (options->proxy_use_fdpass == -1) 1849 options->proxy_use_fdpass = 0; 1850 if (options->canonicalize_max_dots == -1) 1851 options->canonicalize_max_dots = 1; 1852 if (options->canonicalize_fallback_local == -1) 1853 options->canonicalize_fallback_local = 1; 1854 if (options->canonicalize_hostname == -1) 1855 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1856 if (options->fingerprint_hash == -1) 1857 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 1858 if (options->update_hostkeys == -1) 1859 options->update_hostkeys = 0; 1860 if (options->hostbased_key_types == NULL) 1861 options->hostbased_key_types = xstrdup("*"); 1862 1863#define CLEAR_ON_NONE(v) \ 1864 do { \ 1865 if (option_clear_or_none(v)) { \ 1866 free(v); \ 1867 v = NULL; \ 1868 } \ 1869 } while(0) 1870 CLEAR_ON_NONE(options->local_command); 1871 CLEAR_ON_NONE(options->proxy_command); 1872 CLEAR_ON_NONE(options->control_path); 1873 CLEAR_ON_NONE(options->revoked_host_keys); 1874 /* options->user will be set in the main program if appropriate */ 1875 /* options->hostname will be set in the main program if appropriate */ 1876 /* options->host_key_alias should not be set by default */ 1877 /* options->preferred_authentications will be set in ssh */ 1878} 1879 1880struct fwdarg { 1881 char *arg; 1882 int ispath; 1883}; 1884 1885/* 1886 * parse_fwd_field 1887 * parses the next field in a port forwarding specification. 1888 * sets fwd to the parsed field and advances p past the colon 1889 * or sets it to NULL at end of string. 1890 * returns 0 on success, else non-zero. 1891 */ 1892static int 1893parse_fwd_field(char **p, struct fwdarg *fwd) 1894{ 1895 char *ep, *cp = *p; 1896 int ispath = 0; 1897 1898 if (*cp == '\0') { 1899 *p = NULL; 1900 return -1; /* end of string */ 1901 } 1902 1903 /* 1904 * A field escaped with square brackets is used literally. 1905 * XXX - allow ']' to be escaped via backslash? 1906 */ 1907 if (*cp == '[') { 1908 /* find matching ']' */ 1909 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { 1910 if (*ep == '/') 1911 ispath = 1; 1912 } 1913 /* no matching ']' or not at end of field. */ 1914 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) 1915 return -1; 1916 /* NUL terminate the field and advance p past the colon */ 1917 *ep++ = '\0'; 1918 if (*ep != '\0') 1919 *ep++ = '\0'; 1920 fwd->arg = cp + 1; 1921 fwd->ispath = ispath; 1922 *p = ep; 1923 return 0; 1924 } 1925 1926 for (cp = *p; *cp != '\0'; cp++) { 1927 switch (*cp) { 1928 case '\\': 1929 memmove(cp, cp + 1, strlen(cp + 1) + 1); 1930 cp++; 1931 break; 1932 case '/': 1933 ispath = 1; 1934 break; 1935 case ':': 1936 *cp++ = '\0'; 1937 goto done; 1938 } 1939 } 1940done: 1941 fwd->arg = *p; 1942 fwd->ispath = ispath; 1943 *p = cp; 1944 return 0; 1945} 1946 1947/* 1948 * parse_forward 1949 * parses a string containing a port forwarding specification of the form: 1950 * dynamicfwd == 0 1951 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath 1952 * listenpath:connectpath 1953 * dynamicfwd == 1 1954 * [listenhost:]listenport 1955 * returns number of arguments parsed or zero on error 1956 */ 1957int 1958parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1959{ 1960 struct fwdarg fwdargs[4]; 1961 char *p, *cp; 1962 int i; 1963 1964 memset(fwd, 0, sizeof(*fwd)); 1965 memset(fwdargs, 0, sizeof(fwdargs)); 1966 1967 cp = p = xstrdup(fwdspec); 1968 1969 /* skip leading spaces */ 1970 while (isspace((u_char)*cp)) 1971 cp++; 1972 1973 for (i = 0; i < 4; ++i) { 1974 if (parse_fwd_field(&cp, &fwdargs[i]) != 0) 1975 break; 1976 } 1977 1978 /* Check for trailing garbage */ 1979 if (cp != NULL && *cp != '\0') { 1980 i = 0; /* failure */ 1981 } 1982 1983 switch (i) { 1984 case 1: 1985 if (fwdargs[0].ispath) { 1986 fwd->listen_path = xstrdup(fwdargs[0].arg); 1987 fwd->listen_port = PORT_STREAMLOCAL; 1988 } else { 1989 fwd->listen_host = NULL; 1990 fwd->listen_port = a2port(fwdargs[0].arg); 1991 } 1992 fwd->connect_host = xstrdup("socks"); 1993 break; 1994 1995 case 2: 1996 if (fwdargs[0].ispath && fwdargs[1].ispath) { 1997 fwd->listen_path = xstrdup(fwdargs[0].arg); 1998 fwd->listen_port = PORT_STREAMLOCAL; 1999 fwd->connect_path = xstrdup(fwdargs[1].arg); 2000 fwd->connect_port = PORT_STREAMLOCAL; 2001 } else if (fwdargs[1].ispath) { 2002 fwd->listen_host = NULL; 2003 fwd->listen_port = a2port(fwdargs[0].arg); 2004 fwd->connect_path = xstrdup(fwdargs[1].arg); 2005 fwd->connect_port = PORT_STREAMLOCAL; 2006 } else { 2007 fwd->listen_host = xstrdup(fwdargs[0].arg); 2008 fwd->listen_port = a2port(fwdargs[1].arg); 2009 fwd->connect_host = xstrdup("socks"); 2010 } 2011 break; 2012 2013 case 3: 2014 if (fwdargs[0].ispath) { 2015 fwd->listen_path = xstrdup(fwdargs[0].arg); 2016 fwd->listen_port = PORT_STREAMLOCAL; 2017 fwd->connect_host = xstrdup(fwdargs[1].arg); 2018 fwd->connect_port = a2port(fwdargs[2].arg); 2019 } else if (fwdargs[2].ispath) { 2020 fwd->listen_host = xstrdup(fwdargs[0].arg); 2021 fwd->listen_port = a2port(fwdargs[1].arg); 2022 fwd->connect_path = xstrdup(fwdargs[2].arg); 2023 fwd->connect_port = PORT_STREAMLOCAL; 2024 } else { 2025 fwd->listen_host = NULL; 2026 fwd->listen_port = a2port(fwdargs[0].arg); 2027 fwd->connect_host = xstrdup(fwdargs[1].arg); 2028 fwd->connect_port = a2port(fwdargs[2].arg); 2029 } 2030 break; 2031 2032 case 4: 2033 fwd->listen_host = xstrdup(fwdargs[0].arg); 2034 fwd->listen_port = a2port(fwdargs[1].arg); 2035 fwd->connect_host = xstrdup(fwdargs[2].arg); 2036 fwd->connect_port = a2port(fwdargs[3].arg); 2037 break; 2038 default: 2039 i = 0; /* failure */ 2040 } 2041 2042 free(p); 2043 2044 if (dynamicfwd) { 2045 if (!(i == 1 || i == 2)) 2046 goto fail_free; 2047 } else { 2048 if (!(i == 3 || i == 4)) { 2049 if (fwd->connect_path == NULL && 2050 fwd->listen_path == NULL) 2051 goto fail_free; 2052 } 2053 if (fwd->connect_port <= 0 && fwd->connect_path == NULL) 2054 goto fail_free; 2055 } 2056 2057 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || 2058 (!remotefwd && fwd->listen_port == 0)) 2059 goto fail_free; 2060 if (fwd->connect_host != NULL && 2061 strlen(fwd->connect_host) >= NI_MAXHOST) 2062 goto fail_free; 2063 /* XXX - if connecting to a remote socket, max sun len may not match this host */ 2064 if (fwd->connect_path != NULL && 2065 strlen(fwd->connect_path) >= PATH_MAX_SUN) 2066 goto fail_free; 2067 if (fwd->listen_host != NULL && 2068 strlen(fwd->listen_host) >= NI_MAXHOST) 2069 goto fail_free; 2070 if (fwd->listen_path != NULL && 2071 strlen(fwd->listen_path) >= PATH_MAX_SUN) 2072 goto fail_free; 2073 2074 return (i); 2075 2076 fail_free: 2077 free(fwd->connect_host); 2078 fwd->connect_host = NULL; 2079 free(fwd->connect_path); 2080 fwd->connect_path = NULL; 2081 free(fwd->listen_host); 2082 fwd->listen_host = NULL; 2083 free(fwd->listen_path); 2084 fwd->listen_path = NULL; 2085 return (0); 2086} 2087 2088/* XXX the following is a near-vebatim copy from servconf.c; refactor */ 2089static const char * 2090fmt_multistate_int(int val, const struct multistate *m) 2091{ 2092 u_int i; 2093 2094 for (i = 0; m[i].key != NULL; i++) { 2095 if (m[i].value == val) 2096 return m[i].key; 2097 } 2098 return "UNKNOWN"; 2099} 2100 2101static const char * 2102fmt_intarg(OpCodes code, int val) 2103{ 2104 if (val == -1) 2105 return "unset"; 2106 switch (code) { 2107 case oAddressFamily: 2108 return fmt_multistate_int(val, multistate_addressfamily); 2109 case oVerifyHostKeyDNS: 2110 case oStrictHostKeyChecking: 2111 case oUpdateHostkeys: 2112 return fmt_multistate_int(val, multistate_yesnoask); 2113 case oControlMaster: 2114 return fmt_multistate_int(val, multistate_controlmaster); 2115 case oTunnel: 2116 return fmt_multistate_int(val, multistate_tunnel); 2117 case oRequestTTY: 2118 return fmt_multistate_int(val, multistate_requesttty); 2119 case oCanonicalizeHostname: 2120 return fmt_multistate_int(val, multistate_canonicalizehostname); 2121 case oFingerprintHash: 2122 return ssh_digest_alg_name(val); 2123 case oProtocol: 2124 switch (val) { 2125 case SSH_PROTO_1: 2126 return "1"; 2127 case SSH_PROTO_2: 2128 return "2"; 2129 case (SSH_PROTO_1|SSH_PROTO_2): 2130 return "2,1"; 2131 default: 2132 return "UNKNOWN"; 2133 } 2134 default: 2135 switch (val) { 2136 case 0: 2137 return "no"; 2138 case 1: 2139 return "yes"; 2140 default: 2141 return "UNKNOWN"; 2142 } 2143 } 2144} 2145 2146static const char * 2147lookup_opcode_name(OpCodes code) 2148{ 2149 u_int i; 2150 2151 for (i = 0; keywords[i].name != NULL; i++) 2152 if (keywords[i].opcode == code) 2153 return(keywords[i].name); 2154 return "UNKNOWN"; 2155} 2156 2157static void 2158dump_cfg_int(OpCodes code, int val) 2159{ 2160 printf("%s %d\n", lookup_opcode_name(code), val); 2161} 2162 2163static void 2164dump_cfg_fmtint(OpCodes code, int val) 2165{ 2166 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2167} 2168 2169static void 2170dump_cfg_string(OpCodes code, const char *val) 2171{ 2172 if (val == NULL) 2173 return; 2174 printf("%s %s\n", lookup_opcode_name(code), val); 2175} 2176 2177static void 2178dump_cfg_strarray(OpCodes code, u_int count, char **vals) 2179{ 2180 u_int i; 2181 2182 for (i = 0; i < count; i++) 2183 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2184} 2185 2186static void 2187dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) 2188{ 2189 u_int i; 2190 2191 printf("%s", lookup_opcode_name(code)); 2192 for (i = 0; i < count; i++) 2193 printf(" %s", vals[i]); 2194 printf("\n"); 2195} 2196 2197static void 2198dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) 2199{ 2200 const struct Forward *fwd; 2201 u_int i; 2202 2203 /* oDynamicForward */ 2204 for (i = 0; i < count; i++) { 2205 fwd = &fwds[i]; 2206 if (code == oDynamicForward && 2207 strcmp(fwd->connect_host, "socks") != 0) 2208 continue; 2209 if (code == oLocalForward && 2210 strcmp(fwd->connect_host, "socks") == 0) 2211 continue; 2212 printf("%s", lookup_opcode_name(code)); 2213 if (fwd->listen_port == PORT_STREAMLOCAL) 2214 printf(" %s", fwd->listen_path); 2215 else if (fwd->listen_host == NULL) 2216 printf(" %d", fwd->listen_port); 2217 else { 2218 printf(" [%s]:%d", 2219 fwd->listen_host, fwd->listen_port); 2220 } 2221 if (code != oDynamicForward) { 2222 if (fwd->connect_port == PORT_STREAMLOCAL) 2223 printf(" %s", fwd->connect_path); 2224 else if (fwd->connect_host == NULL) 2225 printf(" %d", fwd->connect_port); 2226 else { 2227 printf(" [%s]:%d", 2228 fwd->connect_host, fwd->connect_port); 2229 } 2230 } 2231 printf("\n"); 2232 } 2233} 2234 2235void 2236dump_client_config(Options *o, const char *host) 2237{ 2238 int i; 2239 char vbuf[5]; 2240 2241 /* Most interesting options first: user, host, port */ 2242 dump_cfg_string(oUser, o->user); 2243 dump_cfg_string(oHostName, host); 2244 dump_cfg_int(oPort, o->port); 2245 2246 /* Flag options */ 2247 dump_cfg_fmtint(oAddressFamily, o->address_family); 2248 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2249 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2250 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); 2251 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); 2252 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); 2253 dump_cfg_fmtint(oCompression, o->compression); 2254 dump_cfg_fmtint(oControlMaster, o->control_master); 2255 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); 2256 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2257 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2258 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2259 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2260 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2261 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2262#ifdef GSSAPI 2263 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2264 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2265#endif /* GSSAPI */ 2266 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2267 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2268 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); 2269 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); 2270 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2271 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2272 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2273 dump_cfg_fmtint(oProtocol, o->protocol); 2274 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2275 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2276 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2277 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2278 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); 2279 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2280 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2281 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2282 dump_cfg_fmtint(oTunnel, o->tun_open); 2283 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); 2284 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); 2285 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); 2286 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); 2287 2288 /* Integer options */ 2289 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2290 dump_cfg_int(oCompressionLevel, o->compression_level); 2291 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2292 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2293 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2294 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); 2295 dump_cfg_int(oServerAliveInterval, o->server_alive_interval); 2296 2297 /* String options */ 2298 dump_cfg_string(oBindAddress, o->bind_address); 2299 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); 2300 dump_cfg_string(oControlPath, o->control_path); 2301 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2302 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2303 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2304 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2305 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); 2306 dump_cfg_string(oLocalCommand, o->local_command); 2307 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2308 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); 2309 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2310 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2311 dump_cfg_string(oProxyCommand, o->proxy_command); 2312 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2313 dump_cfg_string(oXAuthLocation, o->xauth_location); 2314 2315 /* Forwards */ 2316 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2317 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2318 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); 2319 2320 /* String array options */ 2321 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); 2322 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); 2323 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); 2324 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); 2325 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); 2326 2327 /* Special cases */ 2328 2329 /* oConnectTimeout */ 2330 if (o->connection_timeout == -1) 2331 printf("connecttimeout none\n"); 2332 else 2333 dump_cfg_int(oConnectTimeout, o->connection_timeout); 2334 2335 /* oTunnelDevice */ 2336 printf("tunneldevice"); 2337 if (o->tun_local == SSH_TUNID_ANY) 2338 printf(" any"); 2339 else 2340 printf(" %d", o->tun_local); 2341 if (o->tun_remote == SSH_TUNID_ANY) 2342 printf(":any"); 2343 else 2344 printf(":%d", o->tun_remote); 2345 printf("\n"); 2346 2347 /* oCanonicalizePermittedCNAMEs */ 2348 if ( o->num_permitted_cnames > 0) { 2349 printf("canonicalizePermittedcnames"); 2350 for (i = 0; i < o->num_permitted_cnames; i++) { 2351 printf(" %s:%s", o->permitted_cnames[i].source_list, 2352 o->permitted_cnames[i].target_list); 2353 } 2354 printf("\n"); 2355 } 2356 2357 /* oCipher */ 2358 if (o->cipher != SSH_CIPHER_NOT_SET) 2359 printf("Cipher %s\n", cipher_name(o->cipher)); 2360 2361 /* oControlPersist */ 2362 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2363 dump_cfg_fmtint(oControlPersist, o->control_persist); 2364 else 2365 dump_cfg_int(oControlPersist, o->control_persist_timeout); 2366 2367 /* oEscapeChar */ 2368 if (o->escape_char == SSH_ESCAPECHAR_NONE) 2369 printf("escapechar none\n"); 2370 else { 2371 vis(vbuf, o->escape_char, VIS_WHITE, 0); 2372 printf("escapechar %s\n", vbuf); 2373 } 2374 2375 /* oIPQoS */ 2376 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2377 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2378 2379 /* oRekeyLimit */ 2380 printf("rekeylimit %lld %d\n", 2381 (long long)o->rekey_limit, o->rekey_interval); 2382 2383 /* oStreamLocalBindMask */ 2384 printf("streamlocalbindmask 0%o\n", 2385 o->fwd_opts.streamlocal_bind_mask); 2386} 2387