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