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