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.76 2001/04/17 10:53:25 markus Exp $"); 16 RCSID("$FreeBSD$"); 17 18 #include "ssh.h" 19 #include "xmalloc.h" 20 #include "compat.h" 21 #include "cipher.h" 22 #include "pathnames.h" 23 #include "log.h" 24 #include "readconf.h" 25 #include "match.h" 26 #include "misc.h" 27 #include "kex.h" 28 #include "mac.h" 29 30 /* Format of the configuration file: 31 32 # Configuration data is parsed as follows: 33 # 1. command line options 34 # 2. user-specific file 35 # 3. system-wide file 36 # Any configuration value is only changed the first time it is set. 37 # Thus, host-specific definitions should be at the beginning of the 38 # configuration file, and defaults at the end. 39 40 # Host-specific declarations. These may override anything above. A single 41 # host may match multiple declarations; these are processed in the order 42 # that they are given in. 43 44 Host *.ngs.fi ngs.fi 45 FallBackToRsh no 46 47 Host fake.com 48 HostName another.host.name.real.org 49 User blaah 50 Port 34289 51 ForwardX11 no 52 ForwardAgent no 53 54 Host books.com 55 RemoteForward 9999 shadows.cs.hut.fi:9999 56 Cipher 3des 57 58 Host fascist.blob.com 59 Port 23123 60 User tylonen 61 RhostsAuthentication no 62 PasswordAuthentication no 63 64 Host puukko.hut.fi 65 User t35124p 66 ProxyCommand ssh-proxy %h %p 67 68 Host *.fr 69 UseRsh yes 70 71 Host *.su 72 Cipher none 73 PasswordAuthentication no 74 75 # Defaults for various options 76 Host * 77 ForwardAgent no 78 ForwardX11 no 79 RhostsAuthentication yes 80 PasswordAuthentication yes 81 RSAAuthentication yes 82 RhostsRSAAuthentication yes 83 FallBackToRsh no 84 UseRsh no 85 StrictHostKeyChecking yes 86 KeepAlives no 87 IdentityFile ~/.ssh/identity 88 Port 22 89 EscapeChar ~ 90 91 */ 92 93 /* Keyword tokens. */ 94 95 typedef enum { 96 oBadOption, 97 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 98 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 99 oChallengeResponseAuthentication, oXAuthLocation, 100 #if defined(KRB4) || defined(KRB5) 101 oKerberosAuthentication, 102 #endif /* KRB4 */ 103 #ifdef KRB5 104 oKrb5TgtPassing, 105 #endif /* KRB5 */ 106 #ifdef AFS 107 oKrb4TgtPassing, oAFSTokenPassing, 108 #endif 109 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 110 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 111 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 112 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 113 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, 114 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 115 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 116 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 117 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 118 oHostKeyAlgorithms 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 /* KRB4 || KRB5 */ 147 #ifdef KRB5 148 { "kerberos5tgtpassing", oKrb5TgtPassing }, 149 #endif /* KRB5 */ 150 #ifdef AFS 151 { "kerberos4tgtpassing", oKrb4TgtPassing }, 152 { "afstokenpassing", oAFSTokenPassing }, 153 #endif 154 { "fallbacktorsh", oFallBackToRsh }, 155 { "usersh", oUseRsh }, 156 { "identityfile", oIdentityFile }, 157 { "identityfile2", oIdentityFile }, /* alias */ 158 { "hostname", oHostName }, 159 { "hostkeyalias", oHostKeyAlias }, 160 { "proxycommand", oProxyCommand }, 161 { "port", oPort }, 162 { "cipher", oCipher }, 163 { "ciphers", oCiphers }, 164 { "macs", oMacs }, 165 { "protocol", oProtocol }, 166 { "remoteforward", oRemoteForward }, 167 { "localforward", oLocalForward }, 168 { "user", oUser }, 169 { "host", oHost }, 170 { "escapechar", oEscapeChar }, 171 { "globalknownhostsfile", oGlobalKnownHostsFile }, 172 { "userknownhostsfile", oUserKnownHostsFile }, 173 { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 174 { "userknownhostsfile2", oUserKnownHostsFile2 }, 175 { "connectionattempts", oConnectionAttempts }, 176 { "batchmode", oBatchMode }, 177 { "checkhostip", oCheckHostIP }, 178 { "stricthostkeychecking", oStrictHostKeyChecking }, 179 { "compression", oCompression }, 180 { "compressionlevel", oCompressionLevel }, 181 { "keepalive", oKeepAlives }, 182 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 183 { "loglevel", oLogLevel }, 184 { "dynamicforward", oDynamicForward }, 185 { "preferredauthentications", oPreferredAuthentications }, 186 { "hostkeyalgorithms", oHostKeyAlgorithms }, 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 #if defined(KRB4) || defined(KRB5) 340 case oKerberosAuthentication: 341 intptr = &options->kerberos_authentication; 342 goto parse_flag; 343 #endif /* KRB4 || KRB5 */ 344 345 case oChallengeResponseAuthentication: 346 intptr = &options->challenge_reponse_authentication; 347 goto parse_flag; 348 349 #ifdef KRB5 350 case oKrb5TgtPassing: 351 intptr = &options->krb5_tgt_passing; 352 goto parse_flag; 353 #endif /* KRB5 */ 354 355 #ifdef AFS 356 case oKrb4TgtPassing: 357 intptr = &options->krb4_tgt_passing; 358 goto parse_flag; 359 360 case oAFSTokenPassing: 361 intptr = &options->afs_token_passing; 362 goto parse_flag; 363 #endif 364 365 case oFallBackToRsh: 366 intptr = &options->fallback_to_rsh; 367 goto parse_flag; 368 369 case oUseRsh: 370 intptr = &options->use_rsh; 371 goto parse_flag; 372 373 case oBatchMode: 374 intptr = &options->batch_mode; 375 goto parse_flag; 376 377 case oCheckHostIP: 378 intptr = &options->check_host_ip; 379 goto parse_flag; 380 381 case oStrictHostKeyChecking: 382 intptr = &options->strict_host_key_checking; 383 arg = strdelim(&s); 384 if (!arg || *arg == '\0') 385 fatal("%.200s line %d: Missing yes/no/ask argument.", 386 filename, linenum); 387 value = 0; /* To avoid compiler warning... */ 388 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 389 value = 1; 390 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 391 value = 0; 392 else if (strcmp(arg, "ask") == 0) 393 value = 2; 394 else 395 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 396 if (*activep && *intptr == -1) 397 *intptr = value; 398 break; 399 400 case oCompression: 401 intptr = &options->compression; 402 goto parse_flag; 403 404 case oKeepAlives: 405 intptr = &options->keepalives; 406 goto parse_flag; 407 408 case oNumberOfPasswordPrompts: 409 intptr = &options->number_of_password_prompts; 410 goto parse_int; 411 412 case oCompressionLevel: 413 intptr = &options->compression_level; 414 goto parse_int; 415 416 case oIdentityFile: 417 arg = strdelim(&s); 418 if (!arg || *arg == '\0') 419 fatal("%.200s line %d: Missing argument.", filename, linenum); 420 if (*activep) { 421 intptr = &options->num_identity_files; 422 if (*intptr >= SSH_MAX_IDENTITY_FILES) 423 fatal("%.200s line %d: Too many identity files specified (max %d).", 424 filename, linenum, SSH_MAX_IDENTITY_FILES); 425 charptr = &options->identity_files[*intptr]; 426 *charptr = xstrdup(arg); 427 *intptr = *intptr + 1; 428 } 429 break; 430 431 case oXAuthLocation: 432 charptr=&options->xauth_location; 433 goto parse_string; 434 435 case oUser: 436 charptr = &options->user; 437 parse_string: 438 arg = strdelim(&s); 439 if (!arg || *arg == '\0') 440 fatal("%.200s line %d: Missing argument.", filename, linenum); 441 if (*activep && *charptr == NULL) 442 *charptr = xstrdup(arg); 443 break; 444 445 case oGlobalKnownHostsFile: 446 charptr = &options->system_hostfile; 447 goto parse_string; 448 449 case oUserKnownHostsFile: 450 charptr = &options->user_hostfile; 451 goto parse_string; 452 453 case oGlobalKnownHostsFile2: 454 charptr = &options->system_hostfile2; 455 goto parse_string; 456 457 case oUserKnownHostsFile2: 458 charptr = &options->user_hostfile2; 459 goto parse_string; 460 461 case oHostName: 462 charptr = &options->hostname; 463 goto parse_string; 464 465 case oHostKeyAlias: 466 charptr = &options->host_key_alias; 467 goto parse_string; 468 469 case oPreferredAuthentications: 470 charptr = &options->preferred_authentications; 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 = -2; 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_reponse_authentication = -1; 733 #if defined(KRB4) || defined(KRB5) 734 options->kerberos_authentication = -1; 735 #endif 736 #ifdef KRB5 737 options->krb5_tgt_passing = -1; 738 #endif /* KRB5 */ 739 #ifdef AFS 740 options->krb4_tgt_passing = -1; 741 options->afs_token_passing = -1; 742 #endif 743 options->password_authentication = -1; 744 options->kbd_interactive_authentication = -1; 745 options->kbd_interactive_devices = NULL; 746 options->rhosts_rsa_authentication = -1; 747 options->hostbased_authentication = -1; 748 options->fallback_to_rsh = -1; 749 options->use_rsh = -1; 750 options->batch_mode = -1; 751 options->check_host_ip = -1; 752 options->strict_host_key_checking = -1; 753 options->compression = -1; 754 options->keepalives = -1; 755 options->compression_level = -1; 756 options->port = -1; 757 options->connection_attempts = -1; 758 options->number_of_password_prompts = -1; 759 options->cipher = -1; 760 options->ciphers = NULL; 761 options->macs = NULL; 762 options->hostkeyalgorithms = NULL; 763 options->protocol = SSH_PROTO_UNKNOWN; 764 options->num_identity_files = 0; 765 options->hostname = NULL; 766 options->host_key_alias = NULL; 767 options->proxy_command = NULL; 768 options->user = NULL; 769 options->escape_char = -1; 770 options->system_hostfile = NULL; 771 options->user_hostfile = NULL; 772 options->system_hostfile2 = NULL; 773 options->user_hostfile2 = NULL; 774 options->num_local_forwards = 0; 775 options->num_remote_forwards = 0; 776 options->log_level = (LogLevel) - 1; 777 options->preferred_authentications = NULL; 778 } 779 780 /* 781 * Called after processing other sources of option data, this fills those 782 * options for which no value has been specified with their default values. 783 */ 784 785 void 786 fill_default_options(Options * options) 787 { 788 int len; 789 790 if (options->forward_agent == -1) 791 options->forward_agent = 0; 792 if (options->forward_x11 == -1) 793 options->forward_x11 = 0; 794 #ifdef XAUTH_PATH 795 if (options->xauth_location == NULL) 796 options->xauth_location = XAUTH_PATH; 797 #endif /* XAUTH_PATH */ 798 if (options->gateway_ports == -1) 799 options->gateway_ports = 0; 800 if (options->use_privileged_port == -1) 801 options->use_privileged_port = 0; 802 if (options->rhosts_authentication == -1) 803 options->rhosts_authentication = 1; 804 if (options->rsa_authentication == -1) 805 options->rsa_authentication = 1; 806 if (options->pubkey_authentication == -1) 807 options->pubkey_authentication = 1; 808 if (options->challenge_reponse_authentication == -1) 809 options->challenge_reponse_authentication = 0; 810 #if defined(KRB4) || defined(KRB5) 811 if (options->kerberos_authentication == -1) 812 options->kerberos_authentication = 1; 813 #endif /* KRB4 || KRB5 */ 814 #ifdef KRB5 815 if (options->krb5_tgt_passing == -1) 816 options->krb5_tgt_passing = 1; 817 #endif /* KRB5 */ 818 #ifdef AFS 819 if (options->krb4_tgt_passing == -1) 820 options->krb4_tgt_passing = 1; 821 if (options->afs_token_passing == -1) 822 options->afs_token_passing = 1; 823 #endif /* AFS */ 824 if (options->password_authentication == -1) 825 options->password_authentication = 1; 826 if (options->kbd_interactive_authentication == -1) 827 options->kbd_interactive_authentication = 1; 828 if (options->rhosts_rsa_authentication == -1) 829 options->rhosts_rsa_authentication = 1; 830 if (options->hostbased_authentication == -1) 831 options->hostbased_authentication = 0; 832 if (options->fallback_to_rsh == -1) 833 options->fallback_to_rsh = 0; 834 if (options->use_rsh == -1) 835 options->use_rsh = 0; 836 if (options->batch_mode == -1) 837 options->batch_mode = 0; 838 if (options->check_host_ip == -1) 839 options->check_host_ip = 0; 840 if (options->strict_host_key_checking == -1) 841 options->strict_host_key_checking = 2; /* 2 is default */ 842 if (options->compression == -1) 843 options->compression = 0; 844 if (options->keepalives == -1) 845 options->keepalives = 1; 846 if (options->compression_level == -1) 847 options->compression_level = 6; 848 if (options->port == -1) 849 options->port = 0; /* Filled in ssh_connect. */ 850 if (options->connection_attempts == -1) 851 options->connection_attempts = 4; 852 if (options->number_of_password_prompts == -1) 853 options->number_of_password_prompts = 3; 854 /* Selected in ssh_login(). */ 855 if (options->cipher == -1) 856 options->cipher = SSH_CIPHER_NOT_SET; 857 /* options->ciphers, default set in myproposals.h */ 858 /* options->macs, default set in myproposals.h */ 859 /* options->hostkeyalgorithms, default set in myproposals.h */ 860 if (options->protocol == SSH_PROTO_UNKNOWN) 861 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 862 if (options->num_identity_files == 0) { 863 if (options->protocol & SSH_PROTO_1) { 864 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 865 options->identity_files[options->num_identity_files] = 866 xmalloc(len); 867 snprintf(options->identity_files[options->num_identity_files++], 868 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 869 } 870 if (options->protocol & SSH_PROTO_2) { 871 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 872 options->identity_files[options->num_identity_files] = 873 xmalloc(len); 874 snprintf(options->identity_files[options->num_identity_files++], 875 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 876 877 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 878 options->identity_files[options->num_identity_files] = 879 xmalloc(len); 880 snprintf(options->identity_files[options->num_identity_files++], 881 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 882 } 883 } 884 if (options->escape_char == -1) 885 options->escape_char = '~'; 886 if (options->system_hostfile == NULL) 887 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 888 if (options->user_hostfile == NULL) 889 options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 890 if (options->system_hostfile2 == NULL) 891 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 892 if (options->user_hostfile2 == NULL) 893 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 894 if (options->log_level == (LogLevel) - 1) 895 options->log_level = SYSLOG_LEVEL_INFO; 896 /* options->proxy_command should not be set by default */ 897 /* options->user will be set in the main program if appropriate */ 898 /* options->hostname will be set in the main program if appropriate */ 899 /* options->host_key_alias should not be set by default */ 900 /* options->preferred_authentications will be set in ssh */ 901 } 902