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