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