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.139 2005/03/10 22:01:05 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 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 = ""; 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 intptr = &options->address_family; 750 if (strcasecmp(arg, "inet") == 0) 751 value = AF_INET; 752 else if (strcasecmp(arg, "inet6") == 0) 753 value = AF_INET6; 754 else if (strcasecmp(arg, "any") == 0) 755 value = AF_UNSPEC; 756 else 757 fatal("Unsupported AddressFamily \"%s\"", arg); 758 if (*activep && *intptr == -1) 759 *intptr = value; 760 break; 761 762 case oEnableSSHKeysign: 763 intptr = &options->enable_ssh_keysign; 764 goto parse_flag; 765 766 case oIdentitiesOnly: 767 intptr = &options->identities_only; 768 goto parse_flag; 769 770 case oServerAliveInterval: 771 intptr = &options->server_alive_interval; 772 goto parse_time; 773 774 case oServerAliveCountMax: 775 intptr = &options->server_alive_count_max; 776 goto parse_int; 777 778 case oSendEnv: 779 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 780 if (strchr(arg, '=') != NULL) 781 fatal("%s line %d: Invalid environment name.", 782 filename, linenum); 783 if (!*activep) 784 continue; 785 if (options->num_send_env >= MAX_SEND_ENV) 786 fatal("%s line %d: too many send env.", 787 filename, linenum); 788 options->send_env[options->num_send_env++] = 789 xstrdup(arg); 790 } 791 break; 792 793 case oControlPath: 794 charptr = &options->control_path; 795 goto parse_string; 796 797 case oControlMaster: 798 intptr = &options->control_master; 799 goto parse_yesnoask; 800 801 case oHashKnownHosts: 802 intptr = &options->hash_known_hosts; 803 goto parse_flag; 804 805 case oVersionAddendum: 806 ssh_version_set_addendum(strtok(s, "\n")); 807 do { 808 arg = strdelim(&s); 809 } while (arg != NULL && *arg != '\0'); 810 break; 811 812 case oDeprecated: 813 debug("%s line %d: Deprecated option \"%s\"", 814 filename, linenum, keyword); 815 return 0; 816 817 case oUnsupported: 818 error("%s line %d: Unsupported option \"%s\"", 819 filename, linenum, keyword); 820 return 0; 821 822 default: 823 fatal("process_config_line: Unimplemented opcode %d", opcode); 824 } 825 826 /* Check that there is no garbage at end of line. */ 827 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 828 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 829 filename, linenum, arg); 830 } 831 return 0; 832 } 833 834 835 /* 836 * Reads the config file and modifies the options accordingly. Options 837 * should already be initialized before this call. This never returns if 838 * there is an error. If the file does not exist, this returns 0. 839 */ 840 841 int 842 read_config_file(const char *filename, const char *host, Options *options, 843 int checkperm) 844 { 845 FILE *f; 846 char line[1024]; 847 int active, linenum; 848 int bad_options = 0; 849 850 /* Open the file. */ 851 if ((f = fopen(filename, "r")) == NULL) 852 return 0; 853 854 if (checkperm) { 855 struct stat sb; 856 857 if (fstat(fileno(f), &sb) == -1) 858 fatal("fstat %s: %s", filename, strerror(errno)); 859 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 860 (sb.st_mode & 022) != 0)) 861 fatal("Bad owner or permissions on %s", filename); 862 } 863 864 debug("Reading configuration data %.200s", filename); 865 866 /* 867 * Mark that we are now processing the options. This flag is turned 868 * on/off by Host specifications. 869 */ 870 active = 1; 871 linenum = 0; 872 while (fgets(line, sizeof(line), f)) { 873 /* Update line number counter. */ 874 linenum++; 875 if (process_config_line(options, host, line, filename, linenum, &active) != 0) 876 bad_options++; 877 } 878 fclose(f); 879 if (bad_options > 0) 880 fatal("%s: terminating, %d bad configuration options", 881 filename, bad_options); 882 return 1; 883 } 884 885 /* 886 * Initializes options to special values that indicate that they have not yet 887 * been set. Read_config_file will only set options with this value. Options 888 * are processed in the following order: command line, user config file, 889 * system config file. Last, fill_default_options is called. 890 */ 891 892 void 893 initialize_options(Options * options) 894 { 895 memset(options, 'X', sizeof(*options)); 896 options->forward_agent = -1; 897 options->forward_x11 = -1; 898 options->forward_x11_trusted = -1; 899 options->xauth_location = NULL; 900 options->gateway_ports = -1; 901 options->use_privileged_port = -1; 902 options->rsa_authentication = -1; 903 options->pubkey_authentication = -1; 904 options->challenge_response_authentication = -1; 905 options->gss_authentication = -1; 906 options->gss_deleg_creds = -1; 907 options->password_authentication = -1; 908 options->kbd_interactive_authentication = -1; 909 options->kbd_interactive_devices = NULL; 910 options->rhosts_rsa_authentication = -1; 911 options->hostbased_authentication = -1; 912 options->batch_mode = -1; 913 options->check_host_ip = -1; 914 options->strict_host_key_checking = -1; 915 options->compression = -1; 916 options->tcp_keep_alive = -1; 917 options->compression_level = -1; 918 options->port = -1; 919 options->address_family = -1; 920 options->connection_attempts = -1; 921 options->connection_timeout = -1; 922 options->number_of_password_prompts = -1; 923 options->cipher = -1; 924 options->ciphers = NULL; 925 options->macs = NULL; 926 options->hostkeyalgorithms = NULL; 927 options->protocol = SSH_PROTO_UNKNOWN; 928 options->num_identity_files = 0; 929 options->hostname = NULL; 930 options->host_key_alias = NULL; 931 options->proxy_command = NULL; 932 options->user = NULL; 933 options->escape_char = -1; 934 options->system_hostfile = NULL; 935 options->user_hostfile = NULL; 936 options->system_hostfile2 = NULL; 937 options->user_hostfile2 = NULL; 938 options->num_local_forwards = 0; 939 options->num_remote_forwards = 0; 940 options->clear_forwardings = -1; 941 options->log_level = SYSLOG_LEVEL_NOT_SET; 942 options->preferred_authentications = NULL; 943 options->bind_address = NULL; 944 options->smartcard_device = NULL; 945 options->enable_ssh_keysign = - 1; 946 options->no_host_authentication_for_localhost = - 1; 947 options->identities_only = - 1; 948 options->rekey_limit = - 1; 949 options->verify_host_key_dns = -1; 950 options->server_alive_interval = -1; 951 options->server_alive_count_max = -1; 952 options->num_send_env = 0; 953 options->control_path = NULL; 954 options->control_master = -1; 955 options->hash_known_hosts = -1; 956 } 957 958 /* 959 * Called after processing other sources of option data, this fills those 960 * options for which no value has been specified with their default values. 961 */ 962 963 void 964 fill_default_options(Options * options) 965 { 966 int len; 967 968 if (options->forward_agent == -1) 969 options->forward_agent = 0; 970 if (options->forward_x11 == -1) 971 options->forward_x11 = 0; 972 if (options->forward_x11_trusted == -1) 973 options->forward_x11_trusted = 0; 974 if (options->xauth_location == NULL) 975 options->xauth_location = _PATH_XAUTH; 976 if (options->gateway_ports == -1) 977 options->gateway_ports = 0; 978 if (options->use_privileged_port == -1) 979 options->use_privileged_port = 0; 980 if (options->rsa_authentication == -1) 981 options->rsa_authentication = 1; 982 if (options->pubkey_authentication == -1) 983 options->pubkey_authentication = 1; 984 if (options->challenge_response_authentication == -1) 985 options->challenge_response_authentication = 1; 986 if (options->gss_authentication == -1) 987 options->gss_authentication = 0; 988 if (options->gss_deleg_creds == -1) 989 options->gss_deleg_creds = 0; 990 if (options->password_authentication == -1) 991 options->password_authentication = 1; 992 if (options->kbd_interactive_authentication == -1) 993 options->kbd_interactive_authentication = 1; 994 if (options->rhosts_rsa_authentication == -1) 995 options->rhosts_rsa_authentication = 0; 996 if (options->hostbased_authentication == -1) 997 options->hostbased_authentication = 0; 998 if (options->batch_mode == -1) 999 options->batch_mode = 0; 1000 if (options->check_host_ip == -1) 1001 options->check_host_ip = 0; 1002 if (options->strict_host_key_checking == -1) 1003 options->strict_host_key_checking = 2; /* 2 is default */ 1004 if (options->compression == -1) 1005 options->compression = 0; 1006 if (options->tcp_keep_alive == -1) 1007 options->tcp_keep_alive = 1; 1008 if (options->compression_level == -1) 1009 options->compression_level = 6; 1010 if (options->port == -1) 1011 options->port = 0; /* Filled in ssh_connect. */ 1012 if (options->address_family == -1) 1013 options->address_family = AF_UNSPEC; 1014 if (options->connection_attempts == -1) 1015 options->connection_attempts = 1; 1016 if (options->number_of_password_prompts == -1) 1017 options->number_of_password_prompts = 3; 1018 /* Selected in ssh_login(). */ 1019 if (options->cipher == -1) 1020 options->cipher = SSH_CIPHER_NOT_SET; 1021 /* options->ciphers, default set in myproposals.h */ 1022 /* options->macs, default set in myproposals.h */ 1023 /* options->hostkeyalgorithms, default set in myproposals.h */ 1024 if (options->protocol == SSH_PROTO_UNKNOWN) 1025 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 1026 if (options->num_identity_files == 0) { 1027 if (options->protocol & SSH_PROTO_1) { 1028 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 1029 options->identity_files[options->num_identity_files] = 1030 xmalloc(len); 1031 snprintf(options->identity_files[options->num_identity_files++], 1032 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 1033 } 1034 if (options->protocol & SSH_PROTO_2) { 1035 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 1036 options->identity_files[options->num_identity_files] = 1037 xmalloc(len); 1038 snprintf(options->identity_files[options->num_identity_files++], 1039 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 1040 1041 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 1042 options->identity_files[options->num_identity_files] = 1043 xmalloc(len); 1044 snprintf(options->identity_files[options->num_identity_files++], 1045 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 1046 } 1047 } 1048 if (options->escape_char == -1) 1049 options->escape_char = '~'; 1050 if (options->system_hostfile == NULL) 1051 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 1052 if (options->user_hostfile == NULL) 1053 options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 1054 if (options->system_hostfile2 == NULL) 1055 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 1056 if (options->user_hostfile2 == NULL) 1057 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 1058 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1059 options->log_level = SYSLOG_LEVEL_INFO; 1060 if (options->clear_forwardings == 1) 1061 clear_forwardings(options); 1062 if (options->no_host_authentication_for_localhost == - 1) 1063 options->no_host_authentication_for_localhost = 0; 1064 if (options->identities_only == -1) 1065 options->identities_only = 0; 1066 if (options->enable_ssh_keysign == -1) 1067 options->enable_ssh_keysign = 0; 1068 if (options->rekey_limit == -1) 1069 options->rekey_limit = 0; 1070 if (options->verify_host_key_dns == -1) 1071 options->verify_host_key_dns = 0; 1072 if (options->server_alive_interval == -1) 1073 options->server_alive_interval = 0; 1074 if (options->server_alive_count_max == -1) 1075 options->server_alive_count_max = 3; 1076 if (options->control_master == -1) 1077 options->control_master = 0; 1078 if (options->hash_known_hosts == -1) 1079 options->hash_known_hosts = 0; 1080 /* options->proxy_command should not be set by default */ 1081 /* options->user will be set in the main program if appropriate */ 1082 /* options->hostname will be set in the main program if appropriate */ 1083 /* options->host_key_alias should not be set by default */ 1084 /* options->preferred_authentications will be set in ssh */ 1085 } 1086 1087 /* 1088 * parse_forward 1089 * parses a string containing a port forwarding specification of the form: 1090 * [listenhost:]listenport:connecthost:connectport 1091 * returns number of arguments parsed or zero on error 1092 */ 1093 int 1094 parse_forward(Forward *fwd, const char *fwdspec) 1095 { 1096 int i; 1097 char *p, *cp, *fwdarg[4]; 1098 1099 memset(fwd, '\0', sizeof(*fwd)); 1100 1101 cp = p = xstrdup(fwdspec); 1102 1103 /* skip leading spaces */ 1104 while (*cp && isspace(*cp)) 1105 cp++; 1106 1107 for (i = 0; i < 4; ++i) 1108 if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1109 break; 1110 1111 /* Check for trailing garbage in 4-arg case*/ 1112 if (cp != NULL) 1113 i = 0; /* failure */ 1114 1115 switch (i) { 1116 case 3: 1117 fwd->listen_host = NULL; 1118 fwd->listen_port = a2port(fwdarg[0]); 1119 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1120 fwd->connect_port = a2port(fwdarg[2]); 1121 break; 1122 1123 case 4: 1124 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1125 fwd->listen_port = a2port(fwdarg[1]); 1126 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1127 fwd->connect_port = a2port(fwdarg[3]); 1128 break; 1129 default: 1130 i = 0; /* failure */ 1131 } 1132 1133 xfree(p); 1134 1135 if (fwd->listen_port == 0 && fwd->connect_port == 0) 1136 goto fail_free; 1137 1138 if (fwd->connect_host != NULL && 1139 strlen(fwd->connect_host) >= NI_MAXHOST) 1140 goto fail_free; 1141 1142 return (i); 1143 1144 fail_free: 1145 if (fwd->connect_host != NULL) 1146 xfree(fwd->connect_host); 1147 if (fwd->listen_host != NULL) 1148 xfree(fwd->listen_host); 1149 return (0); 1150 } 1151