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