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