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