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