1 /* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus 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 23 #include <netinet/in.h> 24 25 #include <ctype.h> 26 #include <errno.h> 27 #include <netdb.h> 28 #include <signal.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include "xmalloc.h" 35 #include "ssh.h" 36 #include "compat.h" 37 #include "cipher.h" 38 #include "pathnames.h" 39 #include "log.h" 40 #include "key.h" 41 #include "readconf.h" 42 #include "match.h" 43 #include "misc.h" 44 #include "buffer.h" 45 #include "kex.h" 46 #include "mac.h" 47 #include "version.h" 48 49 /* Format of the configuration file: 50 51 # Configuration data is parsed as follows: 52 # 1. command line options 53 # 2. user-specific file 54 # 3. system-wide file 55 # Any configuration value is only changed the first time it is set. 56 # Thus, host-specific definitions should be at the beginning of the 57 # configuration file, and defaults at the end. 58 59 # Host-specific declarations. These may override anything above. A single 60 # host may match multiple declarations; these are processed in the order 61 # that they are given in. 62 63 Host *.ngs.fi ngs.fi 64 User foo 65 66 Host fake.com 67 HostName another.host.name.real.org 68 User blaah 69 Port 34289 70 ForwardX11 no 71 ForwardAgent no 72 73 Host books.com 74 RemoteForward 9999 shadows.cs.hut.fi:9999 75 Cipher 3des 76 77 Host fascist.blob.com 78 Port 23123 79 User tylonen 80 PasswordAuthentication no 81 82 Host puukko.hut.fi 83 User t35124p 84 ProxyCommand ssh-proxy %h %p 85 86 Host *.fr 87 PublicKeyAuthentication no 88 89 Host *.su 90 Cipher none 91 PasswordAuthentication no 92 93 Host vpn.fake.com 94 Tunnel yes 95 TunnelDevice 3 96 97 # Defaults for various options 98 Host * 99 ForwardAgent no 100 ForwardX11 no 101 PasswordAuthentication yes 102 RSAAuthentication yes 103 RhostsRSAAuthentication yes 104 StrictHostKeyChecking yes 105 TcpKeepAlive no 106 IdentityFile ~/.ssh/identity 107 Port 22 108 EscapeChar ~ 109 110 */ 111 112 /* Keyword tokens. */ 113 114 typedef enum { 115 oBadOption, 116 oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, 117 oExitOnForwardFailure, 118 oPasswordAuthentication, oRSAAuthentication, 119 oChallengeResponseAuthentication, oXAuthLocation, 120 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 121 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 122 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 123 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 124 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 125 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 126 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 127 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 128 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 129 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 130 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 131 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 132 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 133 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 134 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 135 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 136 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 137 oVersionAddendum, 138 oDeprecated, oUnsupported 139 } OpCodes; 140 141 /* Textual representations of the tokens. */ 142 143 static struct { 144 const char *name; 145 OpCodes opcode; 146 } keywords[] = { 147 { "forwardagent", oForwardAgent }, 148 { "forwardx11", oForwardX11 }, 149 { "forwardx11trusted", oForwardX11Trusted }, 150 { "exitonforwardfailure", oExitOnForwardFailure }, 151 { "xauthlocation", oXAuthLocation }, 152 { "gatewayports", oGatewayPorts }, 153 { "useprivilegedport", oUsePrivilegedPort }, 154 { "rhostsauthentication", oDeprecated }, 155 { "passwordauthentication", oPasswordAuthentication }, 156 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 157 { "kbdinteractivedevices", oKbdInteractiveDevices }, 158 { "rsaauthentication", oRSAAuthentication }, 159 { "pubkeyauthentication", oPubkeyAuthentication }, 160 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 161 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 162 { "hostbasedauthentication", oHostbasedAuthentication }, 163 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 164 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 165 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 166 { "kerberosauthentication", oUnsupported }, 167 { "kerberostgtpassing", oUnsupported }, 168 { "afstokenpassing", oUnsupported }, 169 #if defined(GSSAPI) 170 { "gssapiauthentication", oGssAuthentication }, 171 { "gssapidelegatecredentials", oGssDelegateCreds }, 172 #else 173 { "gssapiauthentication", oUnsupported }, 174 { "gssapidelegatecredentials", oUnsupported }, 175 #endif 176 { "fallbacktorsh", oDeprecated }, 177 { "usersh", oDeprecated }, 178 { "identityfile", oIdentityFile }, 179 { "identityfile2", oIdentityFile }, /* obsolete */ 180 { "identitiesonly", oIdentitiesOnly }, 181 { "hostname", oHostName }, 182 { "hostkeyalias", oHostKeyAlias }, 183 { "proxycommand", oProxyCommand }, 184 { "port", oPort }, 185 { "cipher", oCipher }, 186 { "ciphers", oCiphers }, 187 { "macs", oMacs }, 188 { "protocol", oProtocol }, 189 { "remoteforward", oRemoteForward }, 190 { "localforward", oLocalForward }, 191 { "user", oUser }, 192 { "host", oHost }, 193 { "escapechar", oEscapeChar }, 194 { "globalknownhostsfile", oGlobalKnownHostsFile }, 195 { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */ 196 { "userknownhostsfile", oUserKnownHostsFile }, 197 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 198 { "connectionattempts", oConnectionAttempts }, 199 { "batchmode", oBatchMode }, 200 { "checkhostip", oCheckHostIP }, 201 { "stricthostkeychecking", oStrictHostKeyChecking }, 202 { "compression", oCompression }, 203 { "compressionlevel", oCompressionLevel }, 204 { "tcpkeepalive", oTCPKeepAlive }, 205 { "keepalive", oTCPKeepAlive }, /* obsolete */ 206 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 207 { "loglevel", oLogLevel }, 208 { "dynamicforward", oDynamicForward }, 209 { "preferredauthentications", oPreferredAuthentications }, 210 { "hostkeyalgorithms", oHostKeyAlgorithms }, 211 { "bindaddress", oBindAddress }, 212 #ifdef ENABLE_PKCS11 213 { "smartcarddevice", oPKCS11Provider }, 214 { "pkcs11provider", oPKCS11Provider }, 215 #else 216 { "smartcarddevice", oUnsupported }, 217 { "pkcs11provider", oUnsupported }, 218 #endif 219 { "clearallforwardings", oClearAllForwardings }, 220 { "enablesshkeysign", oEnableSSHKeysign }, 221 { "verifyhostkeydns", oVerifyHostKeyDNS }, 222 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 223 { "rekeylimit", oRekeyLimit }, 224 { "connecttimeout", oConnectTimeout }, 225 { "addressfamily", oAddressFamily }, 226 { "serveraliveinterval", oServerAliveInterval }, 227 { "serveralivecountmax", oServerAliveCountMax }, 228 { "sendenv", oSendEnv }, 229 { "controlpath", oControlPath }, 230 { "controlmaster", oControlMaster }, 231 { "hashknownhosts", oHashKnownHosts }, 232 { "tunnel", oTunnel }, 233 { "tunneldevice", oTunnelDevice }, 234 { "localcommand", oLocalCommand }, 235 { "permitlocalcommand", oPermitLocalCommand }, 236 { "visualhostkey", oVisualHostKey }, 237 { "useroaming", oUseRoaming }, 238 #ifdef JPAKE 239 { "zeroknowledgepasswordauthentication", 240 oZeroKnowledgePasswordAuthentication }, 241 #else 242 { "zeroknowledgepasswordauthentication", oUnsupported }, 243 #endif 244 245 { "versionaddendum", oVersionAddendum }, 246 { NULL, oBadOption } 247 }; 248 249 /* 250 * Adds a local TCP/IP port forward to options. Never returns if there is an 251 * error. 252 */ 253 254 void 255 add_local_forward(Options *options, const Forward *newfwd) 256 { 257 Forward *fwd; 258 #ifndef NO_IPPORT_RESERVED_CONCEPT 259 extern uid_t original_real_uid; 260 int ipport_reserved; 261 #ifdef __FreeBSD__ 262 size_t len_ipport_reserved = sizeof(ipport_reserved); 263 264 if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 265 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 266 ipport_reserved = IPPORT_RESERVED; 267 else 268 ipport_reserved++; 269 #else 270 ipport_reserved = IPPORT_RESERVED; 271 #endif 272 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 273 fatal("Privileged ports can only be forwarded by root."); 274 #endif 275 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 276 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 277 fwd = &options->local_forwards[options->num_local_forwards++]; 278 279 fwd->listen_host = newfwd->listen_host; 280 fwd->listen_port = newfwd->listen_port; 281 fwd->connect_host = newfwd->connect_host; 282 fwd->connect_port = newfwd->connect_port; 283 } 284 285 /* 286 * Adds a remote TCP/IP port forward to options. Never returns if there is 287 * an error. 288 */ 289 290 void 291 add_remote_forward(Options *options, const Forward *newfwd) 292 { 293 Forward *fwd; 294 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 295 fatal("Too many remote forwards (max %d).", 296 SSH_MAX_FORWARDS_PER_DIRECTION); 297 fwd = &options->remote_forwards[options->num_remote_forwards++]; 298 299 fwd->listen_host = newfwd->listen_host; 300 fwd->listen_port = newfwd->listen_port; 301 fwd->connect_host = newfwd->connect_host; 302 fwd->connect_port = newfwd->connect_port; 303 } 304 305 static void 306 clear_forwardings(Options *options) 307 { 308 int i; 309 310 for (i = 0; i < options->num_local_forwards; i++) { 311 if (options->local_forwards[i].listen_host != NULL) 312 xfree(options->local_forwards[i].listen_host); 313 xfree(options->local_forwards[i].connect_host); 314 } 315 options->num_local_forwards = 0; 316 for (i = 0; i < options->num_remote_forwards; i++) { 317 if (options->remote_forwards[i].listen_host != NULL) 318 xfree(options->remote_forwards[i].listen_host); 319 xfree(options->remote_forwards[i].connect_host); 320 } 321 options->num_remote_forwards = 0; 322 options->tun_open = SSH_TUNMODE_NO; 323 } 324 325 /* 326 * Returns the number of the token pointed to by cp or oBadOption. 327 */ 328 329 static OpCodes 330 parse_token(const char *cp, const char *filename, int linenum) 331 { 332 u_int i; 333 334 for (i = 0; keywords[i].name; i++) 335 if (strcasecmp(cp, keywords[i].name) == 0) 336 return keywords[i].opcode; 337 338 error("%s: line %d: Bad configuration option: %s", 339 filename, linenum, cp); 340 return oBadOption; 341 } 342 343 /* 344 * Processes a single option line as used in the configuration files. This 345 * only sets those values that have not already been set. 346 */ 347 #define WHITESPACE " \t\r\n" 348 349 int 350 process_config_line(Options *options, const char *host, 351 char *line, const char *filename, int linenum, 352 int *activep) 353 { 354 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 355 int opcode, *intptr, value, value2, scale; 356 LogLevel *log_level_ptr; 357 long long orig, val64; 358 size_t len; 359 Forward fwd; 360 361 /* Strip trailing whitespace */ 362 for (len = strlen(line) - 1; len > 0; len--) { 363 if (strchr(WHITESPACE, line[len]) == NULL) 364 break; 365 line[len] = '\0'; 366 } 367 368 s = line; 369 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 370 if ((keyword = strdelim(&s)) == NULL) 371 return 0; 372 /* Ignore leading whitespace. */ 373 if (*keyword == '\0') 374 keyword = strdelim(&s); 375 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 376 return 0; 377 378 opcode = parse_token(keyword, filename, linenum); 379 380 switch (opcode) { 381 case oBadOption: 382 /* don't panic, but count bad options */ 383 return -1; 384 /* NOTREACHED */ 385 case oConnectTimeout: 386 intptr = &options->connection_timeout; 387 parse_time: 388 arg = strdelim(&s); 389 if (!arg || *arg == '\0') 390 fatal("%s line %d: missing time value.", 391 filename, linenum); 392 if ((value = convtime(arg)) == -1) 393 fatal("%s line %d: invalid time value.", 394 filename, linenum); 395 if (*activep && *intptr == -1) 396 *intptr = value; 397 break; 398 399 case oForwardAgent: 400 intptr = &options->forward_agent; 401 parse_flag: 402 arg = strdelim(&s); 403 if (!arg || *arg == '\0') 404 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 405 value = 0; /* To avoid compiler warning... */ 406 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 407 value = 1; 408 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 409 value = 0; 410 else 411 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 412 if (*activep && *intptr == -1) 413 *intptr = value; 414 break; 415 416 case oForwardX11: 417 intptr = &options->forward_x11; 418 goto parse_flag; 419 420 case oForwardX11Trusted: 421 intptr = &options->forward_x11_trusted; 422 goto parse_flag; 423 424 case oGatewayPorts: 425 intptr = &options->gateway_ports; 426 goto parse_flag; 427 428 case oExitOnForwardFailure: 429 intptr = &options->exit_on_forward_failure; 430 goto parse_flag; 431 432 case oUsePrivilegedPort: 433 intptr = &options->use_privileged_port; 434 goto parse_flag; 435 436 case oPasswordAuthentication: 437 intptr = &options->password_authentication; 438 goto parse_flag; 439 440 case oZeroKnowledgePasswordAuthentication: 441 intptr = &options->zero_knowledge_password_authentication; 442 goto parse_flag; 443 444 case oKbdInteractiveAuthentication: 445 intptr = &options->kbd_interactive_authentication; 446 goto parse_flag; 447 448 case oKbdInteractiveDevices: 449 charptr = &options->kbd_interactive_devices; 450 goto parse_string; 451 452 case oPubkeyAuthentication: 453 intptr = &options->pubkey_authentication; 454 goto parse_flag; 455 456 case oRSAAuthentication: 457 intptr = &options->rsa_authentication; 458 goto parse_flag; 459 460 case oRhostsRSAAuthentication: 461 intptr = &options->rhosts_rsa_authentication; 462 goto parse_flag; 463 464 case oHostbasedAuthentication: 465 intptr = &options->hostbased_authentication; 466 goto parse_flag; 467 468 case oChallengeResponseAuthentication: 469 intptr = &options->challenge_response_authentication; 470 goto parse_flag; 471 472 case oGssAuthentication: 473 intptr = &options->gss_authentication; 474 goto parse_flag; 475 476 case oGssDelegateCreds: 477 intptr = &options->gss_deleg_creds; 478 goto parse_flag; 479 480 case oBatchMode: 481 intptr = &options->batch_mode; 482 goto parse_flag; 483 484 case oCheckHostIP: 485 intptr = &options->check_host_ip; 486 goto parse_flag; 487 488 case oVerifyHostKeyDNS: 489 intptr = &options->verify_host_key_dns; 490 goto parse_yesnoask; 491 492 case oStrictHostKeyChecking: 493 intptr = &options->strict_host_key_checking; 494 parse_yesnoask: 495 arg = strdelim(&s); 496 if (!arg || *arg == '\0') 497 fatal("%.200s line %d: Missing yes/no/ask argument.", 498 filename, linenum); 499 value = 0; /* To avoid compiler warning... */ 500 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 501 value = 1; 502 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 503 value = 0; 504 else if (strcmp(arg, "ask") == 0) 505 value = 2; 506 else 507 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 508 if (*activep && *intptr == -1) 509 *intptr = value; 510 break; 511 512 case oCompression: 513 intptr = &options->compression; 514 goto parse_flag; 515 516 case oTCPKeepAlive: 517 intptr = &options->tcp_keep_alive; 518 goto parse_flag; 519 520 case oNoHostAuthenticationForLocalhost: 521 intptr = &options->no_host_authentication_for_localhost; 522 goto parse_flag; 523 524 case oNumberOfPasswordPrompts: 525 intptr = &options->number_of_password_prompts; 526 goto parse_int; 527 528 case oCompressionLevel: 529 intptr = &options->compression_level; 530 goto parse_int; 531 532 case oRekeyLimit: 533 arg = strdelim(&s); 534 if (!arg || *arg == '\0') 535 fatal("%.200s line %d: Missing argument.", filename, linenum); 536 if (arg[0] < '0' || arg[0] > '9') 537 fatal("%.200s line %d: Bad number.", filename, linenum); 538 orig = val64 = strtoll(arg, &endofnumber, 10); 539 if (arg == endofnumber) 540 fatal("%.200s line %d: Bad number.", filename, linenum); 541 switch (toupper(*endofnumber)) { 542 case '\0': 543 scale = 1; 544 break; 545 case 'K': 546 scale = 1<<10; 547 break; 548 case 'M': 549 scale = 1<<20; 550 break; 551 case 'G': 552 scale = 1<<30; 553 break; 554 default: 555 fatal("%.200s line %d: Invalid RekeyLimit suffix", 556 filename, linenum); 557 } 558 val64 *= scale; 559 /* detect integer wrap and too-large limits */ 560 if ((val64 / scale) != orig || val64 > UINT_MAX) 561 fatal("%.200s line %d: RekeyLimit too large", 562 filename, linenum); 563 if (val64 < 16) 564 fatal("%.200s line %d: RekeyLimit too small", 565 filename, linenum); 566 if (*activep && options->rekey_limit == -1) 567 options->rekey_limit = (u_int32_t)val64; 568 break; 569 570 case oIdentityFile: 571 arg = strdelim(&s); 572 if (!arg || *arg == '\0') 573 fatal("%.200s line %d: Missing argument.", filename, linenum); 574 if (*activep) { 575 intptr = &options->num_identity_files; 576 if (*intptr >= SSH_MAX_IDENTITY_FILES) 577 fatal("%.200s line %d: Too many identity files specified (max %d).", 578 filename, linenum, SSH_MAX_IDENTITY_FILES); 579 charptr = &options->identity_files[*intptr]; 580 *charptr = xstrdup(arg); 581 *intptr = *intptr + 1; 582 } 583 break; 584 585 case oXAuthLocation: 586 charptr=&options->xauth_location; 587 goto parse_string; 588 589 case oUser: 590 charptr = &options->user; 591 parse_string: 592 arg = strdelim(&s); 593 if (!arg || *arg == '\0') 594 fatal("%.200s line %d: Missing argument.", filename, linenum); 595 if (*activep && *charptr == NULL) 596 *charptr = xstrdup(arg); 597 break; 598 599 case oGlobalKnownHostsFile: 600 charptr = &options->system_hostfile; 601 goto parse_string; 602 603 case oUserKnownHostsFile: 604 charptr = &options->user_hostfile; 605 goto parse_string; 606 607 case oGlobalKnownHostsFile2: 608 charptr = &options->system_hostfile2; 609 goto parse_string; 610 611 case oUserKnownHostsFile2: 612 charptr = &options->user_hostfile2; 613 goto parse_string; 614 615 case oHostName: 616 charptr = &options->hostname; 617 goto parse_string; 618 619 case oHostKeyAlias: 620 charptr = &options->host_key_alias; 621 goto parse_string; 622 623 case oPreferredAuthentications: 624 charptr = &options->preferred_authentications; 625 goto parse_string; 626 627 case oBindAddress: 628 charptr = &options->bind_address; 629 goto parse_string; 630 631 case oPKCS11Provider: 632 charptr = &options->pkcs11_provider; 633 goto parse_string; 634 635 case oProxyCommand: 636 charptr = &options->proxy_command; 637 parse_command: 638 if (s == NULL) 639 fatal("%.200s line %d: Missing argument.", filename, linenum); 640 len = strspn(s, WHITESPACE "="); 641 if (*activep && *charptr == NULL) 642 *charptr = xstrdup(s + len); 643 return 0; 644 645 case oPort: 646 intptr = &options->port; 647 parse_int: 648 arg = strdelim(&s); 649 if (!arg || *arg == '\0') 650 fatal("%.200s line %d: Missing argument.", filename, linenum); 651 if (arg[0] < '0' || arg[0] > '9') 652 fatal("%.200s line %d: Bad number.", filename, linenum); 653 654 /* Octal, decimal, or hex format? */ 655 value = strtol(arg, &endofnumber, 0); 656 if (arg == endofnumber) 657 fatal("%.200s line %d: Bad number.", filename, linenum); 658 if (*activep && *intptr == -1) 659 *intptr = value; 660 break; 661 662 case oConnectionAttempts: 663 intptr = &options->connection_attempts; 664 goto parse_int; 665 666 case oCipher: 667 intptr = &options->cipher; 668 arg = strdelim(&s); 669 if (!arg || *arg == '\0') 670 fatal("%.200s line %d: Missing argument.", filename, linenum); 671 value = cipher_number(arg); 672 if (value == -1) 673 fatal("%.200s line %d: Bad cipher '%s'.", 674 filename, linenum, arg ? arg : "<NONE>"); 675 if (*activep && *intptr == -1) 676 *intptr = value; 677 break; 678 679 case oCiphers: 680 arg = strdelim(&s); 681 if (!arg || *arg == '\0') 682 fatal("%.200s line %d: Missing argument.", filename, linenum); 683 if (!ciphers_valid(arg)) 684 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 685 filename, linenum, arg ? arg : "<NONE>"); 686 if (*activep && options->ciphers == NULL) 687 options->ciphers = xstrdup(arg); 688 break; 689 690 case oMacs: 691 arg = strdelim(&s); 692 if (!arg || *arg == '\0') 693 fatal("%.200s line %d: Missing argument.", filename, linenum); 694 if (!mac_valid(arg)) 695 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 696 filename, linenum, arg ? arg : "<NONE>"); 697 if (*activep && options->macs == NULL) 698 options->macs = xstrdup(arg); 699 break; 700 701 case oHostKeyAlgorithms: 702 arg = strdelim(&s); 703 if (!arg || *arg == '\0') 704 fatal("%.200s line %d: Missing argument.", filename, linenum); 705 if (!key_names_valid2(arg)) 706 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 707 filename, linenum, arg ? arg : "<NONE>"); 708 if (*activep && options->hostkeyalgorithms == NULL) 709 options->hostkeyalgorithms = xstrdup(arg); 710 break; 711 712 case oProtocol: 713 intptr = &options->protocol; 714 arg = strdelim(&s); 715 if (!arg || *arg == '\0') 716 fatal("%.200s line %d: Missing argument.", filename, linenum); 717 value = proto_spec(arg); 718 if (value == SSH_PROTO_UNKNOWN) 719 fatal("%.200s line %d: Bad protocol spec '%s'.", 720 filename, linenum, arg ? arg : "<NONE>"); 721 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 722 *intptr = value; 723 break; 724 725 case oLogLevel: 726 log_level_ptr = &options->log_level; 727 arg = strdelim(&s); 728 value = log_level_number(arg); 729 if (value == SYSLOG_LEVEL_NOT_SET) 730 fatal("%.200s line %d: unsupported log level '%s'", 731 filename, linenum, arg ? arg : "<NONE>"); 732 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 733 *log_level_ptr = (LogLevel) value; 734 break; 735 736 case oLocalForward: 737 case oRemoteForward: 738 case oDynamicForward: 739 arg = strdelim(&s); 740 if (arg == NULL || *arg == '\0') 741 fatal("%.200s line %d: Missing port argument.", 742 filename, linenum); 743 744 if (opcode == oLocalForward || 745 opcode == oRemoteForward) { 746 arg2 = strdelim(&s); 747 if (arg2 == NULL || *arg2 == '\0') 748 fatal("%.200s line %d: Missing target argument.", 749 filename, linenum); 750 751 /* construct a string for parse_forward */ 752 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 753 } else if (opcode == oDynamicForward) { 754 strlcpy(fwdarg, arg, sizeof(fwdarg)); 755 } 756 757 if (parse_forward(&fwd, fwdarg, 758 opcode == oDynamicForward ? 1 : 0, 759 opcode == oRemoteForward ? 1 : 0) == 0) 760 fatal("%.200s line %d: Bad forwarding specification.", 761 filename, linenum); 762 763 if (*activep) { 764 if (opcode == oLocalForward || 765 opcode == oDynamicForward) 766 add_local_forward(options, &fwd); 767 else if (opcode == oRemoteForward) 768 add_remote_forward(options, &fwd); 769 } 770 break; 771 772 case oClearAllForwardings: 773 intptr = &options->clear_forwardings; 774 goto parse_flag; 775 776 case oHost: 777 *activep = 0; 778 while ((arg = strdelim(&s)) != NULL && *arg != '\0') 779 if (match_pattern(host, arg)) { 780 debug("Applying options for %.100s", arg); 781 *activep = 1; 782 break; 783 } 784 /* Avoid garbage check below, as strdelim is done. */ 785 return 0; 786 787 case oEscapeChar: 788 intptr = &options->escape_char; 789 arg = strdelim(&s); 790 if (!arg || *arg == '\0') 791 fatal("%.200s line %d: Missing argument.", filename, linenum); 792 if (arg[0] == '^' && arg[2] == 0 && 793 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 794 value = (u_char) arg[1] & 31; 795 else if (strlen(arg) == 1) 796 value = (u_char) arg[0]; 797 else if (strcmp(arg, "none") == 0) 798 value = SSH_ESCAPECHAR_NONE; 799 else { 800 fatal("%.200s line %d: Bad escape character.", 801 filename, linenum); 802 /* NOTREACHED */ 803 value = 0; /* Avoid compiler warning. */ 804 } 805 if (*activep && *intptr == -1) 806 *intptr = value; 807 break; 808 809 case oAddressFamily: 810 arg = strdelim(&s); 811 if (!arg || *arg == '\0') 812 fatal("%s line %d: missing address family.", 813 filename, linenum); 814 intptr = &options->address_family; 815 if (strcasecmp(arg, "inet") == 0) 816 value = AF_INET; 817 else if (strcasecmp(arg, "inet6") == 0) 818 value = AF_INET6; 819 else if (strcasecmp(arg, "any") == 0) 820 value = AF_UNSPEC; 821 else 822 fatal("Unsupported AddressFamily \"%s\"", arg); 823 if (*activep && *intptr == -1) 824 *intptr = value; 825 break; 826 827 case oEnableSSHKeysign: 828 intptr = &options->enable_ssh_keysign; 829 goto parse_flag; 830 831 case oIdentitiesOnly: 832 intptr = &options->identities_only; 833 goto parse_flag; 834 835 case oServerAliveInterval: 836 intptr = &options->server_alive_interval; 837 goto parse_time; 838 839 case oServerAliveCountMax: 840 intptr = &options->server_alive_count_max; 841 goto parse_int; 842 843 case oSendEnv: 844 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 845 if (strchr(arg, '=') != NULL) 846 fatal("%s line %d: Invalid environment name.", 847 filename, linenum); 848 if (!*activep) 849 continue; 850 if (options->num_send_env >= MAX_SEND_ENV) 851 fatal("%s line %d: too many send env.", 852 filename, linenum); 853 options->send_env[options->num_send_env++] = 854 xstrdup(arg); 855 } 856 break; 857 858 case oControlPath: 859 charptr = &options->control_path; 860 goto parse_string; 861 862 case oControlMaster: 863 intptr = &options->control_master; 864 arg = strdelim(&s); 865 if (!arg || *arg == '\0') 866 fatal("%.200s line %d: Missing ControlMaster argument.", 867 filename, linenum); 868 value = 0; /* To avoid compiler warning... */ 869 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 870 value = SSHCTL_MASTER_YES; 871 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 872 value = SSHCTL_MASTER_NO; 873 else if (strcmp(arg, "auto") == 0) 874 value = SSHCTL_MASTER_AUTO; 875 else if (strcmp(arg, "ask") == 0) 876 value = SSHCTL_MASTER_ASK; 877 else if (strcmp(arg, "autoask") == 0) 878 value = SSHCTL_MASTER_AUTO_ASK; 879 else 880 fatal("%.200s line %d: Bad ControlMaster argument.", 881 filename, linenum); 882 if (*activep && *intptr == -1) 883 *intptr = value; 884 break; 885 886 case oHashKnownHosts: 887 intptr = &options->hash_known_hosts; 888 goto parse_flag; 889 890 case oTunnel: 891 intptr = &options->tun_open; 892 arg = strdelim(&s); 893 if (!arg || *arg == '\0') 894 fatal("%s line %d: Missing yes/point-to-point/" 895 "ethernet/no argument.", filename, linenum); 896 value = 0; /* silence compiler */ 897 if (strcasecmp(arg, "ethernet") == 0) 898 value = SSH_TUNMODE_ETHERNET; 899 else if (strcasecmp(arg, "point-to-point") == 0) 900 value = SSH_TUNMODE_POINTOPOINT; 901 else if (strcasecmp(arg, "yes") == 0) 902 value = SSH_TUNMODE_DEFAULT; 903 else if (strcasecmp(arg, "no") == 0) 904 value = SSH_TUNMODE_NO; 905 else 906 fatal("%s line %d: Bad yes/point-to-point/ethernet/" 907 "no argument: %s", filename, linenum, arg); 908 if (*activep) 909 *intptr = value; 910 break; 911 912 case oTunnelDevice: 913 arg = strdelim(&s); 914 if (!arg || *arg == '\0') 915 fatal("%.200s line %d: Missing argument.", filename, linenum); 916 value = a2tun(arg, &value2); 917 if (value == SSH_TUNID_ERR) 918 fatal("%.200s line %d: Bad tun device.", filename, linenum); 919 if (*activep) { 920 options->tun_local = value; 921 options->tun_remote = value2; 922 } 923 break; 924 925 case oLocalCommand: 926 charptr = &options->local_command; 927 goto parse_command; 928 929 case oPermitLocalCommand: 930 intptr = &options->permit_local_command; 931 goto parse_flag; 932 933 case oVisualHostKey: 934 intptr = &options->visual_host_key; 935 goto parse_flag; 936 937 case oUseRoaming: 938 intptr = &options->use_roaming; 939 goto parse_flag; 940 941 case oVersionAddendum: 942 ssh_version_set_addendum(strtok(s, "\n")); 943 do { 944 arg = strdelim(&s); 945 } while (arg != NULL && *arg != '\0'); 946 break; 947 948 case oDeprecated: 949 debug("%s line %d: Deprecated option \"%s\"", 950 filename, linenum, keyword); 951 return 0; 952 953 case oUnsupported: 954 error("%s line %d: Unsupported option \"%s\"", 955 filename, linenum, keyword); 956 return 0; 957 958 default: 959 fatal("process_config_line: Unimplemented opcode %d", opcode); 960 } 961 962 /* Check that there is no garbage at end of line. */ 963 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 964 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 965 filename, linenum, arg); 966 } 967 return 0; 968 } 969 970 971 /* 972 * Reads the config file and modifies the options accordingly. Options 973 * should already be initialized before this call. This never returns if 974 * there is an error. If the file does not exist, this returns 0. 975 */ 976 977 int 978 read_config_file(const char *filename, const char *host, Options *options, 979 int checkperm) 980 { 981 FILE *f; 982 char line[1024]; 983 int active, linenum; 984 int bad_options = 0; 985 986 if ((f = fopen(filename, "r")) == NULL) 987 return 0; 988 989 if (checkperm) { 990 struct stat sb; 991 992 if (fstat(fileno(f), &sb) == -1) 993 fatal("fstat %s: %s", filename, strerror(errno)); 994 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 995 (sb.st_mode & 022) != 0)) 996 fatal("Bad owner or permissions on %s", filename); 997 } 998 999 debug("Reading configuration data %.200s", filename); 1000 1001 /* 1002 * Mark that we are now processing the options. This flag is turned 1003 * on/off by Host specifications. 1004 */ 1005 active = 1; 1006 linenum = 0; 1007 while (fgets(line, sizeof(line), f)) { 1008 /* Update line number counter. */ 1009 linenum++; 1010 if (process_config_line(options, host, line, filename, linenum, &active) != 0) 1011 bad_options++; 1012 } 1013 fclose(f); 1014 if (bad_options > 0) 1015 fatal("%s: terminating, %d bad configuration options", 1016 filename, bad_options); 1017 return 1; 1018 } 1019 1020 /* 1021 * Initializes options to special values that indicate that they have not yet 1022 * been set. Read_config_file will only set options with this value. Options 1023 * are processed in the following order: command line, user config file, 1024 * system config file. Last, fill_default_options is called. 1025 */ 1026 1027 void 1028 initialize_options(Options * options) 1029 { 1030 memset(options, 'X', sizeof(*options)); 1031 options->forward_agent = -1; 1032 options->forward_x11 = -1; 1033 options->forward_x11_trusted = -1; 1034 options->exit_on_forward_failure = -1; 1035 options->xauth_location = NULL; 1036 options->gateway_ports = -1; 1037 options->use_privileged_port = -1; 1038 options->rsa_authentication = -1; 1039 options->pubkey_authentication = -1; 1040 options->challenge_response_authentication = -1; 1041 options->gss_authentication = -1; 1042 options->gss_deleg_creds = -1; 1043 options->password_authentication = -1; 1044 options->kbd_interactive_authentication = -1; 1045 options->kbd_interactive_devices = NULL; 1046 options->rhosts_rsa_authentication = -1; 1047 options->hostbased_authentication = -1; 1048 options->batch_mode = -1; 1049 options->check_host_ip = -1; 1050 options->strict_host_key_checking = -1; 1051 options->compression = -1; 1052 options->tcp_keep_alive = -1; 1053 options->compression_level = -1; 1054 options->port = -1; 1055 options->address_family = -1; 1056 options->connection_attempts = -1; 1057 options->connection_timeout = -1; 1058 options->number_of_password_prompts = -1; 1059 options->cipher = -1; 1060 options->ciphers = NULL; 1061 options->macs = NULL; 1062 options->hostkeyalgorithms = NULL; 1063 options->protocol = SSH_PROTO_UNKNOWN; 1064 options->num_identity_files = 0; 1065 options->hostname = NULL; 1066 options->host_key_alias = NULL; 1067 options->proxy_command = NULL; 1068 options->user = NULL; 1069 options->escape_char = -1; 1070 options->system_hostfile = NULL; 1071 options->user_hostfile = NULL; 1072 options->system_hostfile2 = NULL; 1073 options->user_hostfile2 = NULL; 1074 options->num_local_forwards = 0; 1075 options->num_remote_forwards = 0; 1076 options->clear_forwardings = -1; 1077 options->log_level = SYSLOG_LEVEL_NOT_SET; 1078 options->preferred_authentications = NULL; 1079 options->bind_address = NULL; 1080 options->pkcs11_provider = NULL; 1081 options->enable_ssh_keysign = - 1; 1082 options->no_host_authentication_for_localhost = - 1; 1083 options->identities_only = - 1; 1084 options->rekey_limit = - 1; 1085 options->verify_host_key_dns = -1; 1086 options->server_alive_interval = -1; 1087 options->server_alive_count_max = -1; 1088 options->num_send_env = 0; 1089 options->control_path = NULL; 1090 options->control_master = -1; 1091 options->hash_known_hosts = -1; 1092 options->tun_open = -1; 1093 options->tun_local = -1; 1094 options->tun_remote = -1; 1095 options->local_command = NULL; 1096 options->permit_local_command = -1; 1097 options->use_roaming = -1; 1098 options->visual_host_key = -1; 1099 options->zero_knowledge_password_authentication = -1; 1100 } 1101 1102 /* 1103 * Called after processing other sources of option data, this fills those 1104 * options for which no value has been specified with their default values. 1105 */ 1106 1107 void 1108 fill_default_options(Options * options) 1109 { 1110 int len; 1111 1112 if (options->forward_agent == -1) 1113 options->forward_agent = 0; 1114 if (options->forward_x11 == -1) 1115 options->forward_x11 = 0; 1116 if (options->forward_x11_trusted == -1) 1117 options->forward_x11_trusted = 0; 1118 if (options->exit_on_forward_failure == -1) 1119 options->exit_on_forward_failure = 0; 1120 if (options->xauth_location == NULL) 1121 options->xauth_location = _PATH_XAUTH; 1122 if (options->gateway_ports == -1) 1123 options->gateway_ports = 0; 1124 if (options->use_privileged_port == -1) 1125 options->use_privileged_port = 0; 1126 if (options->rsa_authentication == -1) 1127 options->rsa_authentication = 1; 1128 if (options->pubkey_authentication == -1) 1129 options->pubkey_authentication = 1; 1130 if (options->challenge_response_authentication == -1) 1131 options->challenge_response_authentication = 1; 1132 if (options->gss_authentication == -1) 1133 options->gss_authentication = 0; 1134 if (options->gss_deleg_creds == -1) 1135 options->gss_deleg_creds = 0; 1136 if (options->password_authentication == -1) 1137 options->password_authentication = 1; 1138 if (options->kbd_interactive_authentication == -1) 1139 options->kbd_interactive_authentication = 1; 1140 if (options->rhosts_rsa_authentication == -1) 1141 options->rhosts_rsa_authentication = 0; 1142 if (options->hostbased_authentication == -1) 1143 options->hostbased_authentication = 0; 1144 if (options->batch_mode == -1) 1145 options->batch_mode = 0; 1146 if (options->check_host_ip == -1) 1147 options->check_host_ip = 0; 1148 if (options->strict_host_key_checking == -1) 1149 options->strict_host_key_checking = 2; /* 2 is default */ 1150 if (options->compression == -1) 1151 options->compression = 0; 1152 if (options->tcp_keep_alive == -1) 1153 options->tcp_keep_alive = 1; 1154 if (options->compression_level == -1) 1155 options->compression_level = 6; 1156 if (options->port == -1) 1157 options->port = 0; /* Filled in ssh_connect. */ 1158 if (options->address_family == -1) 1159 options->address_family = AF_UNSPEC; 1160 if (options->connection_attempts == -1) 1161 options->connection_attempts = 1; 1162 if (options->number_of_password_prompts == -1) 1163 options->number_of_password_prompts = 3; 1164 /* Selected in ssh_login(). */ 1165 if (options->cipher == -1) 1166 options->cipher = SSH_CIPHER_NOT_SET; 1167 /* options->ciphers, default set in myproposals.h */ 1168 /* options->macs, default set in myproposals.h */ 1169 /* options->hostkeyalgorithms, default set in myproposals.h */ 1170 if (options->protocol == SSH_PROTO_UNKNOWN) 1171 options->protocol = SSH_PROTO_2; 1172 if (options->num_identity_files == 0) { 1173 if (options->protocol & SSH_PROTO_1) { 1174 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 1175 options->identity_files[options->num_identity_files] = 1176 xmalloc(len); 1177 snprintf(options->identity_files[options->num_identity_files++], 1178 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 1179 } 1180 if (options->protocol & SSH_PROTO_2) { 1181 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 1182 options->identity_files[options->num_identity_files] = 1183 xmalloc(len); 1184 snprintf(options->identity_files[options->num_identity_files++], 1185 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 1186 1187 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 1188 options->identity_files[options->num_identity_files] = 1189 xmalloc(len); 1190 snprintf(options->identity_files[options->num_identity_files++], 1191 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 1192 } 1193 } 1194 if (options->escape_char == -1) 1195 options->escape_char = '~'; 1196 if (options->system_hostfile == NULL) 1197 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 1198 if (options->user_hostfile == NULL) 1199 options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 1200 if (options->system_hostfile2 == NULL) 1201 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 1202 if (options->user_hostfile2 == NULL) 1203 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 1204 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1205 options->log_level = SYSLOG_LEVEL_INFO; 1206 if (options->clear_forwardings == 1) 1207 clear_forwardings(options); 1208 if (options->no_host_authentication_for_localhost == - 1) 1209 options->no_host_authentication_for_localhost = 0; 1210 if (options->identities_only == -1) 1211 options->identities_only = 0; 1212 if (options->enable_ssh_keysign == -1) 1213 options->enable_ssh_keysign = 0; 1214 if (options->rekey_limit == -1) 1215 options->rekey_limit = 0; 1216 if (options->verify_host_key_dns == -1) 1217 options->verify_host_key_dns = 0; 1218 if (options->server_alive_interval == -1) 1219 options->server_alive_interval = 0; 1220 if (options->server_alive_count_max == -1) 1221 options->server_alive_count_max = 3; 1222 if (options->control_master == -1) 1223 options->control_master = 0; 1224 if (options->hash_known_hosts == -1) 1225 options->hash_known_hosts = 0; 1226 if (options->tun_open == -1) 1227 options->tun_open = SSH_TUNMODE_NO; 1228 if (options->tun_local == -1) 1229 options->tun_local = SSH_TUNID_ANY; 1230 if (options->tun_remote == -1) 1231 options->tun_remote = SSH_TUNID_ANY; 1232 if (options->permit_local_command == -1) 1233 options->permit_local_command = 0; 1234 if (options->use_roaming == -1) 1235 options->use_roaming = 1; 1236 if (options->visual_host_key == -1) 1237 options->visual_host_key = 0; 1238 if (options->zero_knowledge_password_authentication == -1) 1239 options->zero_knowledge_password_authentication = 0; 1240 /* options->local_command should not be set by default */ 1241 /* options->proxy_command should not be set by default */ 1242 /* options->user will be set in the main program if appropriate */ 1243 /* options->hostname will be set in the main program if appropriate */ 1244 /* options->host_key_alias should not be set by default */ 1245 /* options->preferred_authentications will be set in ssh */ 1246 } 1247 1248 /* 1249 * parse_forward 1250 * parses a string containing a port forwarding specification of the form: 1251 * dynamicfwd == 0 1252 * [listenhost:]listenport:connecthost:connectport 1253 * dynamicfwd == 1 1254 * [listenhost:]listenport 1255 * returns number of arguments parsed or zero on error 1256 */ 1257 int 1258 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1259 { 1260 int i; 1261 char *p, *cp, *fwdarg[4]; 1262 1263 memset(fwd, '\0', sizeof(*fwd)); 1264 1265 cp = p = xstrdup(fwdspec); 1266 1267 /* skip leading spaces */ 1268 while (isspace(*cp)) 1269 cp++; 1270 1271 for (i = 0; i < 4; ++i) 1272 if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1273 break; 1274 1275 /* Check for trailing garbage */ 1276 if (cp != NULL) 1277 i = 0; /* failure */ 1278 1279 switch (i) { 1280 case 1: 1281 fwd->listen_host = NULL; 1282 fwd->listen_port = a2port(fwdarg[0]); 1283 fwd->connect_host = xstrdup("socks"); 1284 break; 1285 1286 case 2: 1287 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1288 fwd->listen_port = a2port(fwdarg[1]); 1289 fwd->connect_host = xstrdup("socks"); 1290 break; 1291 1292 case 3: 1293 fwd->listen_host = NULL; 1294 fwd->listen_port = a2port(fwdarg[0]); 1295 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1296 fwd->connect_port = a2port(fwdarg[2]); 1297 break; 1298 1299 case 4: 1300 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1301 fwd->listen_port = a2port(fwdarg[1]); 1302 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1303 fwd->connect_port = a2port(fwdarg[3]); 1304 break; 1305 default: 1306 i = 0; /* failure */ 1307 } 1308 1309 xfree(p); 1310 1311 if (dynamicfwd) { 1312 if (!(i == 1 || i == 2)) 1313 goto fail_free; 1314 } else { 1315 if (!(i == 3 || i == 4)) 1316 goto fail_free; 1317 if (fwd->connect_port <= 0) 1318 goto fail_free; 1319 } 1320 1321 if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1322 goto fail_free; 1323 1324 if (fwd->connect_host != NULL && 1325 strlen(fwd->connect_host) >= NI_MAXHOST) 1326 goto fail_free; 1327 if (fwd->listen_host != NULL && 1328 strlen(fwd->listen_host) >= NI_MAXHOST) 1329 goto fail_free; 1330 1331 1332 return (i); 1333 1334 fail_free: 1335 if (fwd->connect_host != NULL) { 1336 xfree(fwd->connect_host); 1337 fwd->connect_host = NULL; 1338 } 1339 if (fwd->listen_host != NULL) { 1340 xfree(fwd->listen_host); 1341 fwd->listen_host = NULL; 1342 } 1343 return (0); 1344 } 1345