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