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