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