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