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