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