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