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