1 /* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Functions for reading the configuration files.
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
17 #include <sys/types.h>
19 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #include <arpa/inet.h>
49 #include "pathnames.h"
60 /* Format of the configuration file:
62 # Configuration data is parsed as follows:
63 # 1. command line options
64 # 2. user-specific file
66 # Any configuration value is only changed the first time it is set.
67 # Thus, host-specific definitions should be at the beginning of the
68 # configuration file, and defaults at the end.
70 # Host-specific declarations. These may override anything above. A single
71 # host may match multiple declarations; these are processed in the order
72 # that they are given in.
78 HostName another.host.name.real.org
85 RemoteForward 9999 shadows.cs.hut.fi:9999
91 PasswordAuthentication no
95 ProxyCommand ssh-proxy %h %p
98 PublicKeyAuthentication no
102 PasswordAuthentication no
108 # Defaults for various options
112 PasswordAuthentication yes
113 RSAAuthentication yes
114 RhostsRSAAuthentication yes
115 StrictHostKeyChecking yes
117 IdentityFile ~/.ssh/identity
123 /* Keyword tokens. */
128 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
129 oGatewayPorts, oExitOnForwardFailure,
130 oPasswordAuthentication, oRSAAuthentication,
131 oChallengeResponseAuthentication, oXAuthLocation,
132 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
133 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
134 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
135 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
136 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
137 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
138 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
139 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
140 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
141 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
142 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
143 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
144 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
145 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
146 oSendEnv, oControlPath, oControlMaster, oControlPersist,
148 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
149 oVisualHostKey, oUseRoaming,
150 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
151 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
152 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
153 oStreamLocalBindMask, oStreamLocalBindUnlink,
154 oIgnoredUnknownOption, oDeprecated, oUnsupported
157 /* Textual representations of the tokens. */
163 { "forwardagent", oForwardAgent },
164 { "forwardx11", oForwardX11 },
165 { "forwardx11trusted", oForwardX11Trusted },
166 { "forwardx11timeout", oForwardX11Timeout },
167 { "exitonforwardfailure", oExitOnForwardFailure },
168 { "xauthlocation", oXAuthLocation },
169 { "gatewayports", oGatewayPorts },
170 { "useprivilegedport", oUsePrivilegedPort },
171 { "rhostsauthentication", oDeprecated },
172 { "passwordauthentication", oPasswordAuthentication },
173 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
174 { "kbdinteractivedevices", oKbdInteractiveDevices },
175 { "rsaauthentication", oRSAAuthentication },
176 { "pubkeyauthentication", oPubkeyAuthentication },
177 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
178 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
179 { "hostbasedauthentication", oHostbasedAuthentication },
180 { "challengeresponseauthentication", oChallengeResponseAuthentication },
181 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
182 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
183 { "kerberosauthentication", oUnsupported },
184 { "kerberostgtpassing", oUnsupported },
185 { "afstokenpassing", oUnsupported },
187 { "gssapiauthentication", oGssAuthentication },
188 { "gssapidelegatecredentials", oGssDelegateCreds },
190 { "gssapiauthentication", oUnsupported },
191 { "gssapidelegatecredentials", oUnsupported },
193 { "fallbacktorsh", oDeprecated },
194 { "usersh", oDeprecated },
195 { "identityfile", oIdentityFile },
196 { "identityfile2", oIdentityFile }, /* obsolete */
197 { "identitiesonly", oIdentitiesOnly },
198 { "hostname", oHostName },
199 { "hostkeyalias", oHostKeyAlias },
200 { "proxycommand", oProxyCommand },
202 { "cipher", oCipher },
203 { "ciphers", oCiphers },
205 { "protocol", oProtocol },
206 { "remoteforward", oRemoteForward },
207 { "localforward", oLocalForward },
211 { "escapechar", oEscapeChar },
212 { "globalknownhostsfile", oGlobalKnownHostsFile },
213 { "globalknownhostsfile2", oDeprecated },
214 { "userknownhostsfile", oUserKnownHostsFile },
215 { "userknownhostsfile2", oDeprecated },
216 { "connectionattempts", oConnectionAttempts },
217 { "batchmode", oBatchMode },
218 { "checkhostip", oCheckHostIP },
219 { "stricthostkeychecking", oStrictHostKeyChecking },
220 { "compression", oCompression },
221 { "compressionlevel", oCompressionLevel },
222 { "tcpkeepalive", oTCPKeepAlive },
223 { "keepalive", oTCPKeepAlive }, /* obsolete */
224 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
225 { "loglevel", oLogLevel },
226 { "dynamicforward", oDynamicForward },
227 { "preferredauthentications", oPreferredAuthentications },
228 { "hostkeyalgorithms", oHostKeyAlgorithms },
229 { "bindaddress", oBindAddress },
231 { "smartcarddevice", oPKCS11Provider },
232 { "pkcs11provider", oPKCS11Provider },
234 { "smartcarddevice", oUnsupported },
235 { "pkcs11provider", oUnsupported },
237 { "clearallforwardings", oClearAllForwardings },
238 { "enablesshkeysign", oEnableSSHKeysign },
239 { "verifyhostkeydns", oVerifyHostKeyDNS },
240 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
241 { "rekeylimit", oRekeyLimit },
242 { "connecttimeout", oConnectTimeout },
243 { "addressfamily", oAddressFamily },
244 { "serveraliveinterval", oServerAliveInterval },
245 { "serveralivecountmax", oServerAliveCountMax },
246 { "sendenv", oSendEnv },
247 { "controlpath", oControlPath },
248 { "controlmaster", oControlMaster },
249 { "controlpersist", oControlPersist },
250 { "hashknownhosts", oHashKnownHosts },
251 { "tunnel", oTunnel },
252 { "tunneldevice", oTunnelDevice },
253 { "localcommand", oLocalCommand },
254 { "permitlocalcommand", oPermitLocalCommand },
255 { "visualhostkey", oVisualHostKey },
256 { "useroaming", oUseRoaming },
257 { "kexalgorithms", oKexAlgorithms },
259 { "requesttty", oRequestTTY },
260 { "proxyusefdpass", oProxyUseFdpass },
261 { "canonicaldomains", oCanonicalDomains },
262 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
263 { "canonicalizehostname", oCanonicalizeHostname },
264 { "canonicalizemaxdots", oCanonicalizeMaxDots },
265 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
266 { "streamlocalbindmask", oStreamLocalBindMask },
267 { "streamlocalbindunlink", oStreamLocalBindUnlink },
268 { "ignoreunknown", oIgnoreUnknown },
274 * Adds a local TCP/IP port forward to options. Never returns if there is an
279 add_local_forward(Options *options, const struct Forward *newfwd)
282 #ifndef NO_IPPORT_RESERVED_CONCEPT
283 extern uid_t original_real_uid;
284 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
285 newfwd->listen_path == NULL)
286 fatal("Privileged ports can only be forwarded by root.");
288 options->local_forwards = xrealloc(options->local_forwards,
289 options->num_local_forwards + 1,
290 sizeof(*options->local_forwards));
291 fwd = &options->local_forwards[options->num_local_forwards++];
293 fwd->listen_host = newfwd->listen_host;
294 fwd->listen_port = newfwd->listen_port;
295 fwd->listen_path = newfwd->listen_path;
296 fwd->connect_host = newfwd->connect_host;
297 fwd->connect_port = newfwd->connect_port;
298 fwd->connect_path = newfwd->connect_path;
302 * Adds a remote TCP/IP port forward to options. Never returns if there is
307 add_remote_forward(Options *options, const struct Forward *newfwd)
311 options->remote_forwards = xrealloc(options->remote_forwards,
312 options->num_remote_forwards + 1,
313 sizeof(*options->remote_forwards));
314 fwd = &options->remote_forwards[options->num_remote_forwards++];
316 fwd->listen_host = newfwd->listen_host;
317 fwd->listen_port = newfwd->listen_port;
318 fwd->listen_path = newfwd->listen_path;
319 fwd->connect_host = newfwd->connect_host;
320 fwd->connect_port = newfwd->connect_port;
321 fwd->connect_path = newfwd->connect_path;
322 fwd->handle = newfwd->handle;
323 fwd->allocated_port = 0;
327 clear_forwardings(Options *options)
331 for (i = 0; i < options->num_local_forwards; i++) {
332 free(options->local_forwards[i].listen_host);
333 free(options->local_forwards[i].listen_path);
334 free(options->local_forwards[i].connect_host);
335 free(options->local_forwards[i].connect_path);
337 if (options->num_local_forwards > 0) {
338 free(options->local_forwards);
339 options->local_forwards = NULL;
341 options->num_local_forwards = 0;
342 for (i = 0; i < options->num_remote_forwards; i++) {
343 free(options->remote_forwards[i].listen_host);
344 free(options->remote_forwards[i].listen_path);
345 free(options->remote_forwards[i].connect_host);
346 free(options->remote_forwards[i].connect_path);
348 if (options->num_remote_forwards > 0) {
349 free(options->remote_forwards);
350 options->remote_forwards = NULL;
352 options->num_remote_forwards = 0;
353 options->tun_open = SSH_TUNMODE_NO;
357 add_identity_file(Options *options, const char *dir, const char *filename,
363 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
364 fatal("Too many identity files specified (max %d)",
365 SSH_MAX_IDENTITY_FILES);
367 if (dir == NULL) /* no dir, filename is absolute */
368 path = xstrdup(filename);
370 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
372 /* Avoid registering duplicates */
373 for (i = 0; i < options->num_identity_files; i++) {
374 if (options->identity_file_userprovided[i] == userprovided &&
375 strcmp(options->identity_files[i], path) == 0) {
376 debug2("%s: ignoring duplicate key %s", __func__, path);
382 options->identity_file_userprovided[options->num_identity_files] =
384 options->identity_files[options->num_identity_files++] = path;
388 default_ssh_port(void)
394 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
395 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
401 * Execute a command in a shell.
402 * Return its exit status or -1 on abnormal exit.
405 execute_in_shell(const char *cmd)
407 char *shell, *command_string;
410 extern uid_t original_real_uid;
412 if ((shell = getenv("SHELL")) == NULL)
413 shell = _PATH_BSHELL;
416 * Use "exec" to avoid "sh -c" processes on some platforms
419 xasprintf(&command_string, "exec %s", cmd);
421 /* Need this to redirect subprocess stdin/out */
422 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
423 fatal("open(/dev/null): %s", strerror(errno));
425 debug("Executing command: '%.500s'", cmd);
427 /* Fork and execute the command. */
428 if ((pid = fork()) == 0) {
431 /* Child. Permanently give up superuser privileges. */
432 permanently_drop_suid(original_real_uid);
434 /* Redirect child stdin and stdout. Leave stderr */
435 if (dup2(devnull, STDIN_FILENO) == -1)
436 fatal("dup2: %s", strerror(errno));
437 if (dup2(devnull, STDOUT_FILENO) == -1)
438 fatal("dup2: %s", strerror(errno));
439 if (devnull > STDERR_FILENO)
441 closefrom(STDERR_FILENO + 1);
445 argv[2] = command_string;
448 execv(argv[0], argv);
449 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
450 /* Die with signal to make this error apparent to parent. */
451 signal(SIGTERM, SIG_DFL);
452 kill(getpid(), SIGTERM);
457 fatal("%s: fork: %.100s", __func__, strerror(errno));
460 free(command_string);
462 while (waitpid(pid, &status, 0) == -1) {
463 if (errno != EINTR && errno != EAGAIN)
464 fatal("%s: waitpid: %s", __func__, strerror(errno));
466 if (!WIFEXITED(status)) {
467 error("command '%.100s' exited abnormally", cmd);
470 debug3("command returned status %d", WEXITSTATUS(status));
471 return WEXITSTATUS(status);
475 * Parse and execute a Match directive.
478 match_cfg_line(Options *options, char **condition, struct passwd *pw,
479 const char *host_arg, const char *filename, int linenum)
481 char *arg, *attrib, *cmd, *cp = *condition, *host;
483 int r, port, result = 1, attributes = 0;
485 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
488 * Configuration is likely to be incomplete at this point so we
489 * must be prepared to use default values.
491 port = options->port <= 0 ? default_ssh_port() : options->port;
492 ruser = options->user == NULL ? pw->pw_name : options->user;
493 if (options->hostname != NULL) {
494 /* NB. Please keep in sync with ssh.c:main() */
495 host = percent_expand(options->hostname,
496 "h", host_arg, (char *)NULL);
498 host = xstrdup(host_arg);
500 debug3("checking match for '%s' host %s", cp, host);
501 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
503 if (strcasecmp(attrib, "all") == 0) {
504 if (attributes != 1 ||
505 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
506 error("'all' cannot be combined with other "
515 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
516 error("Missing Match criteria for %s", attrib);
521 if (strcasecmp(attrib, "host") == 0) {
522 if (match_hostname(host, arg, len) != 1)
525 debug("%.200s line %d: matched 'Host %.100s' ",
526 filename, linenum, host);
527 } else if (strcasecmp(attrib, "originalhost") == 0) {
528 if (match_hostname(host_arg, arg, len) != 1)
531 debug("%.200s line %d: matched "
532 "'OriginalHost %.100s' ",
533 filename, linenum, host_arg);
534 } else if (strcasecmp(attrib, "user") == 0) {
535 if (match_pattern_list(ruser, arg, len, 0) != 1)
538 debug("%.200s line %d: matched 'User %.100s' ",
539 filename, linenum, ruser);
540 } else if (strcasecmp(attrib, "localuser") == 0) {
541 if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
544 debug("%.200s line %d: matched "
545 "'LocalUser %.100s' ",
546 filename, linenum, pw->pw_name);
547 } else if (strcasecmp(attrib, "exec") == 0) {
548 if (gethostname(thishost, sizeof(thishost)) == -1)
549 fatal("gethostname: %s", strerror(errno));
550 strlcpy(shorthost, thishost, sizeof(shorthost));
551 shorthost[strcspn(thishost, ".")] = '\0';
552 snprintf(portstr, sizeof(portstr), "%d", port);
554 cmd = percent_expand(arg,
565 /* skip execution if prior predicate failed */
566 debug("%.200s line %d: skipped exec \"%.100s\"",
567 filename, linenum, cmd);
569 r = execute_in_shell(cmd);
571 fatal("%.200s line %d: match exec "
572 "'%.100s' error", filename,
575 debug("%.200s line %d: matched "
576 "'exec \"%.100s\"'", filename,
579 debug("%.200s line %d: no match "
580 "'exec \"%.100s\"'", filename,
587 error("Unsupported Match attribute %s", attrib);
592 if (attributes == 0) {
593 error("One or more attributes required for Match");
597 debug3("match %sfound", result ? "" : "not ");
604 /* Check and prepare a domain name: removes trailing '.' and lowercases */
606 valid_domain(char *name, const char *filename, int linenum)
608 size_t i, l = strlen(name);
609 u_char c, last = '\0';
612 fatal("%s line %d: empty hostname suffix", filename, linenum);
613 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
614 fatal("%s line %d: hostname suffix \"%.100s\" "
615 "starts with invalid character", filename, linenum, name);
616 for (i = 0; i < l; i++) {
617 c = tolower((u_char)name[i]);
619 if (last == '.' && c == '.')
620 fatal("%s line %d: hostname suffix \"%.100s\" contains "
621 "consecutive separators", filename, linenum, name);
622 if (c != '.' && c != '-' && !isalnum(c) &&
623 c != '_') /* technically invalid, but common */
624 fatal("%s line %d: hostname suffix \"%.100s\" contains "
625 "invalid characters", filename, linenum, name);
628 if (name[l - 1] == '.')
633 * Returns the number of the token pointed to by cp or oBadOption.
636 parse_token(const char *cp, const char *filename, int linenum,
637 const char *ignored_unknown)
641 for (i = 0; keywords[i].name; i++)
642 if (strcmp(cp, keywords[i].name) == 0)
643 return keywords[i].opcode;
644 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
645 strlen(ignored_unknown), 1) == 1)
646 return oIgnoredUnknownOption;
647 error("%s: line %d: Bad configuration option: %s",
648 filename, linenum, cp);
652 /* Multistate option parsing */
657 static const struct multistate multistate_flag[] = {
664 static const struct multistate multistate_yesnoask[] = {
672 static const struct multistate multistate_addressfamily[] = {
674 { "inet6", AF_INET6 },
675 { "any", AF_UNSPEC },
678 static const struct multistate multistate_controlmaster[] = {
679 { "true", SSHCTL_MASTER_YES },
680 { "yes", SSHCTL_MASTER_YES },
681 { "false", SSHCTL_MASTER_NO },
682 { "no", SSHCTL_MASTER_NO },
683 { "auto", SSHCTL_MASTER_AUTO },
684 { "ask", SSHCTL_MASTER_ASK },
685 { "autoask", SSHCTL_MASTER_AUTO_ASK },
688 static const struct multistate multistate_tunnel[] = {
689 { "ethernet", SSH_TUNMODE_ETHERNET },
690 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
691 { "true", SSH_TUNMODE_DEFAULT },
692 { "yes", SSH_TUNMODE_DEFAULT },
693 { "false", SSH_TUNMODE_NO },
694 { "no", SSH_TUNMODE_NO },
697 static const struct multistate multistate_requesttty[] = {
698 { "true", REQUEST_TTY_YES },
699 { "yes", REQUEST_TTY_YES },
700 { "false", REQUEST_TTY_NO },
701 { "no", REQUEST_TTY_NO },
702 { "force", REQUEST_TTY_FORCE },
703 { "auto", REQUEST_TTY_AUTO },
706 static const struct multistate multistate_canonicalizehostname[] = {
707 { "true", SSH_CANONICALISE_YES },
708 { "false", SSH_CANONICALISE_NO },
709 { "yes", SSH_CANONICALISE_YES },
710 { "no", SSH_CANONICALISE_NO },
711 { "always", SSH_CANONICALISE_ALWAYS },
716 * Processes a single option line as used in the configuration files. This
717 * only sets those values that have not already been set.
719 #define WHITESPACE " \t\r\n"
721 process_config_line(Options *options, struct passwd *pw, const char *host,
722 char *line, const char *filename, int linenum, int *activep, int userconfig)
724 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
725 char **cpptr, fwdarg[256];
726 u_int i, *uintptr, max_entries = 0;
727 int negated, opcode, *intptr, value, value2, cmdline = 0;
728 LogLevel *log_level_ptr;
732 const struct multistate *multistate_ptr;
733 struct allowed_cname *cname;
735 if (activep == NULL) { /* We are processing a command line directive */
740 /* Strip trailing whitespace */
741 for (len = strlen(line) - 1; len > 0; len--) {
742 if (strchr(WHITESPACE, line[len]) == NULL)
748 /* Get the keyword. (Each line is supposed to begin with a keyword). */
749 if ((keyword = strdelim(&s)) == NULL)
751 /* Ignore leading whitespace. */
752 if (*keyword == '\0')
753 keyword = strdelim(&s);
754 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
756 /* Match lowercase keyword */
759 opcode = parse_token(keyword, filename, linenum,
760 options->ignored_unknown);
764 /* don't panic, but count bad options */
767 case oIgnoredUnknownOption:
768 debug("%s line %d: Ignored unknown option \"%s\"",
769 filename, linenum, keyword);
771 case oConnectTimeout:
772 intptr = &options->connection_timeout;
775 if (!arg || *arg == '\0')
776 fatal("%s line %d: missing time value.",
778 if ((value = convtime(arg)) == -1)
779 fatal("%s line %d: invalid time value.",
781 if (*activep && *intptr == -1)
786 intptr = &options->forward_agent;
788 multistate_ptr = multistate_flag;
791 if (!arg || *arg == '\0')
792 fatal("%s line %d: missing argument.",
795 for (i = 0; multistate_ptr[i].key != NULL; i++) {
796 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
797 value = multistate_ptr[i].value;
802 fatal("%s line %d: unsupported option \"%s\".",
803 filename, linenum, arg);
804 if (*activep && *intptr == -1)
809 intptr = &options->forward_x11;
812 case oForwardX11Trusted:
813 intptr = &options->forward_x11_trusted;
816 case oForwardX11Timeout:
817 intptr = &options->forward_x11_timeout;
821 intptr = &options->fwd_opts.gateway_ports;
824 case oExitOnForwardFailure:
825 intptr = &options->exit_on_forward_failure;
828 case oUsePrivilegedPort:
829 intptr = &options->use_privileged_port;
832 case oPasswordAuthentication:
833 intptr = &options->password_authentication;
836 case oKbdInteractiveAuthentication:
837 intptr = &options->kbd_interactive_authentication;
840 case oKbdInteractiveDevices:
841 charptr = &options->kbd_interactive_devices;
844 case oPubkeyAuthentication:
845 intptr = &options->pubkey_authentication;
848 case oRSAAuthentication:
849 intptr = &options->rsa_authentication;
852 case oRhostsRSAAuthentication:
853 intptr = &options->rhosts_rsa_authentication;
856 case oHostbasedAuthentication:
857 intptr = &options->hostbased_authentication;
860 case oChallengeResponseAuthentication:
861 intptr = &options->challenge_response_authentication;
864 case oGssAuthentication:
865 intptr = &options->gss_authentication;
868 case oGssDelegateCreds:
869 intptr = &options->gss_deleg_creds;
873 intptr = &options->batch_mode;
877 intptr = &options->check_host_ip;
880 case oVerifyHostKeyDNS:
881 intptr = &options->verify_host_key_dns;
882 multistate_ptr = multistate_yesnoask;
883 goto parse_multistate;
885 case oStrictHostKeyChecking:
886 intptr = &options->strict_host_key_checking;
887 multistate_ptr = multistate_yesnoask;
888 goto parse_multistate;
891 intptr = &options->compression;
895 intptr = &options->tcp_keep_alive;
898 case oNoHostAuthenticationForLocalhost:
899 intptr = &options->no_host_authentication_for_localhost;
902 case oNumberOfPasswordPrompts:
903 intptr = &options->number_of_password_prompts;
906 case oCompressionLevel:
907 intptr = &options->compression_level;
912 if (!arg || *arg == '\0')
913 fatal("%.200s line %d: Missing argument.", filename,
915 if (strcmp(arg, "default") == 0) {
918 if (scan_scaled(arg, &val64) == -1)
919 fatal("%.200s line %d: Bad number '%s': %s",
920 filename, linenum, arg, strerror(errno));
921 /* check for too-large or too-small limits */
922 if (val64 > UINT_MAX)
923 fatal("%.200s line %d: RekeyLimit too large",
925 if (val64 != 0 && val64 < 16)
926 fatal("%.200s line %d: RekeyLimit too small",
929 if (*activep && options->rekey_limit == -1)
930 options->rekey_limit = (u_int32_t)val64;
931 if (s != NULL) { /* optional rekey interval present */
932 if (strcmp(s, "none") == 0) {
933 (void)strdelim(&s); /* discard */
936 intptr = &options->rekey_interval;
943 if (!arg || *arg == '\0')
944 fatal("%.200s line %d: Missing argument.", filename, linenum);
946 intptr = &options->num_identity_files;
947 if (*intptr >= SSH_MAX_IDENTITY_FILES)
948 fatal("%.200s line %d: Too many identity files specified (max %d).",
949 filename, linenum, SSH_MAX_IDENTITY_FILES);
950 add_identity_file(options, NULL, arg, userconfig);
955 charptr=&options->xauth_location;
959 charptr = &options->user;
962 if (!arg || *arg == '\0')
963 fatal("%.200s line %d: Missing argument.",
965 if (*activep && *charptr == NULL)
966 *charptr = xstrdup(arg);
969 case oGlobalKnownHostsFile:
970 cpptr = (char **)&options->system_hostfiles;
971 uintptr = &options->num_system_hostfiles;
972 max_entries = SSH_MAX_HOSTS_FILES;
974 if (*activep && *uintptr == 0) {
975 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
976 if ((*uintptr) >= max_entries)
978 "too many authorized keys files.",
980 cpptr[(*uintptr)++] = xstrdup(arg);
985 case oUserKnownHostsFile:
986 cpptr = (char **)&options->user_hostfiles;
987 uintptr = &options->num_user_hostfiles;
988 max_entries = SSH_MAX_HOSTS_FILES;
989 goto parse_char_array;
992 charptr = &options->hostname;
996 charptr = &options->host_key_alias;
999 case oPreferredAuthentications:
1000 charptr = &options->preferred_authentications;
1004 charptr = &options->bind_address;
1007 case oPKCS11Provider:
1008 charptr = &options->pkcs11_provider;
1012 charptr = &options->proxy_command;
1015 fatal("%.200s line %d: Missing argument.", filename, linenum);
1016 len = strspn(s, WHITESPACE "=");
1017 if (*activep && *charptr == NULL)
1018 *charptr = xstrdup(s + len);
1022 intptr = &options->port;
1025 if (!arg || *arg == '\0')
1026 fatal("%.200s line %d: Missing argument.", filename, linenum);
1027 if (arg[0] < '0' || arg[0] > '9')
1028 fatal("%.200s line %d: Bad number.", filename, linenum);
1030 /* Octal, decimal, or hex format? */
1031 value = strtol(arg, &endofnumber, 0);
1032 if (arg == endofnumber)
1033 fatal("%.200s line %d: Bad number.", filename, linenum);
1034 if (*activep && *intptr == -1)
1038 case oConnectionAttempts:
1039 intptr = &options->connection_attempts;
1043 intptr = &options->cipher;
1045 if (!arg || *arg == '\0')
1046 fatal("%.200s line %d: Missing argument.", filename, linenum);
1047 value = cipher_number(arg);
1049 fatal("%.200s line %d: Bad cipher '%s'.",
1050 filename, linenum, arg ? arg : "<NONE>");
1051 if (*activep && *intptr == -1)
1057 if (!arg || *arg == '\0')
1058 fatal("%.200s line %d: Missing argument.", filename, linenum);
1059 if (!ciphers_valid(arg))
1060 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1061 filename, linenum, arg ? arg : "<NONE>");
1062 if (*activep && options->ciphers == NULL)
1063 options->ciphers = xstrdup(arg);
1068 if (!arg || *arg == '\0')
1069 fatal("%.200s line %d: Missing argument.", filename, linenum);
1070 if (!mac_valid(arg))
1071 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1072 filename, linenum, arg ? arg : "<NONE>");
1073 if (*activep && options->macs == NULL)
1074 options->macs = xstrdup(arg);
1077 case oKexAlgorithms:
1079 if (!arg || *arg == '\0')
1080 fatal("%.200s line %d: Missing argument.",
1082 if (!kex_names_valid(arg))
1083 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1084 filename, linenum, arg ? arg : "<NONE>");
1085 if (*activep && options->kex_algorithms == NULL)
1086 options->kex_algorithms = xstrdup(arg);
1089 case oHostKeyAlgorithms:
1091 if (!arg || *arg == '\0')
1092 fatal("%.200s line %d: Missing argument.", filename, linenum);
1093 if (!key_names_valid2(arg))
1094 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1095 filename, linenum, arg ? arg : "<NONE>");
1096 if (*activep && options->hostkeyalgorithms == NULL)
1097 options->hostkeyalgorithms = xstrdup(arg);
1101 intptr = &options->protocol;
1103 if (!arg || *arg == '\0')
1104 fatal("%.200s line %d: Missing argument.", filename, linenum);
1105 value = proto_spec(arg);
1106 if (value == SSH_PROTO_UNKNOWN)
1107 fatal("%.200s line %d: Bad protocol spec '%s'.",
1108 filename, linenum, arg ? arg : "<NONE>");
1109 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1114 log_level_ptr = &options->log_level;
1116 value = log_level_number(arg);
1117 if (value == SYSLOG_LEVEL_NOT_SET)
1118 fatal("%.200s line %d: unsupported log level '%s'",
1119 filename, linenum, arg ? arg : "<NONE>");
1120 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1121 *log_level_ptr = (LogLevel) value;
1125 case oRemoteForward:
1126 case oDynamicForward:
1128 if (arg == NULL || *arg == '\0')
1129 fatal("%.200s line %d: Missing port argument.",
1132 if (opcode == oLocalForward ||
1133 opcode == oRemoteForward) {
1134 arg2 = strdelim(&s);
1135 if (arg2 == NULL || *arg2 == '\0')
1136 fatal("%.200s line %d: Missing target argument.",
1139 /* construct a string for parse_forward */
1140 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1141 } else if (opcode == oDynamicForward) {
1142 strlcpy(fwdarg, arg, sizeof(fwdarg));
1145 if (parse_forward(&fwd, fwdarg,
1146 opcode == oDynamicForward ? 1 : 0,
1147 opcode == oRemoteForward ? 1 : 0) == 0)
1148 fatal("%.200s line %d: Bad forwarding specification.",
1152 if (opcode == oLocalForward ||
1153 opcode == oDynamicForward)
1154 add_local_forward(options, &fwd);
1155 else if (opcode == oRemoteForward)
1156 add_remote_forward(options, &fwd);
1160 case oClearAllForwardings:
1161 intptr = &options->clear_forwardings;
1166 fatal("Host directive not supported as a command-line "
1170 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1171 negated = *arg == '!';
1174 if (match_pattern(host, arg)) {
1176 debug("%.200s line %d: Skipping Host "
1177 "block because of negated match "
1178 "for %.100s", filename, linenum,
1184 arg2 = arg; /* logged below */
1189 debug("%.200s line %d: Applying options for %.100s",
1190 filename, linenum, arg2);
1191 /* Avoid garbage check below, as strdelim is done. */
1196 fatal("Host directive not supported as a command-line "
1198 value = match_cfg_line(options, &s, pw, host,
1201 fatal("%.200s line %d: Bad Match condition", filename,
1207 intptr = &options->escape_char;
1209 if (!arg || *arg == '\0')
1210 fatal("%.200s line %d: Missing argument.", filename, linenum);
1211 if (arg[0] == '^' && arg[2] == 0 &&
1212 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1213 value = (u_char) arg[1] & 31;
1214 else if (strlen(arg) == 1)
1215 value = (u_char) arg[0];
1216 else if (strcmp(arg, "none") == 0)
1217 value = SSH_ESCAPECHAR_NONE;
1219 fatal("%.200s line %d: Bad escape character.",
1222 value = 0; /* Avoid compiler warning. */
1224 if (*activep && *intptr == -1)
1228 case oAddressFamily:
1229 intptr = &options->address_family;
1230 multistate_ptr = multistate_addressfamily;
1231 goto parse_multistate;
1233 case oEnableSSHKeysign:
1234 intptr = &options->enable_ssh_keysign;
1237 case oIdentitiesOnly:
1238 intptr = &options->identities_only;
1241 case oServerAliveInterval:
1242 intptr = &options->server_alive_interval;
1245 case oServerAliveCountMax:
1246 intptr = &options->server_alive_count_max;
1250 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1251 if (strchr(arg, '=') != NULL)
1252 fatal("%s line %d: Invalid environment name.",
1256 if (options->num_send_env >= MAX_SEND_ENV)
1257 fatal("%s line %d: too many send env.",
1259 options->send_env[options->num_send_env++] =
1265 charptr = &options->control_path;
1268 case oControlMaster:
1269 intptr = &options->control_master;
1270 multistate_ptr = multistate_controlmaster;
1271 goto parse_multistate;
1273 case oControlPersist:
1274 /* no/false/yes/true, or a time spec */
1275 intptr = &options->control_persist;
1277 if (!arg || *arg == '\0')
1278 fatal("%.200s line %d: Missing ControlPersist"
1279 " argument.", filename, linenum);
1281 value2 = 0; /* timeout */
1282 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1284 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1286 else if ((value2 = convtime(arg)) >= 0)
1289 fatal("%.200s line %d: Bad ControlPersist argument.",
1291 if (*activep && *intptr == -1) {
1293 options->control_persist_timeout = value2;
1297 case oHashKnownHosts:
1298 intptr = &options->hash_known_hosts;
1302 intptr = &options->tun_open;
1303 multistate_ptr = multistate_tunnel;
1304 goto parse_multistate;
1308 if (!arg || *arg == '\0')
1309 fatal("%.200s line %d: Missing argument.", filename, linenum);
1310 value = a2tun(arg, &value2);
1311 if (value == SSH_TUNID_ERR)
1312 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1314 options->tun_local = value;
1315 options->tun_remote = value2;
1320 charptr = &options->local_command;
1323 case oPermitLocalCommand:
1324 intptr = &options->permit_local_command;
1327 case oVisualHostKey:
1328 intptr = &options->visual_host_key;
1333 if ((value = parse_ipqos(arg)) == -1)
1334 fatal("%s line %d: Bad IPQoS value: %s",
1335 filename, linenum, arg);
1339 else if ((value2 = parse_ipqos(arg)) == -1)
1340 fatal("%s line %d: Bad IPQoS value: %s",
1341 filename, linenum, arg);
1343 options->ip_qos_interactive = value;
1344 options->ip_qos_bulk = value2;
1349 intptr = &options->use_roaming;
1353 intptr = &options->request_tty;
1354 multistate_ptr = multistate_requesttty;
1355 goto parse_multistate;
1357 case oIgnoreUnknown:
1358 charptr = &options->ignored_unknown;
1361 case oProxyUseFdpass:
1362 intptr = &options->proxy_use_fdpass;
1365 case oCanonicalDomains:
1366 value = options->num_canonical_domains != 0;
1367 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1368 valid_domain(arg, filename, linenum);
1369 if (!*activep || value)
1371 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1372 fatal("%s line %d: too many hostname suffixes.",
1374 options->canonical_domains[
1375 options->num_canonical_domains++] = xstrdup(arg);
1379 case oCanonicalizePermittedCNAMEs:
1380 value = options->num_permitted_cnames != 0;
1381 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1382 /* Either '*' for everything or 'list:list' */
1383 if (strcmp(arg, "*") == 0)
1387 if ((arg2 = strchr(arg, ':')) == NULL ||
1389 fatal("%s line %d: "
1390 "Invalid permitted CNAME \"%s\"",
1391 filename, linenum, arg);
1396 if (!*activep || value)
1398 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1399 fatal("%s line %d: too many permitted CNAMEs.",
1401 cname = options->permitted_cnames +
1402 options->num_permitted_cnames++;
1403 cname->source_list = xstrdup(arg);
1404 cname->target_list = xstrdup(arg2);
1408 case oCanonicalizeHostname:
1409 intptr = &options->canonicalize_hostname;
1410 multistate_ptr = multistate_canonicalizehostname;
1411 goto parse_multistate;
1413 case oCanonicalizeMaxDots:
1414 intptr = &options->canonicalize_max_dots;
1417 case oCanonicalizeFallbackLocal:
1418 intptr = &options->canonicalize_fallback_local;
1421 case oStreamLocalBindMask:
1423 if (!arg || *arg == '\0')
1424 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1425 /* Parse mode in octal format */
1426 value = strtol(arg, &endofnumber, 8);
1427 if (arg == endofnumber || value < 0 || value > 0777)
1428 fatal("%.200s line %d: Bad mask.", filename, linenum);
1429 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1432 case oStreamLocalBindUnlink:
1433 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1437 debug("%s line %d: Deprecated option \"%s\"",
1438 filename, linenum, keyword);
1442 error("%s line %d: Unsupported option \"%s\"",
1443 filename, linenum, keyword);
1447 fatal("process_config_line: Unimplemented opcode %d", opcode);
1450 /* Check that there is no garbage at end of line. */
1451 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1452 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1453 filename, linenum, arg);
1460 * Reads the config file and modifies the options accordingly. Options
1461 * should already be initialized before this call. This never returns if
1462 * there is an error. If the file does not exist, this returns 0.
1466 read_config_file(const char *filename, struct passwd *pw, const char *host,
1467 Options *options, int flags)
1471 int active, linenum;
1472 int bad_options = 0;
1474 if ((f = fopen(filename, "r")) == NULL)
1477 if (flags & SSHCONF_CHECKPERM) {
1480 if (fstat(fileno(f), &sb) == -1)
1481 fatal("fstat %s: %s", filename, strerror(errno));
1482 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1483 (sb.st_mode & 022) != 0))
1484 fatal("Bad owner or permissions on %s", filename);
1487 debug("Reading configuration data %.200s", filename);
1490 * Mark that we are now processing the options. This flag is turned
1491 * on/off by Host specifications.
1495 while (fgets(line, sizeof(line), f)) {
1496 /* Update line number counter. */
1498 if (process_config_line(options, pw, host, line, filename,
1499 linenum, &active, flags & SSHCONF_USERCONF) != 0)
1503 if (bad_options > 0)
1504 fatal("%s: terminating, %d bad configuration options",
1505 filename, bad_options);
1509 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1511 option_clear_or_none(const char *o)
1513 return o == NULL || strcasecmp(o, "none") == 0;
1517 * Initializes options to special values that indicate that they have not yet
1518 * been set. Read_config_file will only set options with this value. Options
1519 * are processed in the following order: command line, user config file,
1520 * system config file. Last, fill_default_options is called.
1524 initialize_options(Options * options)
1526 memset(options, 'X', sizeof(*options));
1527 options->forward_agent = -1;
1528 options->forward_x11 = -1;
1529 options->forward_x11_trusted = -1;
1530 options->forward_x11_timeout = -1;
1531 options->exit_on_forward_failure = -1;
1532 options->xauth_location = NULL;
1533 options->fwd_opts.gateway_ports = -1;
1534 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1535 options->fwd_opts.streamlocal_bind_unlink = -1;
1536 options->use_privileged_port = -1;
1537 options->rsa_authentication = -1;
1538 options->pubkey_authentication = -1;
1539 options->challenge_response_authentication = -1;
1540 options->gss_authentication = -1;
1541 options->gss_deleg_creds = -1;
1542 options->password_authentication = -1;
1543 options->kbd_interactive_authentication = -1;
1544 options->kbd_interactive_devices = NULL;
1545 options->rhosts_rsa_authentication = -1;
1546 options->hostbased_authentication = -1;
1547 options->batch_mode = -1;
1548 options->check_host_ip = -1;
1549 options->strict_host_key_checking = -1;
1550 options->compression = -1;
1551 options->tcp_keep_alive = -1;
1552 options->compression_level = -1;
1554 options->address_family = -1;
1555 options->connection_attempts = -1;
1556 options->connection_timeout = -1;
1557 options->number_of_password_prompts = -1;
1558 options->cipher = -1;
1559 options->ciphers = NULL;
1560 options->macs = NULL;
1561 options->kex_algorithms = NULL;
1562 options->hostkeyalgorithms = NULL;
1563 options->protocol = SSH_PROTO_UNKNOWN;
1564 options->num_identity_files = 0;
1565 options->hostname = NULL;
1566 options->host_key_alias = NULL;
1567 options->proxy_command = NULL;
1568 options->user = NULL;
1569 options->escape_char = -1;
1570 options->num_system_hostfiles = 0;
1571 options->num_user_hostfiles = 0;
1572 options->local_forwards = NULL;
1573 options->num_local_forwards = 0;
1574 options->remote_forwards = NULL;
1575 options->num_remote_forwards = 0;
1576 options->clear_forwardings = -1;
1577 options->log_level = SYSLOG_LEVEL_NOT_SET;
1578 options->preferred_authentications = NULL;
1579 options->bind_address = NULL;
1580 options->pkcs11_provider = NULL;
1581 options->enable_ssh_keysign = - 1;
1582 options->no_host_authentication_for_localhost = - 1;
1583 options->identities_only = - 1;
1584 options->rekey_limit = - 1;
1585 options->rekey_interval = -1;
1586 options->verify_host_key_dns = -1;
1587 options->server_alive_interval = -1;
1588 options->server_alive_count_max = -1;
1589 options->num_send_env = 0;
1590 options->control_path = NULL;
1591 options->control_master = -1;
1592 options->control_persist = -1;
1593 options->control_persist_timeout = 0;
1594 options->hash_known_hosts = -1;
1595 options->tun_open = -1;
1596 options->tun_local = -1;
1597 options->tun_remote = -1;
1598 options->local_command = NULL;
1599 options->permit_local_command = -1;
1600 options->use_roaming = -1;
1601 options->visual_host_key = -1;
1602 options->ip_qos_interactive = -1;
1603 options->ip_qos_bulk = -1;
1604 options->request_tty = -1;
1605 options->proxy_use_fdpass = -1;
1606 options->ignored_unknown = NULL;
1607 options->num_canonical_domains = 0;
1608 options->num_permitted_cnames = 0;
1609 options->canonicalize_max_dots = -1;
1610 options->canonicalize_fallback_local = -1;
1611 options->canonicalize_hostname = -1;
1615 * A petite version of fill_default_options() that just fills the options
1616 * needed for hostname canonicalization to proceed.
1619 fill_default_options_for_canonicalization(Options *options)
1621 if (options->canonicalize_max_dots == -1)
1622 options->canonicalize_max_dots = 1;
1623 if (options->canonicalize_fallback_local == -1)
1624 options->canonicalize_fallback_local = 1;
1625 if (options->canonicalize_hostname == -1)
1626 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1630 * Called after processing other sources of option data, this fills those
1631 * options for which no value has been specified with their default values.
1634 fill_default_options(Options * options)
1636 if (options->forward_agent == -1)
1637 options->forward_agent = 0;
1638 if (options->forward_x11 == -1)
1639 options->forward_x11 = 0;
1640 if (options->forward_x11_trusted == -1)
1641 options->forward_x11_trusted = 0;
1642 if (options->forward_x11_timeout == -1)
1643 options->forward_x11_timeout = 1200;
1644 if (options->exit_on_forward_failure == -1)
1645 options->exit_on_forward_failure = 0;
1646 if (options->xauth_location == NULL)
1647 options->xauth_location = _PATH_XAUTH;
1648 if (options->fwd_opts.gateway_ports == -1)
1649 options->fwd_opts.gateway_ports = 0;
1650 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1651 options->fwd_opts.streamlocal_bind_mask = 0177;
1652 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1653 options->fwd_opts.streamlocal_bind_unlink = 0;
1654 if (options->use_privileged_port == -1)
1655 options->use_privileged_port = 0;
1656 if (options->rsa_authentication == -1)
1657 options->rsa_authentication = 1;
1658 if (options->pubkey_authentication == -1)
1659 options->pubkey_authentication = 1;
1660 if (options->challenge_response_authentication == -1)
1661 options->challenge_response_authentication = 1;
1662 if (options->gss_authentication == -1)
1663 options->gss_authentication = 0;
1664 if (options->gss_deleg_creds == -1)
1665 options->gss_deleg_creds = 0;
1666 if (options->password_authentication == -1)
1667 options->password_authentication = 1;
1668 if (options->kbd_interactive_authentication == -1)
1669 options->kbd_interactive_authentication = 1;
1670 if (options->rhosts_rsa_authentication == -1)
1671 options->rhosts_rsa_authentication = 0;
1672 if (options->hostbased_authentication == -1)
1673 options->hostbased_authentication = 0;
1674 if (options->batch_mode == -1)
1675 options->batch_mode = 0;
1676 if (options->check_host_ip == -1)
1677 options->check_host_ip = 1;
1678 if (options->strict_host_key_checking == -1)
1679 options->strict_host_key_checking = 2; /* 2 is default */
1680 if (options->compression == -1)
1681 options->compression = 0;
1682 if (options->tcp_keep_alive == -1)
1683 options->tcp_keep_alive = 1;
1684 if (options->compression_level == -1)
1685 options->compression_level = 6;
1686 if (options->port == -1)
1687 options->port = 0; /* Filled in ssh_connect. */
1688 if (options->address_family == -1)
1689 options->address_family = AF_UNSPEC;
1690 if (options->connection_attempts == -1)
1691 options->connection_attempts = 1;
1692 if (options->number_of_password_prompts == -1)
1693 options->number_of_password_prompts = 3;
1694 /* Selected in ssh_login(). */
1695 if (options->cipher == -1)
1696 options->cipher = SSH_CIPHER_NOT_SET;
1697 /* options->ciphers, default set in myproposals.h */
1698 /* options->macs, default set in myproposals.h */
1699 /* options->kex_algorithms, default set in myproposals.h */
1700 /* options->hostkeyalgorithms, default set in myproposals.h */
1701 if (options->protocol == SSH_PROTO_UNKNOWN)
1702 options->protocol = SSH_PROTO_2;
1703 if (options->num_identity_files == 0) {
1704 if (options->protocol & SSH_PROTO_1) {
1705 add_identity_file(options, "~/",
1706 _PATH_SSH_CLIENT_IDENTITY, 0);
1708 if (options->protocol & SSH_PROTO_2) {
1709 add_identity_file(options, "~/",
1710 _PATH_SSH_CLIENT_ID_RSA, 0);
1711 add_identity_file(options, "~/",
1712 _PATH_SSH_CLIENT_ID_DSA, 0);
1713 #ifdef OPENSSL_HAS_ECC
1714 add_identity_file(options, "~/",
1715 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1717 add_identity_file(options, "~/",
1718 _PATH_SSH_CLIENT_ID_ED25519, 0);
1721 if (options->escape_char == -1)
1722 options->escape_char = '~';
1723 if (options->num_system_hostfiles == 0) {
1724 options->system_hostfiles[options->num_system_hostfiles++] =
1725 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1726 options->system_hostfiles[options->num_system_hostfiles++] =
1727 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1729 if (options->num_user_hostfiles == 0) {
1730 options->user_hostfiles[options->num_user_hostfiles++] =
1731 xstrdup(_PATH_SSH_USER_HOSTFILE);
1732 options->user_hostfiles[options->num_user_hostfiles++] =
1733 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1735 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1736 options->log_level = SYSLOG_LEVEL_INFO;
1737 if (options->clear_forwardings == 1)
1738 clear_forwardings(options);
1739 if (options->no_host_authentication_for_localhost == - 1)
1740 options->no_host_authentication_for_localhost = 0;
1741 if (options->identities_only == -1)
1742 options->identities_only = 0;
1743 if (options->enable_ssh_keysign == -1)
1744 options->enable_ssh_keysign = 0;
1745 if (options->rekey_limit == -1)
1746 options->rekey_limit = 0;
1747 if (options->rekey_interval == -1)
1748 options->rekey_interval = 0;
1749 if (options->verify_host_key_dns == -1)
1750 options->verify_host_key_dns = 0;
1751 if (options->server_alive_interval == -1)
1752 options->server_alive_interval = 0;
1753 if (options->server_alive_count_max == -1)
1754 options->server_alive_count_max = 3;
1755 if (options->control_master == -1)
1756 options->control_master = 0;
1757 if (options->control_persist == -1) {
1758 options->control_persist = 0;
1759 options->control_persist_timeout = 0;
1761 if (options->hash_known_hosts == -1)
1762 options->hash_known_hosts = 0;
1763 if (options->tun_open == -1)
1764 options->tun_open = SSH_TUNMODE_NO;
1765 if (options->tun_local == -1)
1766 options->tun_local = SSH_TUNID_ANY;
1767 if (options->tun_remote == -1)
1768 options->tun_remote = SSH_TUNID_ANY;
1769 if (options->permit_local_command == -1)
1770 options->permit_local_command = 0;
1771 if (options->use_roaming == -1)
1772 options->use_roaming = 1;
1773 if (options->visual_host_key == -1)
1774 options->visual_host_key = 0;
1775 if (options->ip_qos_interactive == -1)
1776 options->ip_qos_interactive = IPTOS_LOWDELAY;
1777 if (options->ip_qos_bulk == -1)
1778 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1779 if (options->request_tty == -1)
1780 options->request_tty = REQUEST_TTY_AUTO;
1781 if (options->proxy_use_fdpass == -1)
1782 options->proxy_use_fdpass = 0;
1783 if (options->canonicalize_max_dots == -1)
1784 options->canonicalize_max_dots = 1;
1785 if (options->canonicalize_fallback_local == -1)
1786 options->canonicalize_fallback_local = 1;
1787 if (options->canonicalize_hostname == -1)
1788 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1789 #define CLEAR_ON_NONE(v) \
1791 if (option_clear_or_none(v)) { \
1796 CLEAR_ON_NONE(options->local_command);
1797 CLEAR_ON_NONE(options->proxy_command);
1798 CLEAR_ON_NONE(options->control_path);
1799 /* options->user will be set in the main program if appropriate */
1800 /* options->hostname will be set in the main program if appropriate */
1801 /* options->host_key_alias should not be set by default */
1802 /* options->preferred_authentications will be set in ssh */
1812 * parses the next field in a port forwarding specification.
1813 * sets fwd to the parsed field and advances p past the colon
1814 * or sets it to NULL at end of string.
1815 * returns 0 on success, else non-zero.
1818 parse_fwd_field(char **p, struct fwdarg *fwd)
1825 return -1; /* end of string */
1829 * A field escaped with square brackets is used literally.
1830 * XXX - allow ']' to be escaped via backslash?
1833 /* find matching ']' */
1834 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1838 /* no matching ']' or not at end of field. */
1839 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1841 /* NUL terminate the field and advance p past the colon */
1846 fwd->ispath = ispath;
1851 for (cp = *p; *cp != '\0'; cp++) {
1854 memmove(cp, cp + 1, strlen(cp + 1) + 1);
1867 fwd->ispath = ispath;
1874 * parses a string containing a port forwarding specification of the form:
1876 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
1877 * listenpath:connectpath
1879 * [listenhost:]listenport
1880 * returns number of arguments parsed or zero on error
1883 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1885 struct fwdarg fwdargs[4];
1889 memset(fwd, 0, sizeof(*fwd));
1890 memset(fwdargs, 0, sizeof(fwdargs));
1892 cp = p = xstrdup(fwdspec);
1894 /* skip leading spaces */
1895 while (isspace((u_char)*cp))
1898 for (i = 0; i < 4; ++i) {
1899 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
1903 /* Check for trailing garbage */
1904 if (cp != NULL && *cp != '\0') {
1905 i = 0; /* failure */
1910 if (fwdargs[0].ispath) {
1911 fwd->listen_path = xstrdup(fwdargs[0].arg);
1912 fwd->listen_port = PORT_STREAMLOCAL;
1914 fwd->listen_host = NULL;
1915 fwd->listen_port = a2port(fwdargs[0].arg);
1917 fwd->connect_host = xstrdup("socks");
1921 if (fwdargs[0].ispath && fwdargs[1].ispath) {
1922 fwd->listen_path = xstrdup(fwdargs[0].arg);
1923 fwd->listen_port = PORT_STREAMLOCAL;
1924 fwd->connect_path = xstrdup(fwdargs[1].arg);
1925 fwd->connect_port = PORT_STREAMLOCAL;
1926 } else if (fwdargs[1].ispath) {
1927 fwd->listen_host = NULL;
1928 fwd->listen_port = a2port(fwdargs[0].arg);
1929 fwd->connect_path = xstrdup(fwdargs[1].arg);
1930 fwd->connect_port = PORT_STREAMLOCAL;
1932 fwd->listen_host = xstrdup(fwdargs[0].arg);
1933 fwd->listen_port = a2port(fwdargs[1].arg);
1934 fwd->connect_host = xstrdup("socks");
1939 if (fwdargs[0].ispath) {
1940 fwd->listen_path = xstrdup(fwdargs[0].arg);
1941 fwd->listen_port = PORT_STREAMLOCAL;
1942 fwd->connect_host = xstrdup(fwdargs[1].arg);
1943 fwd->connect_port = a2port(fwdargs[2].arg);
1944 } else if (fwdargs[2].ispath) {
1945 fwd->listen_host = xstrdup(fwdargs[0].arg);
1946 fwd->listen_port = a2port(fwdargs[1].arg);
1947 fwd->connect_path = xstrdup(fwdargs[2].arg);
1948 fwd->connect_port = PORT_STREAMLOCAL;
1950 fwd->listen_host = NULL;
1951 fwd->listen_port = a2port(fwdargs[0].arg);
1952 fwd->connect_host = xstrdup(fwdargs[1].arg);
1953 fwd->connect_port = a2port(fwdargs[2].arg);
1958 fwd->listen_host = xstrdup(fwdargs[0].arg);
1959 fwd->listen_port = a2port(fwdargs[1].arg);
1960 fwd->connect_host = xstrdup(fwdargs[2].arg);
1961 fwd->connect_port = a2port(fwdargs[3].arg);
1964 i = 0; /* failure */
1970 if (!(i == 1 || i == 2))
1973 if (!(i == 3 || i == 4)) {
1974 if (fwd->connect_path == NULL &&
1975 fwd->listen_path == NULL)
1978 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
1982 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
1983 (!remotefwd && fwd->listen_port == 0))
1985 if (fwd->connect_host != NULL &&
1986 strlen(fwd->connect_host) >= NI_MAXHOST)
1988 /* XXX - if connecting to a remote socket, max sun len may not match this host */
1989 if (fwd->connect_path != NULL &&
1990 strlen(fwd->connect_path) >= PATH_MAX_SUN)
1992 if (fwd->listen_host != NULL &&
1993 strlen(fwd->listen_host) >= NI_MAXHOST)
1995 if (fwd->listen_path != NULL &&
1996 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2002 free(fwd->connect_host);
2003 fwd->connect_host = NULL;
2004 free(fwd->connect_path);
2005 fwd->connect_path = NULL;
2006 free(fwd->listen_host);
2007 fwd->listen_host = NULL;
2008 free(fwd->listen_path);
2009 fwd->listen_path = NULL;