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 #include "includes.h" 15 RCSID("$OpenBSD: readconf.c,v 1.93 2001/12/19 07:18:56 deraadt Exp $"); 16 17 #include "ssh.h" 18 #include "xmalloc.h" 19 #include "compat.h" 20 #include "cipher.h" 21 #include "pathnames.h" 22 #include "log.h" 23 #include "readconf.h" 24 #include "match.h" 25 #include "misc.h" 26 #include "kex.h" 27 #include "mac.h" 28 29 /* Format of the configuration file: 30 31 # Configuration data is parsed as follows: 32 # 1. command line options 33 # 2. user-specific file 34 # 3. system-wide file 35 # Any configuration value is only changed the first time it is set. 36 # Thus, host-specific definitions should be at the beginning of the 37 # configuration file, and defaults at the end. 38 39 # Host-specific declarations. These may override anything above. A single 40 # host may match multiple declarations; these are processed in the order 41 # that they are given in. 42 43 Host *.ngs.fi ngs.fi 44 FallBackToRsh no 45 46 Host fake.com 47 HostName another.host.name.real.org 48 User blaah 49 Port 34289 50 ForwardX11 no 51 ForwardAgent no 52 53 Host books.com 54 RemoteForward 9999 shadows.cs.hut.fi:9999 55 Cipher 3des 56 57 Host fascist.blob.com 58 Port 23123 59 User tylonen 60 RhostsAuthentication no 61 PasswordAuthentication no 62 63 Host puukko.hut.fi 64 User t35124p 65 ProxyCommand ssh-proxy %h %p 66 67 Host *.fr 68 UseRsh yes 69 70 Host *.su 71 Cipher none 72 PasswordAuthentication no 73 74 # Defaults for various options 75 Host * 76 ForwardAgent no 77 ForwardX11 no 78 RhostsAuthentication yes 79 PasswordAuthentication yes 80 RSAAuthentication yes 81 RhostsRSAAuthentication yes 82 FallBackToRsh no 83 UseRsh no 84 StrictHostKeyChecking yes 85 KeepAlives no 86 IdentityFile ~/.ssh/identity 87 Port 22 88 EscapeChar ~ 89 90 */ 91 92 /* Keyword tokens. */ 93 94 typedef enum { 95 oBadOption, 96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 98 oChallengeResponseAuthentication, oXAuthLocation, 99 #if defined(KRB4) || defined(KRB5) 100 oKerberosAuthentication, 101 #endif 102 #if defined(AFS) || defined(KRB5) 103 oKerberosTgtPassing, 104 #endif 105 #ifdef AFS 106 oAFSTokenPassing, 107 #endif 108 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 109 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 110 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 111 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 112 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, 113 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 114 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 115 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 116 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 117 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 118 oClearAllForwardings, oNoHostAuthenticationForLocalhost 119 } OpCodes; 120 121 /* Textual representations of the tokens. */ 122 123 static struct { 124 const char *name; 125 OpCodes opcode; 126 } keywords[] = { 127 { "forwardagent", oForwardAgent }, 128 { "forwardx11", oForwardX11 }, 129 { "xauthlocation", oXAuthLocation }, 130 { "gatewayports", oGatewayPorts }, 131 { "useprivilegedport", oUsePrivilegedPort }, 132 { "rhostsauthentication", oRhostsAuthentication }, 133 { "passwordauthentication", oPasswordAuthentication }, 134 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 135 { "kbdinteractivedevices", oKbdInteractiveDevices }, 136 { "rsaauthentication", oRSAAuthentication }, 137 { "pubkeyauthentication", oPubkeyAuthentication }, 138 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 139 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 140 { "hostbasedauthentication", oHostbasedAuthentication }, 141 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 142 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 143 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 144 #if defined(KRB4) || defined(KRB5) 145 { "kerberosauthentication", oKerberosAuthentication }, 146 #endif 147 #if defined(AFS) || defined(KRB5) 148 { "kerberostgtpassing", oKerberosTgtPassing }, 149 #endif 150 #ifdef AFS 151 { "afstokenpassing", oAFSTokenPassing }, 152 #endif 153 { "fallbacktorsh", oFallBackToRsh }, 154 { "usersh", oUseRsh }, 155 { "identityfile", oIdentityFile }, 156 { "identityfile2", oIdentityFile }, /* alias */ 157 { "hostname", oHostName }, 158 { "hostkeyalias", oHostKeyAlias }, 159 { "proxycommand", oProxyCommand }, 160 { "port", oPort }, 161 { "cipher", oCipher }, 162 { "ciphers", oCiphers }, 163 { "macs", oMacs }, 164 { "protocol", oProtocol }, 165 { "remoteforward", oRemoteForward }, 166 { "localforward", oLocalForward }, 167 { "user", oUser }, 168 { "host", oHost }, 169 { "escapechar", oEscapeChar }, 170 { "globalknownhostsfile", oGlobalKnownHostsFile }, 171 { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ 172 { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 173 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 174 { "connectionattempts", oConnectionAttempts }, 175 { "batchmode", oBatchMode }, 176 { "checkhostip", oCheckHostIP }, 177 { "stricthostkeychecking", oStrictHostKeyChecking }, 178 { "compression", oCompression }, 179 { "compressionlevel", oCompressionLevel }, 180 { "keepalive", oKeepAlives }, 181 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 182 { "loglevel", oLogLevel }, 183 { "dynamicforward", oDynamicForward }, 184 { "preferredauthentications", oPreferredAuthentications }, 185 { "hostkeyalgorithms", oHostKeyAlgorithms }, 186 { "bindaddress", oBindAddress }, 187 { "smartcarddevice", oSmartcardDevice }, 188 { "clearallforwardings", oClearAllForwardings }, 189 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 190 { NULL, oBadOption } 191 }; 192 193 /* 194 * Adds a local TCP/IP port forward to options. Never returns if there is an 195 * error. 196 */ 197 198 void 199 add_local_forward(Options *options, u_short port, const char *host, 200 u_short host_port) 201 { 202 Forward *fwd; 203 extern uid_t original_real_uid; 204 if (port < IPPORT_RESERVED && original_real_uid != 0) 205 fatal("Privileged ports can only be forwarded by root."); 206 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 207 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 208 fwd = &options->local_forwards[options->num_local_forwards++]; 209 fwd->port = port; 210 fwd->host = xstrdup(host); 211 fwd->host_port = host_port; 212 } 213 214 /* 215 * Adds a remote TCP/IP port forward to options. Never returns if there is 216 * an error. 217 */ 218 219 void 220 add_remote_forward(Options *options, u_short port, const char *host, 221 u_short host_port) 222 { 223 Forward *fwd; 224 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 225 fatal("Too many remote forwards (max %d).", 226 SSH_MAX_FORWARDS_PER_DIRECTION); 227 fwd = &options->remote_forwards[options->num_remote_forwards++]; 228 fwd->port = port; 229 fwd->host = xstrdup(host); 230 fwd->host_port = host_port; 231 } 232 233 static void 234 clear_forwardings(Options *options) 235 { 236 int i; 237 238 for (i = 0; i < options->num_local_forwards; i++) 239 xfree(options->local_forwards[i].host); 240 options->num_local_forwards = 0; 241 for (i = 0; i < options->num_remote_forwards; i++) 242 xfree(options->remote_forwards[i].host); 243 options->num_remote_forwards = 0; 244 } 245 246 /* 247 * Returns the number of the token pointed to by cp or oBadOption. 248 */ 249 250 static OpCodes 251 parse_token(const char *cp, const char *filename, int linenum) 252 { 253 u_int i; 254 255 for (i = 0; keywords[i].name; i++) 256 if (strcasecmp(cp, keywords[i].name) == 0) 257 return keywords[i].opcode; 258 259 error("%s: line %d: Bad configuration option: %s", 260 filename, linenum, cp); 261 return oBadOption; 262 } 263 264 /* 265 * Processes a single option line as used in the configuration files. This 266 * only sets those values that have not already been set. 267 */ 268 269 int 270 process_config_line(Options *options, const char *host, 271 char *line, const char *filename, int linenum, 272 int *activep) 273 { 274 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; 275 int opcode, *intptr, value; 276 u_short fwd_port, fwd_host_port; 277 char sfwd_host_port[6]; 278 279 s = line; 280 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 281 keyword = strdelim(&s); 282 /* Ignore leading whitespace. */ 283 if (*keyword == '\0') 284 keyword = strdelim(&s); 285 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 286 return 0; 287 288 opcode = parse_token(keyword, filename, linenum); 289 290 switch (opcode) { 291 case oBadOption: 292 /* don't panic, but count bad options */ 293 return -1; 294 /* NOTREACHED */ 295 case oForwardAgent: 296 intptr = &options->forward_agent; 297 parse_flag: 298 arg = strdelim(&s); 299 if (!arg || *arg == '\0') 300 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 301 value = 0; /* To avoid compiler warning... */ 302 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 303 value = 1; 304 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 305 value = 0; 306 else 307 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 308 if (*activep && *intptr == -1) 309 *intptr = value; 310 break; 311 312 case oForwardX11: 313 intptr = &options->forward_x11; 314 goto parse_flag; 315 316 case oGatewayPorts: 317 intptr = &options->gateway_ports; 318 goto parse_flag; 319 320 case oUsePrivilegedPort: 321 intptr = &options->use_privileged_port; 322 goto parse_flag; 323 324 case oRhostsAuthentication: 325 intptr = &options->rhosts_authentication; 326 goto parse_flag; 327 328 case oPasswordAuthentication: 329 intptr = &options->password_authentication; 330 goto parse_flag; 331 332 case oKbdInteractiveAuthentication: 333 intptr = &options->kbd_interactive_authentication; 334 goto parse_flag; 335 336 case oKbdInteractiveDevices: 337 charptr = &options->kbd_interactive_devices; 338 goto parse_string; 339 340 case oPubkeyAuthentication: 341 intptr = &options->pubkey_authentication; 342 goto parse_flag; 343 344 case oRSAAuthentication: 345 intptr = &options->rsa_authentication; 346 goto parse_flag; 347 348 case oRhostsRSAAuthentication: 349 intptr = &options->rhosts_rsa_authentication; 350 goto parse_flag; 351 352 case oHostbasedAuthentication: 353 intptr = &options->hostbased_authentication; 354 goto parse_flag; 355 356 case oChallengeResponseAuthentication: 357 intptr = &options->challenge_response_authentication; 358 goto parse_flag; 359 #if defined(KRB4) || defined(KRB5) 360 case oKerberosAuthentication: 361 intptr = &options->kerberos_authentication; 362 goto parse_flag; 363 #endif 364 #if defined(AFS) || defined(KRB5) 365 case oKerberosTgtPassing: 366 intptr = &options->kerberos_tgt_passing; 367 goto parse_flag; 368 #endif 369 #ifdef AFS 370 case oAFSTokenPassing: 371 intptr = &options->afs_token_passing; 372 goto parse_flag; 373 #endif 374 case oFallBackToRsh: 375 intptr = &options->fallback_to_rsh; 376 goto parse_flag; 377 378 case oUseRsh: 379 intptr = &options->use_rsh; 380 goto parse_flag; 381 382 case oBatchMode: 383 intptr = &options->batch_mode; 384 goto parse_flag; 385 386 case oCheckHostIP: 387 intptr = &options->check_host_ip; 388 goto parse_flag; 389 390 case oStrictHostKeyChecking: 391 intptr = &options->strict_host_key_checking; 392 arg = strdelim(&s); 393 if (!arg || *arg == '\0') 394 fatal("%.200s line %d: Missing yes/no/ask argument.", 395 filename, linenum); 396 value = 0; /* To avoid compiler warning... */ 397 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 398 value = 1; 399 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 400 value = 0; 401 else if (strcmp(arg, "ask") == 0) 402 value = 2; 403 else 404 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 405 if (*activep && *intptr == -1) 406 *intptr = value; 407 break; 408 409 case oCompression: 410 intptr = &options->compression; 411 goto parse_flag; 412 413 case oKeepAlives: 414 intptr = &options->keepalives; 415 goto parse_flag; 416 417 case oNoHostAuthenticationForLocalhost: 418 intptr = &options->no_host_authentication_for_localhost; 419 goto parse_flag; 420 421 case oNumberOfPasswordPrompts: 422 intptr = &options->number_of_password_prompts; 423 goto parse_int; 424 425 case oCompressionLevel: 426 intptr = &options->compression_level; 427 goto parse_int; 428 429 case oIdentityFile: 430 arg = strdelim(&s); 431 if (!arg || *arg == '\0') 432 fatal("%.200s line %d: Missing argument.", filename, linenum); 433 if (*activep) { 434 intptr = &options->num_identity_files; 435 if (*intptr >= SSH_MAX_IDENTITY_FILES) 436 fatal("%.200s line %d: Too many identity files specified (max %d).", 437 filename, linenum, SSH_MAX_IDENTITY_FILES); 438 charptr = &options->identity_files[*intptr]; 439 *charptr = xstrdup(arg); 440 *intptr = *intptr + 1; 441 } 442 break; 443 444 case oXAuthLocation: 445 charptr=&options->xauth_location; 446 goto parse_string; 447 448 case oUser: 449 charptr = &options->user; 450 parse_string: 451 arg = strdelim(&s); 452 if (!arg || *arg == '\0') 453 fatal("%.200s line %d: Missing argument.", filename, linenum); 454 if (*activep && *charptr == NULL) 455 *charptr = xstrdup(arg); 456 break; 457 458 case oGlobalKnownHostsFile: 459 charptr = &options->system_hostfile; 460 goto parse_string; 461 462 case oUserKnownHostsFile: 463 charptr = &options->user_hostfile; 464 goto parse_string; 465 466 case oGlobalKnownHostsFile2: 467 charptr = &options->system_hostfile2; 468 goto parse_string; 469 470 case oUserKnownHostsFile2: 471 charptr = &options->user_hostfile2; 472 goto parse_string; 473 474 case oHostName: 475 charptr = &options->hostname; 476 goto parse_string; 477 478 case oHostKeyAlias: 479 charptr = &options->host_key_alias; 480 goto parse_string; 481 482 case oPreferredAuthentications: 483 charptr = &options->preferred_authentications; 484 goto parse_string; 485 486 case oBindAddress: 487 charptr = &options->bind_address; 488 goto parse_string; 489 490 case oSmartcardDevice: 491 charptr = &options->smartcard_device; 492 goto parse_string; 493 494 case oProxyCommand: 495 charptr = &options->proxy_command; 496 string = xstrdup(""); 497 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 498 string = xrealloc(string, strlen(string) + strlen(arg) + 2); 499 strcat(string, " "); 500 strcat(string, arg); 501 } 502 if (*activep && *charptr == NULL) 503 *charptr = string; 504 else 505 xfree(string); 506 return 0; 507 508 case oPort: 509 intptr = &options->port; 510 parse_int: 511 arg = strdelim(&s); 512 if (!arg || *arg == '\0') 513 fatal("%.200s line %d: Missing argument.", filename, linenum); 514 if (arg[0] < '0' || arg[0] > '9') 515 fatal("%.200s line %d: Bad number.", filename, linenum); 516 517 /* Octal, decimal, or hex format? */ 518 value = strtol(arg, &endofnumber, 0); 519 if (arg == endofnumber) 520 fatal("%.200s line %d: Bad number.", filename, linenum); 521 if (*activep && *intptr == -1) 522 *intptr = value; 523 break; 524 525 case oConnectionAttempts: 526 intptr = &options->connection_attempts; 527 goto parse_int; 528 529 case oCipher: 530 intptr = &options->cipher; 531 arg = strdelim(&s); 532 if (!arg || *arg == '\0') 533 fatal("%.200s line %d: Missing argument.", filename, linenum); 534 value = cipher_number(arg); 535 if (value == -1) 536 fatal("%.200s line %d: Bad cipher '%s'.", 537 filename, linenum, arg ? arg : "<NONE>"); 538 if (*activep && *intptr == -1) 539 *intptr = value; 540 break; 541 542 case oCiphers: 543 arg = strdelim(&s); 544 if (!arg || *arg == '\0') 545 fatal("%.200s line %d: Missing argument.", filename, linenum); 546 if (!ciphers_valid(arg)) 547 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 548 filename, linenum, arg ? arg : "<NONE>"); 549 if (*activep && options->ciphers == NULL) 550 options->ciphers = xstrdup(arg); 551 break; 552 553 case oMacs: 554 arg = strdelim(&s); 555 if (!arg || *arg == '\0') 556 fatal("%.200s line %d: Missing argument.", filename, linenum); 557 if (!mac_valid(arg)) 558 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 559 filename, linenum, arg ? arg : "<NONE>"); 560 if (*activep && options->macs == NULL) 561 options->macs = xstrdup(arg); 562 break; 563 564 case oHostKeyAlgorithms: 565 arg = strdelim(&s); 566 if (!arg || *arg == '\0') 567 fatal("%.200s line %d: Missing argument.", filename, linenum); 568 if (!key_names_valid2(arg)) 569 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 570 filename, linenum, arg ? arg : "<NONE>"); 571 if (*activep && options->hostkeyalgorithms == NULL) 572 options->hostkeyalgorithms = xstrdup(arg); 573 break; 574 575 case oProtocol: 576 intptr = &options->protocol; 577 arg = strdelim(&s); 578 if (!arg || *arg == '\0') 579 fatal("%.200s line %d: Missing argument.", filename, linenum); 580 value = proto_spec(arg); 581 if (value == SSH_PROTO_UNKNOWN) 582 fatal("%.200s line %d: Bad protocol spec '%s'.", 583 filename, linenum, arg ? arg : "<NONE>"); 584 if (*activep && *intptr == SSH_PROTO_UNKNOWN) 585 *intptr = value; 586 break; 587 588 case oLogLevel: 589 intptr = (int *) &options->log_level; 590 arg = strdelim(&s); 591 value = log_level_number(arg); 592 if (value == (LogLevel) - 1) 593 fatal("%.200s line %d: unsupported log level '%s'", 594 filename, linenum, arg ? arg : "<NONE>"); 595 if (*activep && (LogLevel) * intptr == -1) 596 *intptr = (LogLevel) value; 597 break; 598 599 case oLocalForward: 600 case oRemoteForward: 601 arg = strdelim(&s); 602 if (!arg || *arg == '\0') 603 fatal("%.200s line %d: Missing port argument.", 604 filename, linenum); 605 if ((fwd_port = a2port(arg)) == 0) 606 fatal("%.200s line %d: Bad listen port.", 607 filename, linenum); 608 arg = strdelim(&s); 609 if (!arg || *arg == '\0') 610 fatal("%.200s line %d: Missing second argument.", 611 filename, linenum); 612 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && 613 sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) 614 fatal("%.200s line %d: Bad forwarding specification.", 615 filename, linenum); 616 if ((fwd_host_port = a2port(sfwd_host_port)) == 0) 617 fatal("%.200s line %d: Bad forwarding port.", 618 filename, linenum); 619 if (*activep) { 620 if (opcode == oLocalForward) 621 add_local_forward(options, fwd_port, buf, 622 fwd_host_port); 623 else if (opcode == oRemoteForward) 624 add_remote_forward(options, fwd_port, buf, 625 fwd_host_port); 626 } 627 break; 628 629 case oDynamicForward: 630 arg = strdelim(&s); 631 if (!arg || *arg == '\0') 632 fatal("%.200s line %d: Missing port argument.", 633 filename, linenum); 634 fwd_port = a2port(arg); 635 if (fwd_port == 0) 636 fatal("%.200s line %d: Badly formatted port number.", 637 filename, linenum); 638 if (*activep) 639 add_local_forward(options, fwd_port, "socks4", 0); 640 break; 641 642 case oClearAllForwardings: 643 intptr = &options->clear_forwardings; 644 goto parse_flag; 645 646 case oHost: 647 *activep = 0; 648 while ((arg = strdelim(&s)) != NULL && *arg != '\0') 649 if (match_pattern(host, arg)) { 650 debug("Applying options for %.100s", arg); 651 *activep = 1; 652 break; 653 } 654 /* Avoid garbage check below, as strdelim is done. */ 655 return 0; 656 657 case oEscapeChar: 658 intptr = &options->escape_char; 659 arg = strdelim(&s); 660 if (!arg || *arg == '\0') 661 fatal("%.200s line %d: Missing argument.", filename, linenum); 662 if (arg[0] == '^' && arg[2] == 0 && 663 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 664 value = (u_char) arg[1] & 31; 665 else if (strlen(arg) == 1) 666 value = (u_char) arg[0]; 667 else if (strcmp(arg, "none") == 0) 668 value = SSH_ESCAPECHAR_NONE; 669 else { 670 fatal("%.200s line %d: Bad escape character.", 671 filename, linenum); 672 /* NOTREACHED */ 673 value = 0; /* Avoid compiler warning. */ 674 } 675 if (*activep && *intptr == -1) 676 *intptr = value; 677 break; 678 679 default: 680 fatal("process_config_line: Unimplemented opcode %d", opcode); 681 } 682 683 /* Check that there is no garbage at end of line. */ 684 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 685 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 686 filename, linenum, arg); 687 } 688 return 0; 689 } 690 691 692 /* 693 * Reads the config file and modifies the options accordingly. Options 694 * should already be initialized before this call. This never returns if 695 * there is an error. If the file does not exist, this returns 0. 696 */ 697 698 int 699 read_config_file(const char *filename, const char *host, Options *options) 700 { 701 FILE *f; 702 char line[1024]; 703 int active, linenum; 704 int bad_options = 0; 705 706 /* Open the file. */ 707 f = fopen(filename, "r"); 708 if (!f) 709 return 0; 710 711 debug("Reading configuration data %.200s", filename); 712 713 /* 714 * Mark that we are now processing the options. This flag is turned 715 * on/off by Host specifications. 716 */ 717 active = 1; 718 linenum = 0; 719 while (fgets(line, sizeof(line), f)) { 720 /* Update line number counter. */ 721 linenum++; 722 if (process_config_line(options, host, line, filename, linenum, &active) != 0) 723 bad_options++; 724 } 725 fclose(f); 726 if (bad_options > 0) 727 fatal("%s: terminating, %d bad configuration options", 728 filename, bad_options); 729 return 1; 730 } 731 732 /* 733 * Initializes options to special values that indicate that they have not yet 734 * been set. Read_config_file will only set options with this value. Options 735 * are processed in the following order: command line, user config file, 736 * system config file. Last, fill_default_options is called. 737 */ 738 739 void 740 initialize_options(Options * options) 741 { 742 memset(options, 'X', sizeof(*options)); 743 options->forward_agent = -1; 744 options->forward_x11 = -1; 745 options->xauth_location = NULL; 746 options->gateway_ports = -1; 747 options->use_privileged_port = -1; 748 options->rhosts_authentication = -1; 749 options->rsa_authentication = -1; 750 options->pubkey_authentication = -1; 751 options->challenge_response_authentication = -1; 752 #if defined(KRB4) || defined(KRB5) 753 options->kerberos_authentication = -1; 754 #endif 755 #if defined(AFS) || defined(KRB5) 756 options->kerberos_tgt_passing = -1; 757 #endif 758 #ifdef AFS 759 options->afs_token_passing = -1; 760 #endif 761 options->password_authentication = -1; 762 options->kbd_interactive_authentication = -1; 763 options->kbd_interactive_devices = NULL; 764 options->rhosts_rsa_authentication = -1; 765 options->hostbased_authentication = -1; 766 options->fallback_to_rsh = -1; 767 options->use_rsh = -1; 768 options->batch_mode = -1; 769 options->check_host_ip = -1; 770 options->strict_host_key_checking = -1; 771 options->compression = -1; 772 options->keepalives = -1; 773 options->compression_level = -1; 774 options->port = -1; 775 options->connection_attempts = -1; 776 options->number_of_password_prompts = -1; 777 options->cipher = -1; 778 options->ciphers = NULL; 779 options->macs = NULL; 780 options->hostkeyalgorithms = NULL; 781 options->protocol = SSH_PROTO_UNKNOWN; 782 options->num_identity_files = 0; 783 options->hostname = NULL; 784 options->host_key_alias = NULL; 785 options->proxy_command = NULL; 786 options->user = NULL; 787 options->escape_char = -1; 788 options->system_hostfile = NULL; 789 options->user_hostfile = NULL; 790 options->system_hostfile2 = NULL; 791 options->user_hostfile2 = NULL; 792 options->num_local_forwards = 0; 793 options->num_remote_forwards = 0; 794 options->clear_forwardings = -1; 795 options->log_level = (LogLevel) - 1; 796 options->preferred_authentications = NULL; 797 options->bind_address = NULL; 798 options->smartcard_device = NULL; 799 options->no_host_authentication_for_localhost = - 1; 800 } 801 802 /* 803 * Called after processing other sources of option data, this fills those 804 * options for which no value has been specified with their default values. 805 */ 806 807 void 808 fill_default_options(Options * options) 809 { 810 int len; 811 812 if (options->forward_agent == -1) 813 options->forward_agent = 0; 814 if (options->forward_x11 == -1) 815 options->forward_x11 = 0; 816 #ifdef _PATH_XAUTH 817 if (options->xauth_location == NULL) 818 options->xauth_location = _PATH_XAUTH; 819 #endif 820 if (options->gateway_ports == -1) 821 options->gateway_ports = 0; 822 if (options->use_privileged_port == -1) 823 options->use_privileged_port = 0; 824 if (options->rhosts_authentication == -1) 825 options->rhosts_authentication = 1; 826 if (options->rsa_authentication == -1) 827 options->rsa_authentication = 1; 828 if (options->pubkey_authentication == -1) 829 options->pubkey_authentication = 1; 830 if (options->challenge_response_authentication == -1) 831 options->challenge_response_authentication = 1; 832 #if defined(KRB4) || defined(KRB5) 833 if (options->kerberos_authentication == -1) 834 options->kerberos_authentication = 1; 835 #endif 836 #if defined(AFS) || defined(KRB5) 837 if (options->kerberos_tgt_passing == -1) 838 options->kerberos_tgt_passing = 1; 839 #endif 840 #ifdef AFS 841 if (options->afs_token_passing == -1) 842 options->afs_token_passing = 1; 843 #endif 844 if (options->password_authentication == -1) 845 options->password_authentication = 1; 846 if (options->kbd_interactive_authentication == -1) 847 options->kbd_interactive_authentication = 1; 848 if (options->rhosts_rsa_authentication == -1) 849 options->rhosts_rsa_authentication = 1; 850 if (options->hostbased_authentication == -1) 851 options->hostbased_authentication = 0; 852 if (options->fallback_to_rsh == -1) 853 options->fallback_to_rsh = 0; 854 if (options->use_rsh == -1) 855 options->use_rsh = 0; 856 if (options->batch_mode == -1) 857 options->batch_mode = 0; 858 if (options->check_host_ip == -1) 859 options->check_host_ip = 1; 860 if (options->strict_host_key_checking == -1) 861 options->strict_host_key_checking = 2; /* 2 is default */ 862 if (options->compression == -1) 863 options->compression = 0; 864 if (options->keepalives == -1) 865 options->keepalives = 1; 866 if (options->compression_level == -1) 867 options->compression_level = 6; 868 if (options->port == -1) 869 options->port = 0; /* Filled in ssh_connect. */ 870 if (options->connection_attempts == -1) 871 options->connection_attempts = 1; 872 if (options->number_of_password_prompts == -1) 873 options->number_of_password_prompts = 3; 874 /* Selected in ssh_login(). */ 875 if (options->cipher == -1) 876 options->cipher = SSH_CIPHER_NOT_SET; 877 /* options->ciphers, default set in myproposals.h */ 878 /* options->macs, default set in myproposals.h */ 879 /* options->hostkeyalgorithms, default set in myproposals.h */ 880 if (options->protocol == SSH_PROTO_UNKNOWN) 881 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 882 if (options->num_identity_files == 0) { 883 if (options->protocol & SSH_PROTO_1) { 884 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 885 options->identity_files[options->num_identity_files] = 886 xmalloc(len); 887 snprintf(options->identity_files[options->num_identity_files++], 888 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 889 } 890 if (options->protocol & SSH_PROTO_2) { 891 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 892 options->identity_files[options->num_identity_files] = 893 xmalloc(len); 894 snprintf(options->identity_files[options->num_identity_files++], 895 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 896 897 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 898 options->identity_files[options->num_identity_files] = 899 xmalloc(len); 900 snprintf(options->identity_files[options->num_identity_files++], 901 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 902 } 903 } 904 if (options->escape_char == -1) 905 options->escape_char = '~'; 906 if (options->system_hostfile == NULL) 907 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 908 if (options->user_hostfile == NULL) 909 options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 910 if (options->system_hostfile2 == NULL) 911 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 912 if (options->user_hostfile2 == NULL) 913 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 914 if (options->log_level == (LogLevel) - 1) 915 options->log_level = SYSLOG_LEVEL_INFO; 916 if (options->clear_forwardings == 1) 917 clear_forwardings(options); 918 if (options->no_host_authentication_for_localhost == - 1) 919 options->no_host_authentication_for_localhost = 0; 920 /* options->proxy_command should not be set by default */ 921 /* options->user will be set in the main program if appropriate */ 922 /* options->hostname will be set in the main program if appropriate */ 923 /* options->host_key_alias should not be set by default */ 924 /* options->preferred_authentications will be set in ssh */ 925 } 926