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