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