1 /* 2 * 3 * readconf.c 4 * 5 * Author: Tatu Ylonen <ylo@cs.hut.fi> 6 * 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 8 * All rights reserved 9 * 10 * Created: Sat Apr 22 00:03:10 1995 ylo 11 * 12 * Functions for reading the configuration files. 13 * 14 * $FreeBSD$ 15 */ 16 17 #include "includes.h" 18 RCSID("$Id: readconf.c,v 1.23 2000/02/28 19:51:58 markus Exp $"); 19 20 #include "ssh.h" 21 #include "cipher.h" 22 #include "readconf.h" 23 #include "xmalloc.h" 24 25 /* Format of the configuration file: 26 27 # Configuration data is parsed as follows: 28 # 1. command line options 29 # 2. user-specific file 30 # 3. system-wide file 31 # Any configuration value is only changed the first time it is set. 32 # Thus, host-specific definitions should be at the beginning of the 33 # configuration file, and defaults at the end. 34 35 # Host-specific declarations. These may override anything above. A single 36 # host may match multiple declarations; these are processed in the order 37 # that they are given in. 38 39 Host *.ngs.fi ngs.fi 40 FallBackToRsh no 41 42 Host fake.com 43 HostName another.host.name.real.org 44 User blaah 45 Port 34289 46 ForwardX11 no 47 ForwardAgent no 48 49 Host books.com 50 RemoteForward 9999 shadows.cs.hut.fi:9999 51 Cipher 3des 52 53 Host fascist.blob.com 54 Port 23123 55 User tylonen 56 RhostsAuthentication no 57 PasswordAuthentication no 58 59 Host puukko.hut.fi 60 User t35124p 61 ProxyCommand ssh-proxy %h %p 62 63 Host *.fr 64 UseRsh yes 65 66 Host *.su 67 Cipher none 68 PasswordAuthentication no 69 70 # Defaults for various options 71 Host * 72 ForwardAgent no 73 ForwardX11 yes 74 RhostsAuthentication yes 75 PasswordAuthentication yes 76 RSAAuthentication yes 77 RhostsRSAAuthentication yes 78 FallBackToRsh no 79 UseRsh no 80 StrictHostKeyChecking yes 81 KeepAlives no 82 IdentityFile ~/.ssh/identity 83 Port 22 84 EscapeChar ~ 85 86 */ 87 88 /* Keyword tokens. */ 89 90 typedef enum { 91 oBadOption, 92 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 93 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 94 oSkeyAuthentication, 95 #ifdef KRB4 96 oKrb4Authentication, 97 #endif /* KRB4 */ 98 #ifdef KRB5 99 oKrb5Authentication, oKrb5TgtPassing, 100 #endif /* KRB5 */ 101 #ifdef AFS 102 oKrb4TgtPassing, oAFSTokenPassing, 103 #endif 104 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 105 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 106 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 107 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 108 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, 109 oUsePrivilegedPort, oLogLevel 110 } OpCodes; 111 112 /* Textual representations of the tokens. */ 113 114 static struct { 115 const char *name; 116 OpCodes opcode; 117 } keywords[] = { 118 { "forwardagent", oForwardAgent }, 119 { "forwardx11", oForwardX11 }, 120 { "gatewayports", oGatewayPorts }, 121 { "useprivilegedport", oUsePrivilegedPort }, 122 { "rhostsauthentication", oRhostsAuthentication }, 123 { "passwordauthentication", oPasswordAuthentication }, 124 { "rsaauthentication", oRSAAuthentication }, 125 { "skeyauthentication", oSkeyAuthentication }, 126 #ifdef KRB4 127 { "kerberos4authentication", oKrb4Authentication }, 128 #endif /* KRB4 */ 129 #ifdef KRB5 130 { "kerberos5authentication", oKrb5Authentication }, 131 { "kerberos5tgtpassing", oKrb5TgtPassing }, 132 #endif /* KRB5 */ 133 #ifdef AFS 134 { "kerberos4tgtpassing", oKrb4TgtPassing }, 135 { "afstokenpassing", oAFSTokenPassing }, 136 #endif 137 { "fallbacktorsh", oFallBackToRsh }, 138 { "usersh", oUseRsh }, 139 { "identityfile", oIdentityFile }, 140 { "hostname", oHostName }, 141 { "proxycommand", oProxyCommand }, 142 { "port", oPort }, 143 { "cipher", oCipher }, 144 { "remoteforward", oRemoteForward }, 145 { "localforward", oLocalForward }, 146 { "user", oUser }, 147 { "host", oHost }, 148 { "escapechar", oEscapeChar }, 149 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 150 { "globalknownhostsfile", oGlobalKnownHostsFile }, 151 { "userknownhostsfile", oUserKnownHostsFile }, 152 { "connectionattempts", oConnectionAttempts }, 153 { "batchmode", oBatchMode }, 154 { "checkhostip", oCheckHostIP }, 155 { "stricthostkeychecking", oStrictHostKeyChecking }, 156 { "compression", oCompression }, 157 { "compressionlevel", oCompressionLevel }, 158 { "keepalive", oKeepAlives }, 159 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 160 { "tisauthentication", oTISAuthentication }, 161 { "loglevel", oLogLevel }, 162 { NULL, 0 } 163 }; 164 165 /* Characters considered whitespace in strtok calls. */ 166 #define WHITESPACE " \t\r\n" 167 168 169 /* 170 * Adds a local TCP/IP port forward to options. Never returns if there is an 171 * error. 172 */ 173 174 void 175 add_local_forward(Options *options, u_short port, const char *host, 176 u_short host_port) 177 { 178 Forward *fwd; 179 extern uid_t original_real_uid; 180 if (port < IPPORT_RESERVED && original_real_uid != 0) 181 fatal("Privileged ports can only be forwarded by root.\n"); 182 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 183 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 184 fwd = &options->local_forwards[options->num_local_forwards++]; 185 fwd->port = port; 186 fwd->host = xstrdup(host); 187 fwd->host_port = host_port; 188 } 189 190 /* 191 * Adds a remote TCP/IP port forward to options. Never returns if there is 192 * an error. 193 */ 194 195 void 196 add_remote_forward(Options *options, u_short port, const char *host, 197 u_short host_port) 198 { 199 Forward *fwd; 200 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 201 fatal("Too many remote forwards (max %d).", 202 SSH_MAX_FORWARDS_PER_DIRECTION); 203 fwd = &options->remote_forwards[options->num_remote_forwards++]; 204 fwd->port = port; 205 fwd->host = xstrdup(host); 206 fwd->host_port = host_port; 207 } 208 209 /* 210 * Returns the number of the token pointed to by cp of length len. Never 211 * returns if the token is not known. 212 */ 213 214 static OpCodes 215 parse_token(const char *cp, const char *filename, int linenum) 216 { 217 unsigned int i; 218 219 for (i = 0; keywords[i].name; i++) 220 if (strcasecmp(cp, keywords[i].name) == 0) 221 return keywords[i].opcode; 222 223 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 224 filename, linenum, cp); 225 return oBadOption; 226 } 227 228 /* 229 * Processes a single option line as used in the configuration files. This 230 * only sets those values that have not already been set. 231 */ 232 233 int 234 process_config_line(Options *options, const char *host, 235 char *line, const char *filename, int linenum, 236 int *activep) 237 { 238 char buf[256], *cp, *string, **charptr, *cp2; 239 int opcode, *intptr, value; 240 u_short fwd_port, fwd_host_port; 241 242 /* Skip leading whitespace. */ 243 cp = line + strspn(line, WHITESPACE); 244 if (!*cp || *cp == '\n' || *cp == '#') 245 return 0; 246 247 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 248 cp = strtok(cp, WHITESPACE); 249 opcode = parse_token(cp, filename, linenum); 250 251 switch (opcode) { 252 case oBadOption: 253 /* don't panic, but count bad options */ 254 return -1; 255 /* NOTREACHED */ 256 case oForwardAgent: 257 intptr = &options->forward_agent; 258 parse_flag: 259 cp = strtok(NULL, WHITESPACE); 260 if (!cp) 261 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 262 value = 0; /* To avoid compiler warning... */ 263 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) 264 value = 1; 265 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) 266 value = 0; 267 else 268 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 269 if (*activep && *intptr == -1) 270 *intptr = value; 271 break; 272 273 case oForwardX11: 274 intptr = &options->forward_x11; 275 goto parse_flag; 276 277 case oGatewayPorts: 278 intptr = &options->gateway_ports; 279 goto parse_flag; 280 281 case oUsePrivilegedPort: 282 intptr = &options->use_privileged_port; 283 goto parse_flag; 284 285 case oRhostsAuthentication: 286 intptr = &options->rhosts_authentication; 287 goto parse_flag; 288 289 case oPasswordAuthentication: 290 intptr = &options->password_authentication; 291 goto parse_flag; 292 293 case oRSAAuthentication: 294 intptr = &options->rsa_authentication; 295 goto parse_flag; 296 297 case oRhostsRSAAuthentication: 298 intptr = &options->rhosts_rsa_authentication; 299 goto parse_flag; 300 301 case oTISAuthentication: 302 /* fallthrough, there is no difference on the client side */ 303 case oSkeyAuthentication: 304 intptr = &options->skey_authentication; 305 goto parse_flag; 306 307 #ifdef KRB4 308 case oKrb4Authentication: 309 intptr = &options->krb4_authentication; 310 goto parse_flag; 311 #endif /* KRB4 */ 312 313 #ifdef KRB5 314 case oKrb5Authentication: 315 intptr = &options->krb5_authentication; 316 goto parse_flag; 317 318 case oKrb5TgtPassing: 319 intptr = &options->krb5_tgt_passing; 320 goto parse_flag; 321 #endif /* KRB5 */ 322 323 #ifdef AFS 324 case oKrb4TgtPassing: 325 intptr = &options->krb4_tgt_passing; 326 goto parse_flag; 327 328 case oAFSTokenPassing: 329 intptr = &options->afs_token_passing; 330 goto parse_flag; 331 #endif 332 333 case oFallBackToRsh: 334 intptr = &options->fallback_to_rsh; 335 goto parse_flag; 336 337 case oUseRsh: 338 intptr = &options->use_rsh; 339 goto parse_flag; 340 341 case oBatchMode: 342 intptr = &options->batch_mode; 343 goto parse_flag; 344 345 case oCheckHostIP: 346 intptr = &options->check_host_ip; 347 goto parse_flag; 348 349 case oStrictHostKeyChecking: 350 intptr = &options->strict_host_key_checking; 351 cp = strtok(NULL, WHITESPACE); 352 if (!cp) 353 fatal("%.200s line %d: Missing yes/no argument.", 354 filename, linenum); 355 value = 0; /* To avoid compiler warning... */ 356 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) 357 value = 1; 358 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) 359 value = 0; 360 else if (strcmp(cp, "ask") == 0) 361 value = 2; 362 else 363 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 364 if (*activep && *intptr == -1) 365 *intptr = value; 366 break; 367 368 case oCompression: 369 intptr = &options->compression; 370 goto parse_flag; 371 372 case oKeepAlives: 373 intptr = &options->keepalives; 374 goto parse_flag; 375 376 case oNumberOfPasswordPrompts: 377 intptr = &options->number_of_password_prompts; 378 goto parse_int; 379 380 case oCompressionLevel: 381 intptr = &options->compression_level; 382 goto parse_int; 383 384 case oIdentityFile: 385 cp = strtok(NULL, WHITESPACE); 386 if (!cp) 387 fatal("%.200s line %d: Missing argument.", filename, linenum); 388 if (*activep) { 389 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 390 fatal("%.200s line %d: Too many identity files specified (max %d).", 391 filename, linenum, SSH_MAX_IDENTITY_FILES); 392 options->identity_files[options->num_identity_files++] = xstrdup(cp); 393 } 394 break; 395 396 case oUser: 397 charptr = &options->user; 398 parse_string: 399 cp = strtok(NULL, WHITESPACE); 400 if (!cp) 401 fatal("%.200s line %d: Missing argument.", filename, linenum); 402 if (*activep && *charptr == NULL) 403 *charptr = xstrdup(cp); 404 break; 405 406 case oGlobalKnownHostsFile: 407 charptr = &options->system_hostfile; 408 goto parse_string; 409 410 case oUserKnownHostsFile: 411 charptr = &options->user_hostfile; 412 goto parse_string; 413 414 case oHostName: 415 charptr = &options->hostname; 416 goto parse_string; 417 418 case oProxyCommand: 419 charptr = &options->proxy_command; 420 string = xstrdup(""); 421 while ((cp = strtok(NULL, WHITESPACE)) != NULL) { 422 string = xrealloc(string, strlen(string) + strlen(cp) + 2); 423 strcat(string, " "); 424 strcat(string, cp); 425 } 426 if (*activep && *charptr == NULL) 427 *charptr = string; 428 else 429 xfree(string); 430 return 0; 431 432 case oPort: 433 intptr = &options->port; 434 parse_int: 435 cp = strtok(NULL, WHITESPACE); 436 if (!cp) 437 fatal("%.200s line %d: Missing argument.", filename, linenum); 438 if (cp[0] < '0' || cp[0] > '9') 439 fatal("%.200s line %d: Bad number.", filename, linenum); 440 441 /* Octal, decimal, or hex format? */ 442 value = strtol(cp, &cp2, 0); 443 if (cp == cp2) 444 fatal("%.200s line %d: Bad number.", filename, linenum); 445 if (*activep && *intptr == -1) 446 *intptr = value; 447 break; 448 449 case oConnectionAttempts: 450 intptr = &options->connection_attempts; 451 goto parse_int; 452 453 case oCipher: 454 intptr = &options->cipher; 455 cp = strtok(NULL, WHITESPACE); 456 value = cipher_number(cp); 457 if (value == -1) 458 fatal("%.200s line %d: Bad cipher '%s'.", 459 filename, linenum, cp ? cp : "<NONE>"); 460 if (*activep && *intptr == -1) 461 *intptr = value; 462 break; 463 464 case oLogLevel: 465 intptr = (int *) &options->log_level; 466 cp = strtok(NULL, WHITESPACE); 467 value = log_level_number(cp); 468 if (value == (LogLevel) - 1) 469 fatal("%.200s line %d: unsupported log level '%s'\n", 470 filename, linenum, cp ? cp : "<NONE>"); 471 if (*activep && (LogLevel) * intptr == -1) 472 *intptr = (LogLevel) value; 473 break; 474 475 case oRemoteForward: 476 cp = strtok(NULL, WHITESPACE); 477 if (!cp) 478 fatal("%.200s line %d: Missing argument.", filename, linenum); 479 if (cp[0] < '0' || cp[0] > '9') 480 fatal("%.200s line %d: Badly formatted port number.", 481 filename, linenum); 482 fwd_port = atoi(cp); 483 cp = strtok(NULL, WHITESPACE); 484 if (!cp) 485 fatal("%.200s line %d: Missing second argument.", 486 filename, linenum); 487 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) 488 fatal("%.200s line %d: Badly formatted host:port.", 489 filename, linenum); 490 if (*activep) 491 add_remote_forward(options, fwd_port, buf, fwd_host_port); 492 break; 493 494 case oLocalForward: 495 cp = strtok(NULL, WHITESPACE); 496 if (!cp) 497 fatal("%.200s line %d: Missing argument.", filename, linenum); 498 if (cp[0] < '0' || cp[0] > '9') 499 fatal("%.200s line %d: Badly formatted port number.", 500 filename, linenum); 501 fwd_port = atoi(cp); 502 cp = strtok(NULL, WHITESPACE); 503 if (!cp) 504 fatal("%.200s line %d: Missing second argument.", 505 filename, linenum); 506 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) 507 fatal("%.200s line %d: Badly formatted host:port.", 508 filename, linenum); 509 if (*activep) 510 add_local_forward(options, fwd_port, buf, fwd_host_port); 511 break; 512 513 case oHost: 514 *activep = 0; 515 while ((cp = strtok(NULL, WHITESPACE)) != NULL) 516 if (match_pattern(host, cp)) { 517 debug("Applying options for %.100s", cp); 518 *activep = 1; 519 break; 520 } 521 /* Avoid garbage check below, as strtok already returned NULL. */ 522 return 0; 523 524 case oEscapeChar: 525 intptr = &options->escape_char; 526 cp = strtok(NULL, WHITESPACE); 527 if (!cp) 528 fatal("%.200s line %d: Missing argument.", filename, linenum); 529 if (cp[0] == '^' && cp[2] == 0 && 530 (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128) 531 value = (unsigned char) cp[1] & 31; 532 else if (strlen(cp) == 1) 533 value = (unsigned char) cp[0]; 534 else if (strcmp(cp, "none") == 0) 535 value = -2; 536 else { 537 fatal("%.200s line %d: Bad escape character.", 538 filename, linenum); 539 /* NOTREACHED */ 540 value = 0; /* Avoid compiler warning. */ 541 } 542 if (*activep && *intptr == -1) 543 *intptr = value; 544 break; 545 546 default: 547 fatal("process_config_line: Unimplemented opcode %d", opcode); 548 } 549 550 /* Check that there is no garbage at end of line. */ 551 if (strtok(NULL, WHITESPACE) != NULL) 552 fatal("%.200s line %d: garbage at end of line.", 553 filename, linenum); 554 return 0; 555 } 556 557 558 /* 559 * Reads the config file and modifies the options accordingly. Options 560 * should already be initialized before this call. This never returns if 561 * there is an error. If the file does not exist, this returns immediately. 562 */ 563 564 void 565 read_config_file(const char *filename, const char *host, Options *options) 566 { 567 FILE *f; 568 char line[1024]; 569 int active, linenum; 570 int bad_options = 0; 571 572 /* Open the file. */ 573 f = fopen(filename, "r"); 574 if (!f) 575 return; 576 577 debug("Reading configuration data %.200s", filename); 578 579 /* 580 * Mark that we are now processing the options. This flag is turned 581 * on/off by Host specifications. 582 */ 583 active = 1; 584 linenum = 0; 585 while (fgets(line, sizeof(line), f)) { 586 /* Update line number counter. */ 587 linenum++; 588 if (process_config_line(options, host, line, filename, linenum, &active) != 0) 589 bad_options++; 590 } 591 fclose(f); 592 if (bad_options > 0) 593 fatal("%s: terminating, %d bad configuration options\n", 594 filename, bad_options); 595 } 596 597 /* 598 * Initializes options to special values that indicate that they have not yet 599 * been set. Read_config_file will only set options with this value. Options 600 * are processed in the following order: command line, user config file, 601 * system config file. Last, fill_default_options is called. 602 */ 603 604 void 605 initialize_options(Options * options) 606 { 607 memset(options, 'X', sizeof(*options)); 608 options->forward_agent = -1; 609 options->forward_x11 = -1; 610 options->gateway_ports = -1; 611 options->use_privileged_port = -1; 612 options->rhosts_authentication = -1; 613 options->rsa_authentication = -1; 614 options->skey_authentication = -1; 615 #ifdef KRB4 616 options->krb4_authentication = -1; 617 #endif 618 #ifdef KRB5 619 options->krb5_authentication = -1; 620 options->krb5_tgt_passing = -1; 621 #endif /* KRB5 */ 622 #ifdef AFS 623 options->krb4_tgt_passing = -1; 624 options->afs_token_passing = -1; 625 #endif 626 options->password_authentication = -1; 627 options->rhosts_rsa_authentication = -1; 628 options->fallback_to_rsh = -1; 629 options->use_rsh = -1; 630 options->batch_mode = -1; 631 options->check_host_ip = -1; 632 options->strict_host_key_checking = -1; 633 options->compression = -1; 634 options->keepalives = -1; 635 options->compression_level = -1; 636 options->port = -1; 637 options->connection_attempts = -1; 638 options->number_of_password_prompts = -1; 639 options->cipher = -1; 640 options->num_identity_files = 0; 641 options->hostname = NULL; 642 options->proxy_command = NULL; 643 options->user = NULL; 644 options->escape_char = -1; 645 options->system_hostfile = NULL; 646 options->user_hostfile = NULL; 647 options->num_local_forwards = 0; 648 options->num_remote_forwards = 0; 649 options->log_level = (LogLevel) - 1; 650 } 651 652 /* 653 * Called after processing other sources of option data, this fills those 654 * options for which no value has been specified with their default values. 655 */ 656 657 void 658 fill_default_options(Options * options) 659 { 660 if (options->forward_agent == -1) 661 options->forward_agent = 1; 662 if (options->forward_x11 == -1) 663 options->forward_x11 = 0; 664 if (options->gateway_ports == -1) 665 options->gateway_ports = 0; 666 if (options->use_privileged_port == -1) 667 options->use_privileged_port = 1; 668 if (options->rhosts_authentication == -1) 669 options->rhosts_authentication = 1; 670 if (options->rsa_authentication == -1) 671 options->rsa_authentication = 1; 672 if (options->skey_authentication == -1) 673 options->skey_authentication = 0; 674 #ifdef KRB4 675 if (options->krb4_authentication == -1) 676 options->krb4_authentication = 1; 677 #endif /* KRB4 */ 678 #ifdef KRB5 679 if (options->krb5_authentication == -1) 680 options->krb5_authentication = 1; 681 if (options->krb5_tgt_passing == -1) 682 options->krb5_tgt_passing = 1; 683 #endif /* KRB5 */ 684 #ifdef AFS 685 if (options->krb4_tgt_passing == -1) 686 options->krb4_tgt_passing = 1; 687 if (options->afs_token_passing == -1) 688 options->afs_token_passing = 1; 689 #endif /* AFS */ 690 if (options->password_authentication == -1) 691 options->password_authentication = 1; 692 if (options->rhosts_rsa_authentication == -1) 693 options->rhosts_rsa_authentication = 1; 694 if (options->fallback_to_rsh == -1) 695 options->fallback_to_rsh = 1; 696 if (options->use_rsh == -1) 697 options->use_rsh = 0; 698 if (options->batch_mode == -1) 699 options->batch_mode = 0; 700 if (options->check_host_ip == -1) 701 options->check_host_ip = 0; 702 if (options->strict_host_key_checking == -1) 703 options->strict_host_key_checking = 2; /* 2 is default */ 704 if (options->compression == -1) 705 options->compression = 0; 706 if (options->keepalives == -1) 707 options->keepalives = 1; 708 if (options->compression_level == -1) 709 options->compression_level = 6; 710 if (options->port == -1) 711 options->port = 0; /* Filled in ssh_connect. */ 712 if (options->connection_attempts == -1) 713 options->connection_attempts = 4; 714 if (options->number_of_password_prompts == -1) 715 options->number_of_password_prompts = 3; 716 /* Selected in ssh_login(). */ 717 if (options->cipher == -1) 718 options->cipher = SSH_CIPHER_NOT_SET; 719 if (options->num_identity_files == 0) { 720 options->identity_files[0] = 721 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); 722 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); 723 options->num_identity_files = 1; 724 } 725 if (options->escape_char == -1) 726 options->escape_char = '~'; 727 if (options->system_hostfile == NULL) 728 options->system_hostfile = SSH_SYSTEM_HOSTFILE; 729 if (options->user_hostfile == NULL) 730 options->user_hostfile = SSH_USER_HOSTFILE; 731 if (options->log_level == (LogLevel) - 1) 732 options->log_level = SYSLOG_LEVEL_INFO; 733 /* options->proxy_command should not be set by default */ 734 /* options->user will be set in the main program if appropriate */ 735 /* options->hostname will be set in the main program if appropriate */ 736 } 737