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