2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * Functions for reading the configuration files.
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".
15 RCSID("$OpenBSD: readconf.c,v 1.76 2001/04/17 10:53:25 markus Exp $");
21 #include "pathnames.h"
29 /* Format of the configuration file:
31 # Configuration data is parsed as follows:
32 # 1. command line options
33 # 2. user-specific file
35 # Any configuration value is only changed the first time it is set.
36 # Thus, host-specific definitions should be at the beginning of the
37 # configuration file, and defaults at the end.
39 # Host-specific declarations. These may override anything above. A single
40 # host may match multiple declarations; these are processed in the order
41 # that they are given in.
47 HostName another.host.name.real.org
54 RemoteForward 9999 shadows.cs.hut.fi:9999
60 RhostsAuthentication no
61 PasswordAuthentication no
65 ProxyCommand ssh-proxy %h %p
72 PasswordAuthentication no
74 # Defaults for various options
78 RhostsAuthentication yes
79 PasswordAuthentication yes
81 RhostsRSAAuthentication yes
84 StrictHostKeyChecking yes
86 IdentityFile ~/.ssh/identity
96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98 oChallengeResponseAuthentication, oXAuthLocation,
100 oKerberosAuthentication,
103 oKerberosTgtPassing, oAFSTokenPassing,
105 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
106 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
107 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
108 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
109 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
117 /* Textual representations of the tokens. */
123 { "forwardagent", oForwardAgent },
124 { "forwardx11", oForwardX11 },
125 { "xauthlocation", oXAuthLocation },
126 { "gatewayports", oGatewayPorts },
127 { "useprivilegedport", oUsePrivilegedPort },
128 { "rhostsauthentication", oRhostsAuthentication },
129 { "passwordauthentication", oPasswordAuthentication },
130 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
131 { "kbdinteractivedevices", oKbdInteractiveDevices },
132 { "rsaauthentication", oRSAAuthentication },
133 { "pubkeyauthentication", oPubkeyAuthentication },
134 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
135 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
136 { "hostbasedauthentication", oHostbasedAuthentication },
137 { "challengeresponseauthentication", oChallengeResponseAuthentication },
138 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
139 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
141 { "kerberosauthentication", oKerberosAuthentication },
144 { "kerberostgtpassing", oKerberosTgtPassing },
145 { "afstokenpassing", oAFSTokenPassing },
147 { "fallbacktorsh", oFallBackToRsh },
148 { "usersh", oUseRsh },
149 { "identityfile", oIdentityFile },
150 { "identityfile2", oIdentityFile }, /* alias */
151 { "hostname", oHostName },
152 { "hostkeyalias", oHostKeyAlias },
153 { "proxycommand", oProxyCommand },
155 { "cipher", oCipher },
156 { "ciphers", oCiphers },
158 { "protocol", oProtocol },
159 { "remoteforward", oRemoteForward },
160 { "localforward", oLocalForward },
163 { "escapechar", oEscapeChar },
164 { "globalknownhostsfile", oGlobalKnownHostsFile },
165 { "userknownhostsfile", oUserKnownHostsFile },
166 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
167 { "userknownhostsfile2", oUserKnownHostsFile2 },
168 { "connectionattempts", oConnectionAttempts },
169 { "batchmode", oBatchMode },
170 { "checkhostip", oCheckHostIP },
171 { "stricthostkeychecking", oStrictHostKeyChecking },
172 { "compression", oCompression },
173 { "compressionlevel", oCompressionLevel },
174 { "keepalive", oKeepAlives },
175 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
176 { "loglevel", oLogLevel },
177 { "dynamicforward", oDynamicForward },
178 { "preferredauthentications", oPreferredAuthentications },
179 { "hostkeyalgorithms", oHostKeyAlgorithms },
184 * Adds a local TCP/IP port forward to options. Never returns if there is an
189 add_local_forward(Options *options, u_short port, const char *host,
194 extern uid_t original_real_uid;
195 if (port < IPPORT_RESERVED && original_real_uid != 0)
196 fatal("Privileged ports can only be forwarded by root.");
198 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
199 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
200 fwd = &options->local_forwards[options->num_local_forwards++];
202 fwd->host = xstrdup(host);
203 fwd->host_port = host_port;
207 * Adds a remote TCP/IP port forward to options. Never returns if there is
212 add_remote_forward(Options *options, u_short port, const char *host,
216 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
217 fatal("Too many remote forwards (max %d).",
218 SSH_MAX_FORWARDS_PER_DIRECTION);
219 fwd = &options->remote_forwards[options->num_remote_forwards++];
221 fwd->host = xstrdup(host);
222 fwd->host_port = host_port;
226 * Returns the number of the token pointed to by cp or oBadOption.
230 parse_token(const char *cp, const char *filename, int linenum)
234 for (i = 0; keywords[i].name; i++)
235 if (strcasecmp(cp, keywords[i].name) == 0)
236 return keywords[i].opcode;
238 error("%s: line %d: Bad configuration option: %s",
239 filename, linenum, cp);
244 * Processes a single option line as used in the configuration files. This
245 * only sets those values that have not already been set.
249 process_config_line(Options *options, const char *host,
250 char *line, const char *filename, int linenum,
253 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
254 int opcode, *intptr, value;
255 u_short fwd_port, fwd_host_port;
258 /* Get the keyword. (Each line is supposed to begin with a keyword). */
259 keyword = strdelim(&s);
260 /* Ignore leading whitespace. */
261 if (*keyword == '\0')
262 keyword = strdelim(&s);
263 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
266 opcode = parse_token(keyword, filename, linenum);
270 /* don't panic, but count bad options */
274 intptr = &options->forward_agent;
277 if (!arg || *arg == '\0')
278 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
279 value = 0; /* To avoid compiler warning... */
280 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
282 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
285 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
286 if (*activep && *intptr == -1)
291 intptr = &options->forward_x11;
295 intptr = &options->gateway_ports;
298 case oUsePrivilegedPort:
299 intptr = &options->use_privileged_port;
302 case oRhostsAuthentication:
303 intptr = &options->rhosts_authentication;
306 case oPasswordAuthentication:
307 intptr = &options->password_authentication;
310 case oKbdInteractiveAuthentication:
311 intptr = &options->kbd_interactive_authentication;
314 case oKbdInteractiveDevices:
315 charptr = &options->kbd_interactive_devices;
318 case oPubkeyAuthentication:
319 intptr = &options->pubkey_authentication;
322 case oRSAAuthentication:
323 intptr = &options->rsa_authentication;
326 case oRhostsRSAAuthentication:
327 intptr = &options->rhosts_rsa_authentication;
330 case oHostbasedAuthentication:
331 intptr = &options->hostbased_authentication;
334 case oChallengeResponseAuthentication:
335 intptr = &options->challenge_reponse_authentication;
339 case oKerberosAuthentication:
340 intptr = &options->kerberos_authentication;
345 case oKerberosTgtPassing:
346 intptr = &options->kerberos_tgt_passing;
349 case oAFSTokenPassing:
350 intptr = &options->afs_token_passing;
355 intptr = &options->fallback_to_rsh;
359 intptr = &options->use_rsh;
363 intptr = &options->batch_mode;
367 intptr = &options->check_host_ip;
370 case oStrictHostKeyChecking:
371 intptr = &options->strict_host_key_checking;
373 if (!arg || *arg == '\0')
374 fatal("%.200s line %d: Missing yes/no/ask argument.",
376 value = 0; /* To avoid compiler warning... */
377 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
379 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
381 else if (strcmp(arg, "ask") == 0)
384 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
385 if (*activep && *intptr == -1)
390 intptr = &options->compression;
394 intptr = &options->keepalives;
397 case oNumberOfPasswordPrompts:
398 intptr = &options->number_of_password_prompts;
401 case oCompressionLevel:
402 intptr = &options->compression_level;
407 if (!arg || *arg == '\0')
408 fatal("%.200s line %d: Missing argument.", filename, linenum);
410 intptr = &options->num_identity_files;
411 if (*intptr >= SSH_MAX_IDENTITY_FILES)
412 fatal("%.200s line %d: Too many identity files specified (max %d).",
413 filename, linenum, SSH_MAX_IDENTITY_FILES);
414 charptr = &options->identity_files[*intptr];
415 *charptr = xstrdup(arg);
416 *intptr = *intptr + 1;
421 charptr=&options->xauth_location;
425 charptr = &options->user;
428 if (!arg || *arg == '\0')
429 fatal("%.200s line %d: Missing argument.", filename, linenum);
430 if (*activep && *charptr == NULL)
431 *charptr = xstrdup(arg);
434 case oGlobalKnownHostsFile:
435 charptr = &options->system_hostfile;
438 case oUserKnownHostsFile:
439 charptr = &options->user_hostfile;
442 case oGlobalKnownHostsFile2:
443 charptr = &options->system_hostfile2;
446 case oUserKnownHostsFile2:
447 charptr = &options->user_hostfile2;
451 charptr = &options->hostname;
455 charptr = &options->host_key_alias;
458 case oPreferredAuthentications:
459 charptr = &options->preferred_authentications;
463 charptr = &options->proxy_command;
464 string = xstrdup("");
465 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
466 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
470 if (*activep && *charptr == NULL)
477 intptr = &options->port;
480 if (!arg || *arg == '\0')
481 fatal("%.200s line %d: Missing argument.", filename, linenum);
482 if (arg[0] < '0' || arg[0] > '9')
483 fatal("%.200s line %d: Bad number.", filename, linenum);
485 /* Octal, decimal, or hex format? */
486 value = strtol(arg, &endofnumber, 0);
487 if (arg == endofnumber)
488 fatal("%.200s line %d: Bad number.", filename, linenum);
489 if (*activep && *intptr == -1)
493 case oConnectionAttempts:
494 intptr = &options->connection_attempts;
498 intptr = &options->cipher;
500 if (!arg || *arg == '\0')
501 fatal("%.200s line %d: Missing argument.", filename, linenum);
502 value = cipher_number(arg);
504 fatal("%.200s line %d: Bad cipher '%s'.",
505 filename, linenum, arg ? arg : "<NONE>");
506 if (*activep && *intptr == -1)
512 if (!arg || *arg == '\0')
513 fatal("%.200s line %d: Missing argument.", filename, linenum);
514 if (!ciphers_valid(arg))
515 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
516 filename, linenum, arg ? arg : "<NONE>");
517 if (*activep && options->ciphers == NULL)
518 options->ciphers = xstrdup(arg);
523 if (!arg || *arg == '\0')
524 fatal("%.200s line %d: Missing argument.", filename, linenum);
526 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
527 filename, linenum, arg ? arg : "<NONE>");
528 if (*activep && options->macs == NULL)
529 options->macs = xstrdup(arg);
532 case oHostKeyAlgorithms:
534 if (!arg || *arg == '\0')
535 fatal("%.200s line %d: Missing argument.", filename, linenum);
536 if (!key_names_valid2(arg))
537 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
538 filename, linenum, arg ? arg : "<NONE>");
539 if (*activep && options->hostkeyalgorithms == NULL)
540 options->hostkeyalgorithms = xstrdup(arg);
544 intptr = &options->protocol;
546 if (!arg || *arg == '\0')
547 fatal("%.200s line %d: Missing argument.", filename, linenum);
548 value = proto_spec(arg);
549 if (value == SSH_PROTO_UNKNOWN)
550 fatal("%.200s line %d: Bad protocol spec '%s'.",
551 filename, linenum, arg ? arg : "<NONE>");
552 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
557 intptr = (int *) &options->log_level;
559 value = log_level_number(arg);
560 if (value == (LogLevel) - 1)
561 fatal("%.200s line %d: unsupported log level '%s'",
562 filename, linenum, arg ? arg : "<NONE>");
563 if (*activep && (LogLevel) * intptr == -1)
564 *intptr = (LogLevel) value;
569 if (!arg || *arg == '\0')
570 fatal("%.200s line %d: Missing argument.", filename, linenum);
571 fwd_port = a2port(arg);
573 fatal("%.200s line %d: Badly formatted port number.",
576 if (!arg || *arg == '\0')
577 fatal("%.200s line %d: Missing second argument.",
579 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
580 fatal("%.200s line %d: Badly formatted host:port.",
583 add_remote_forward(options, fwd_port, buf, fwd_host_port);
588 if (!arg || *arg == '\0')
589 fatal("%.200s line %d: Missing argument.", filename, linenum);
590 fwd_port = a2port(arg);
592 fatal("%.200s line %d: Badly formatted port number.",
595 if (!arg || *arg == '\0')
596 fatal("%.200s line %d: Missing second argument.",
598 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
599 fatal("%.200s line %d: Badly formatted host:port.",
602 add_local_forward(options, fwd_port, buf, fwd_host_port);
605 case oDynamicForward:
607 if (!arg || *arg == '\0')
608 fatal("%.200s line %d: Missing port argument.",
610 fwd_port = a2port(arg);
612 fatal("%.200s line %d: Badly formatted port number.",
614 add_local_forward(options, fwd_port, "socks4", 0);
619 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
620 if (match_pattern(host, arg)) {
621 debug("Applying options for %.100s", arg);
625 /* Avoid garbage check below, as strdelim is done. */
629 intptr = &options->escape_char;
631 if (!arg || *arg == '\0')
632 fatal("%.200s line %d: Missing argument.", filename, linenum);
633 if (arg[0] == '^' && arg[2] == 0 &&
634 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
635 value = (u_char) arg[1] & 31;
636 else if (strlen(arg) == 1)
637 value = (u_char) arg[0];
638 else if (strcmp(arg, "none") == 0)
641 fatal("%.200s line %d: Bad escape character.",
644 value = 0; /* Avoid compiler warning. */
646 if (*activep && *intptr == -1)
651 fatal("process_config_line: Unimplemented opcode %d", opcode);
654 /* Check that there is no garbage at end of line. */
655 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
656 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
657 filename, linenum, arg);
664 * Reads the config file and modifies the options accordingly. Options
665 * should already be initialized before this call. This never returns if
666 * there is an error. If the file does not exist, this returns immediately.
670 read_config_file(const char *filename, const char *host, Options *options)
678 f = fopen(filename, "r");
682 debug("Reading configuration data %.200s", filename);
685 * Mark that we are now processing the options. This flag is turned
686 * on/off by Host specifications.
690 while (fgets(line, sizeof(line), f)) {
691 /* Update line number counter. */
693 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
698 fatal("%s: terminating, %d bad configuration options",
699 filename, bad_options);
703 * Initializes options to special values that indicate that they have not yet
704 * been set. Read_config_file will only set options with this value. Options
705 * are processed in the following order: command line, user config file,
706 * system config file. Last, fill_default_options is called.
710 initialize_options(Options * options)
712 memset(options, 'X', sizeof(*options));
713 options->forward_agent = -1;
714 options->forward_x11 = -1;
715 options->xauth_location = NULL;
716 options->gateway_ports = -1;
717 options->use_privileged_port = -1;
718 options->rhosts_authentication = -1;
719 options->rsa_authentication = -1;
720 options->pubkey_authentication = -1;
721 options->challenge_reponse_authentication = -1;
723 options->kerberos_authentication = -1;
726 options->kerberos_tgt_passing = -1;
727 options->afs_token_passing = -1;
729 options->password_authentication = -1;
730 options->kbd_interactive_authentication = -1;
731 options->kbd_interactive_devices = NULL;
732 options->rhosts_rsa_authentication = -1;
733 options->hostbased_authentication = -1;
734 options->fallback_to_rsh = -1;
735 options->use_rsh = -1;
736 options->batch_mode = -1;
737 options->check_host_ip = -1;
738 options->strict_host_key_checking = -1;
739 options->compression = -1;
740 options->keepalives = -1;
741 options->compression_level = -1;
743 options->connection_attempts = -1;
744 options->number_of_password_prompts = -1;
745 options->cipher = -1;
746 options->ciphers = NULL;
747 options->macs = NULL;
748 options->hostkeyalgorithms = NULL;
749 options->protocol = SSH_PROTO_UNKNOWN;
750 options->num_identity_files = 0;
751 options->hostname = NULL;
752 options->host_key_alias = NULL;
753 options->proxy_command = NULL;
754 options->user = NULL;
755 options->escape_char = -1;
756 options->system_hostfile = NULL;
757 options->user_hostfile = NULL;
758 options->system_hostfile2 = NULL;
759 options->user_hostfile2 = NULL;
760 options->num_local_forwards = 0;
761 options->num_remote_forwards = 0;
762 options->log_level = (LogLevel) - 1;
763 options->preferred_authentications = NULL;
767 * Called after processing other sources of option data, this fills those
768 * options for which no value has been specified with their default values.
772 fill_default_options(Options * options)
776 if (options->forward_agent == -1)
777 options->forward_agent = 0;
778 if (options->forward_x11 == -1)
779 options->forward_x11 = 0;
781 if (options->xauth_location == NULL)
782 options->xauth_location = XAUTH_PATH;
783 #endif /* XAUTH_PATH */
784 if (options->gateway_ports == -1)
785 options->gateway_ports = 0;
786 if (options->use_privileged_port == -1)
787 options->use_privileged_port = 0;
788 if (options->rhosts_authentication == -1)
789 options->rhosts_authentication = 1;
790 if (options->rsa_authentication == -1)
791 options->rsa_authentication = 1;
792 if (options->pubkey_authentication == -1)
793 options->pubkey_authentication = 1;
794 if (options->challenge_reponse_authentication == -1)
795 options->challenge_reponse_authentication = 0;
797 if (options->kerberos_authentication == -1)
798 options->kerberos_authentication = 1;
801 if (options->kerberos_tgt_passing == -1)
802 options->kerberos_tgt_passing = 1;
803 if (options->afs_token_passing == -1)
804 options->afs_token_passing = 1;
806 if (options->password_authentication == -1)
807 options->password_authentication = 1;
808 if (options->kbd_interactive_authentication == -1)
809 options->kbd_interactive_authentication = 1;
810 if (options->rhosts_rsa_authentication == -1)
811 options->rhosts_rsa_authentication = 1;
812 if (options->hostbased_authentication == -1)
813 options->hostbased_authentication = 0;
814 if (options->fallback_to_rsh == -1)
815 options->fallback_to_rsh = 0;
816 if (options->use_rsh == -1)
817 options->use_rsh = 0;
818 if (options->batch_mode == -1)
819 options->batch_mode = 0;
820 if (options->check_host_ip == -1)
821 options->check_host_ip = 1;
822 if (options->strict_host_key_checking == -1)
823 options->strict_host_key_checking = 2; /* 2 is default */
824 if (options->compression == -1)
825 options->compression = 0;
826 if (options->keepalives == -1)
827 options->keepalives = 1;
828 if (options->compression_level == -1)
829 options->compression_level = 6;
830 if (options->port == -1)
831 options->port = 0; /* Filled in ssh_connect. */
832 if (options->connection_attempts == -1)
833 options->connection_attempts = 4;
834 if (options->number_of_password_prompts == -1)
835 options->number_of_password_prompts = 3;
836 /* Selected in ssh_login(). */
837 if (options->cipher == -1)
838 options->cipher = SSH_CIPHER_NOT_SET;
839 /* options->ciphers, default set in myproposals.h */
840 /* options->macs, default set in myproposals.h */
841 /* options->hostkeyalgorithms, default set in myproposals.h */
842 if (options->protocol == SSH_PROTO_UNKNOWN)
843 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
844 if (options->num_identity_files == 0) {
845 if (options->protocol & SSH_PROTO_1) {
846 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
847 options->identity_files[options->num_identity_files] =
849 snprintf(options->identity_files[options->num_identity_files++],
850 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
852 if (options->protocol & SSH_PROTO_2) {
853 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
854 options->identity_files[options->num_identity_files] =
856 snprintf(options->identity_files[options->num_identity_files++],
857 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
859 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
860 options->identity_files[options->num_identity_files] =
862 snprintf(options->identity_files[options->num_identity_files++],
863 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
866 if (options->escape_char == -1)
867 options->escape_char = '~';
868 if (options->system_hostfile == NULL)
869 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
870 if (options->user_hostfile == NULL)
871 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
872 if (options->system_hostfile2 == NULL)
873 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
874 if (options->user_hostfile2 == NULL)
875 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
876 if (options->log_level == (LogLevel) - 1)
877 options->log_level = SYSLOG_LEVEL_INFO;
878 /* options->proxy_command should not be set by default */
879 /* options->user will be set in the main program if appropriate */
880 /* options->hostname will be set in the main program if appropriate */
881 /* options->host_key_alias should not be set by default */
882 /* options->preferred_authentications will be set in ssh */