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