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"
61 /* Format of the configuration file:
63 # Configuration data is parsed as follows:
64 # 1. command line options
65 # 2. user-specific file
67 # Any configuration value is only changed the first time it is set.
68 # Thus, host-specific definitions should be at the beginning of the
69 # configuration file, and defaults at the end.
71 # Host-specific declarations. These may override anything above. A single
72 # host may match multiple declarations; these are processed in the order
73 # that they are given in.
79 HostName another.host.name.real.org
86 RemoteForward 9999 shadows.cs.hut.fi:9999
92 PasswordAuthentication no
96 ProxyCommand ssh-proxy %h %p
99 PublicKeyAuthentication no
103 PasswordAuthentication no
109 # Defaults for various options
113 PasswordAuthentication yes
114 RSAAuthentication yes
115 RhostsRSAAuthentication yes
116 StrictHostKeyChecking yes
118 IdentityFile ~/.ssh/identity
124 /* Keyword tokens. */
129 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
130 oGatewayPorts, oExitOnForwardFailure,
131 oPasswordAuthentication, oRSAAuthentication,
132 oChallengeResponseAuthentication, oXAuthLocation,
133 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
134 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
135 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
136 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
137 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
138 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
139 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
140 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
141 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
142 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
143 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
144 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
145 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
146 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
148 oSendEnv, oControlPath, oControlMaster, oControlPersist,
150 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
151 oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize,
152 oNoneEnabled, oNoneSwitch,
153 oVisualHostKey, oUseRoaming,
154 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
155 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
156 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
157 oStreamLocalBindMask, oStreamLocalBindUnlink,
158 oIgnoredUnknownOption, oDeprecated, oUnsupported
161 /* Textual representations of the tokens. */
167 { "forwardagent", oForwardAgent },
168 { "forwardx11", oForwardX11 },
169 { "forwardx11trusted", oForwardX11Trusted },
170 { "forwardx11timeout", oForwardX11Timeout },
171 { "exitonforwardfailure", oExitOnForwardFailure },
172 { "xauthlocation", oXAuthLocation },
173 { "gatewayports", oGatewayPorts },
174 { "useprivilegedport", oUsePrivilegedPort },
175 { "rhostsauthentication", oDeprecated },
176 { "passwordauthentication", oPasswordAuthentication },
177 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
178 { "kbdinteractivedevices", oKbdInteractiveDevices },
179 { "rsaauthentication", oRSAAuthentication },
180 { "pubkeyauthentication", oPubkeyAuthentication },
181 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
182 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
183 { "hostbasedauthentication", oHostbasedAuthentication },
184 { "challengeresponseauthentication", oChallengeResponseAuthentication },
185 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
186 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
187 { "kerberosauthentication", oUnsupported },
188 { "kerberostgtpassing", oUnsupported },
189 { "afstokenpassing", oUnsupported },
191 { "gssapiauthentication", oGssAuthentication },
192 { "gssapidelegatecredentials", oGssDelegateCreds },
194 { "gssapiauthentication", oUnsupported },
195 { "gssapidelegatecredentials", oUnsupported },
197 { "fallbacktorsh", oDeprecated },
198 { "usersh", oDeprecated },
199 { "identityfile", oIdentityFile },
200 { "identityfile2", oIdentityFile }, /* obsolete */
201 { "identitiesonly", oIdentitiesOnly },
202 { "hostname", oHostName },
203 { "hostkeyalias", oHostKeyAlias },
204 { "proxycommand", oProxyCommand },
206 { "cipher", oCipher },
207 { "ciphers", oCiphers },
209 { "protocol", oProtocol },
210 { "remoteforward", oRemoteForward },
211 { "localforward", oLocalForward },
215 { "escapechar", oEscapeChar },
216 { "globalknownhostsfile", oGlobalKnownHostsFile },
217 { "globalknownhostsfile2", oDeprecated },
218 { "userknownhostsfile", oUserKnownHostsFile },
219 { "userknownhostsfile2", oDeprecated },
220 { "connectionattempts", oConnectionAttempts },
221 { "batchmode", oBatchMode },
222 { "checkhostip", oCheckHostIP },
223 { "stricthostkeychecking", oStrictHostKeyChecking },
224 { "compression", oCompression },
225 { "compressionlevel", oCompressionLevel },
226 { "tcpkeepalive", oTCPKeepAlive },
227 { "keepalive", oTCPKeepAlive }, /* obsolete */
228 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
229 { "loglevel", oLogLevel },
230 { "dynamicforward", oDynamicForward },
231 { "preferredauthentications", oPreferredAuthentications },
232 { "hostkeyalgorithms", oHostKeyAlgorithms },
233 { "bindaddress", oBindAddress },
235 { "smartcarddevice", oPKCS11Provider },
236 { "pkcs11provider", oPKCS11Provider },
238 { "smartcarddevice", oUnsupported },
239 { "pkcs11provider", oUnsupported },
241 { "clearallforwardings", oClearAllForwardings },
242 { "enablesshkeysign", oEnableSSHKeysign },
243 { "verifyhostkeydns", oVerifyHostKeyDNS },
244 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
245 { "rekeylimit", oRekeyLimit },
246 { "connecttimeout", oConnectTimeout },
247 { "addressfamily", oAddressFamily },
248 { "serveraliveinterval", oServerAliveInterval },
249 { "serveralivecountmax", oServerAliveCountMax },
250 { "versionaddendum", oVersionAddendum },
251 { "sendenv", oSendEnv },
252 { "controlpath", oControlPath },
253 { "controlmaster", oControlMaster },
254 { "controlpersist", oControlPersist },
255 { "hashknownhosts", oHashKnownHosts },
256 { "tunnel", oTunnel },
257 { "tunneldevice", oTunnelDevice },
258 { "localcommand", oLocalCommand },
259 { "permitlocalcommand", oPermitLocalCommand },
260 { "visualhostkey", oVisualHostKey },
261 { "useroaming", oUseRoaming },
262 { "kexalgorithms", oKexAlgorithms },
264 { "requesttty", oRequestTTY },
265 { "noneenabled", oNoneEnabled },
266 { "noneswitch", oNoneSwitch },
267 { "tcprcvbufpoll", oTcpRcvBufPoll },
268 { "tcprcvbuf", oTcpRcvBuf },
269 { "hpndisabled", oHPNDisabled },
270 { "hpnbuffersize", oHPNBufferSize },
271 { "proxyusefdpass", oProxyUseFdpass },
272 { "canonicaldomains", oCanonicalDomains },
273 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
274 { "canonicalizehostname", oCanonicalizeHostname },
275 { "canonicalizemaxdots", oCanonicalizeMaxDots },
276 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
277 { "streamlocalbindmask", oStreamLocalBindMask },
278 { "streamlocalbindunlink", oStreamLocalBindUnlink },
279 { "ignoreunknown", oIgnoreUnknown },
285 * Adds a local TCP/IP port forward to options. Never returns if there is an
290 add_local_forward(Options *options, const struct Forward *newfwd)
293 #ifndef NO_IPPORT_RESERVED_CONCEPT
294 extern uid_t original_real_uid;
295 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
296 newfwd->listen_path == NULL)
297 fatal("Privileged ports can only be forwarded by root.");
299 options->local_forwards = xrealloc(options->local_forwards,
300 options->num_local_forwards + 1,
301 sizeof(*options->local_forwards));
302 fwd = &options->local_forwards[options->num_local_forwards++];
304 fwd->listen_host = newfwd->listen_host;
305 fwd->listen_port = newfwd->listen_port;
306 fwd->listen_path = newfwd->listen_path;
307 fwd->connect_host = newfwd->connect_host;
308 fwd->connect_port = newfwd->connect_port;
309 fwd->connect_path = newfwd->connect_path;
313 * Adds a remote TCP/IP port forward to options. Never returns if there is
318 add_remote_forward(Options *options, const struct Forward *newfwd)
322 options->remote_forwards = xrealloc(options->remote_forwards,
323 options->num_remote_forwards + 1,
324 sizeof(*options->remote_forwards));
325 fwd = &options->remote_forwards[options->num_remote_forwards++];
327 fwd->listen_host = newfwd->listen_host;
328 fwd->listen_port = newfwd->listen_port;
329 fwd->listen_path = newfwd->listen_path;
330 fwd->connect_host = newfwd->connect_host;
331 fwd->connect_port = newfwd->connect_port;
332 fwd->connect_path = newfwd->connect_path;
333 fwd->handle = newfwd->handle;
334 fwd->allocated_port = 0;
338 clear_forwardings(Options *options)
342 for (i = 0; i < options->num_local_forwards; i++) {
343 free(options->local_forwards[i].listen_host);
344 free(options->local_forwards[i].listen_path);
345 free(options->local_forwards[i].connect_host);
346 free(options->local_forwards[i].connect_path);
348 if (options->num_local_forwards > 0) {
349 free(options->local_forwards);
350 options->local_forwards = NULL;
352 options->num_local_forwards = 0;
353 for (i = 0; i < options->num_remote_forwards; i++) {
354 free(options->remote_forwards[i].listen_host);
355 free(options->remote_forwards[i].listen_path);
356 free(options->remote_forwards[i].connect_host);
357 free(options->remote_forwards[i].connect_path);
359 if (options->num_remote_forwards > 0) {
360 free(options->remote_forwards);
361 options->remote_forwards = NULL;
363 options->num_remote_forwards = 0;
364 options->tun_open = SSH_TUNMODE_NO;
368 add_identity_file(Options *options, const char *dir, const char *filename,
374 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
375 fatal("Too many identity files specified (max %d)",
376 SSH_MAX_IDENTITY_FILES);
378 if (dir == NULL) /* no dir, filename is absolute */
379 path = xstrdup(filename);
381 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
383 /* Avoid registering duplicates */
384 for (i = 0; i < options->num_identity_files; i++) {
385 if (options->identity_file_userprovided[i] == userprovided &&
386 strcmp(options->identity_files[i], path) == 0) {
387 debug2("%s: ignoring duplicate key %s", __func__, path);
393 options->identity_file_userprovided[options->num_identity_files] =
395 options->identity_files[options->num_identity_files++] = path;
399 default_ssh_port(void)
405 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
406 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
412 * Execute a command in a shell.
413 * Return its exit status or -1 on abnormal exit.
416 execute_in_shell(const char *cmd)
418 char *shell, *command_string;
421 extern uid_t original_real_uid;
423 if ((shell = getenv("SHELL")) == NULL)
424 shell = _PATH_BSHELL;
427 * Use "exec" to avoid "sh -c" processes on some platforms
430 xasprintf(&command_string, "exec %s", cmd);
432 /* Need this to redirect subprocess stdin/out */
433 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
434 fatal("open(/dev/null): %s", strerror(errno));
436 debug("Executing command: '%.500s'", cmd);
438 /* Fork and execute the command. */
439 if ((pid = fork()) == 0) {
442 /* Child. Permanently give up superuser privileges. */
443 permanently_drop_suid(original_real_uid);
445 /* Redirect child stdin and stdout. Leave stderr */
446 if (dup2(devnull, STDIN_FILENO) == -1)
447 fatal("dup2: %s", strerror(errno));
448 if (dup2(devnull, STDOUT_FILENO) == -1)
449 fatal("dup2: %s", strerror(errno));
450 if (devnull > STDERR_FILENO)
452 closefrom(STDERR_FILENO + 1);
456 argv[2] = command_string;
459 execv(argv[0], argv);
460 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
461 /* Die with signal to make this error apparent to parent. */
462 signal(SIGTERM, SIG_DFL);
463 kill(getpid(), SIGTERM);
468 fatal("%s: fork: %.100s", __func__, strerror(errno));
471 free(command_string);
473 while (waitpid(pid, &status, 0) == -1) {
474 if (errno != EINTR && errno != EAGAIN)
475 fatal("%s: waitpid: %s", __func__, strerror(errno));
477 if (!WIFEXITED(status)) {
478 error("command '%.100s' exited abnormally", cmd);
481 debug3("command returned status %d", WEXITSTATUS(status));
482 return WEXITSTATUS(status);
486 * Parse and execute a Match directive.
489 match_cfg_line(Options *options, char **condition, struct passwd *pw,
490 const char *host_arg, const char *filename, int linenum)
492 char *arg, *attrib, *cmd, *cp = *condition, *host;
494 int r, port, result = 1, attributes = 0;
496 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
499 * Configuration is likely to be incomplete at this point so we
500 * must be prepared to use default values.
502 port = options->port <= 0 ? default_ssh_port() : options->port;
503 ruser = options->user == NULL ? pw->pw_name : options->user;
504 if (options->hostname != NULL) {
505 /* NB. Please keep in sync with ssh.c:main() */
506 host = percent_expand(options->hostname,
507 "h", host_arg, (char *)NULL);
509 host = xstrdup(host_arg);
511 debug3("checking match for '%s' host %s", cp, host);
512 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
514 if (strcasecmp(attrib, "all") == 0) {
515 if (attributes != 1 ||
516 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
517 error("'all' cannot be combined with other "
526 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
527 error("Missing Match criteria for %s", attrib);
532 if (strcasecmp(attrib, "host") == 0) {
533 if (match_hostname(host, arg, len) != 1)
536 debug("%.200s line %d: matched 'Host %.100s' ",
537 filename, linenum, host);
538 } else if (strcasecmp(attrib, "originalhost") == 0) {
539 if (match_hostname(host_arg, arg, len) != 1)
542 debug("%.200s line %d: matched "
543 "'OriginalHost %.100s' ",
544 filename, linenum, host_arg);
545 } else if (strcasecmp(attrib, "user") == 0) {
546 if (match_pattern_list(ruser, arg, len, 0) != 1)
549 debug("%.200s line %d: matched 'User %.100s' ",
550 filename, linenum, ruser);
551 } else if (strcasecmp(attrib, "localuser") == 0) {
552 if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
555 debug("%.200s line %d: matched "
556 "'LocalUser %.100s' ",
557 filename, linenum, pw->pw_name);
558 } else if (strcasecmp(attrib, "exec") == 0) {
559 if (gethostname(thishost, sizeof(thishost)) == -1)
560 fatal("gethostname: %s", strerror(errno));
561 strlcpy(shorthost, thishost, sizeof(shorthost));
562 shorthost[strcspn(thishost, ".")] = '\0';
563 snprintf(portstr, sizeof(portstr), "%d", port);
565 cmd = percent_expand(arg,
576 /* skip execution if prior predicate failed */
577 debug("%.200s line %d: skipped exec \"%.100s\"",
578 filename, linenum, cmd);
580 r = execute_in_shell(cmd);
582 fatal("%.200s line %d: match exec "
583 "'%.100s' error", filename,
586 debug("%.200s line %d: matched "
587 "'exec \"%.100s\"'", filename,
590 debug("%.200s line %d: no match "
591 "'exec \"%.100s\"'", filename,
598 error("Unsupported Match attribute %s", attrib);
603 if (attributes == 0) {
604 error("One or more attributes required for Match");
608 debug3("match %sfound", result ? "" : "not ");
615 /* Check and prepare a domain name: removes trailing '.' and lowercases */
617 valid_domain(char *name, const char *filename, int linenum)
619 size_t i, l = strlen(name);
620 u_char c, last = '\0';
623 fatal("%s line %d: empty hostname suffix", filename, linenum);
624 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
625 fatal("%s line %d: hostname suffix \"%.100s\" "
626 "starts with invalid character", filename, linenum, name);
627 for (i = 0; i < l; i++) {
628 c = tolower((u_char)name[i]);
630 if (last == '.' && c == '.')
631 fatal("%s line %d: hostname suffix \"%.100s\" contains "
632 "consecutive separators", filename, linenum, name);
633 if (c != '.' && c != '-' && !isalnum(c) &&
634 c != '_') /* technically invalid, but common */
635 fatal("%s line %d: hostname suffix \"%.100s\" contains "
636 "invalid characters", filename, linenum, name);
639 if (name[l - 1] == '.')
644 * Returns the number of the token pointed to by cp or oBadOption.
647 parse_token(const char *cp, const char *filename, int linenum,
648 const char *ignored_unknown)
652 for (i = 0; keywords[i].name; i++)
653 if (strcmp(cp, keywords[i].name) == 0)
654 return keywords[i].opcode;
655 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
656 strlen(ignored_unknown), 1) == 1)
657 return oIgnoredUnknownOption;
658 error("%s: line %d: Bad configuration option: %s",
659 filename, linenum, cp);
663 /* Multistate option parsing */
668 static const struct multistate multistate_flag[] = {
675 static const struct multistate multistate_yesnoask[] = {
683 static const struct multistate multistate_addressfamily[] = {
685 { "inet6", AF_INET6 },
686 { "any", AF_UNSPEC },
689 static const struct multistate multistate_controlmaster[] = {
690 { "true", SSHCTL_MASTER_YES },
691 { "yes", SSHCTL_MASTER_YES },
692 { "false", SSHCTL_MASTER_NO },
693 { "no", SSHCTL_MASTER_NO },
694 { "auto", SSHCTL_MASTER_AUTO },
695 { "ask", SSHCTL_MASTER_ASK },
696 { "autoask", SSHCTL_MASTER_AUTO_ASK },
699 static const struct multistate multistate_tunnel[] = {
700 { "ethernet", SSH_TUNMODE_ETHERNET },
701 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
702 { "true", SSH_TUNMODE_DEFAULT },
703 { "yes", SSH_TUNMODE_DEFAULT },
704 { "false", SSH_TUNMODE_NO },
705 { "no", SSH_TUNMODE_NO },
708 static const struct multistate multistate_requesttty[] = {
709 { "true", REQUEST_TTY_YES },
710 { "yes", REQUEST_TTY_YES },
711 { "false", REQUEST_TTY_NO },
712 { "no", REQUEST_TTY_NO },
713 { "force", REQUEST_TTY_FORCE },
714 { "auto", REQUEST_TTY_AUTO },
717 static const struct multistate multistate_canonicalizehostname[] = {
718 { "true", SSH_CANONICALISE_YES },
719 { "false", SSH_CANONICALISE_NO },
720 { "yes", SSH_CANONICALISE_YES },
721 { "no", SSH_CANONICALISE_NO },
722 { "always", SSH_CANONICALISE_ALWAYS },
727 * Processes a single option line as used in the configuration files. This
728 * only sets those values that have not already been set.
730 #define WHITESPACE " \t\r\n"
732 process_config_line(Options *options, struct passwd *pw, const char *host,
733 char *line, const char *filename, int linenum, int *activep, int userconfig)
735 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
736 char **cpptr, fwdarg[256];
737 u_int i, *uintptr, max_entries = 0;
738 int negated, opcode, *intptr, value, value2, cmdline = 0;
739 LogLevel *log_level_ptr;
743 const struct multistate *multistate_ptr;
744 struct allowed_cname *cname;
746 if (activep == NULL) { /* We are processing a command line directive */
751 /* Strip trailing whitespace */
752 for (len = strlen(line) - 1; len > 0; len--) {
753 if (strchr(WHITESPACE, line[len]) == NULL)
759 /* Get the keyword. (Each line is supposed to begin with a keyword). */
760 if ((keyword = strdelim(&s)) == NULL)
762 /* Ignore leading whitespace. */
763 if (*keyword == '\0')
764 keyword = strdelim(&s);
765 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
767 /* Match lowercase keyword */
770 opcode = parse_token(keyword, filename, linenum,
771 options->ignored_unknown);
775 /* don't panic, but count bad options */
778 case oIgnoredUnknownOption:
779 debug("%s line %d: Ignored unknown option \"%s\"",
780 filename, linenum, keyword);
782 case oConnectTimeout:
783 intptr = &options->connection_timeout;
786 if (!arg || *arg == '\0')
787 fatal("%s line %d: missing time value.",
789 if ((value = convtime(arg)) == -1)
790 fatal("%s line %d: invalid time value.",
792 if (*activep && *intptr == -1)
797 intptr = &options->forward_agent;
799 multistate_ptr = multistate_flag;
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: missing argument.",
806 for (i = 0; multistate_ptr[i].key != NULL; i++) {
807 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
808 value = multistate_ptr[i].value;
813 fatal("%s line %d: unsupported option \"%s\".",
814 filename, linenum, arg);
815 if (*activep && *intptr == -1)
820 intptr = &options->forward_x11;
823 case oForwardX11Trusted:
824 intptr = &options->forward_x11_trusted;
827 case oForwardX11Timeout:
828 intptr = &options->forward_x11_timeout;
832 intptr = &options->fwd_opts.gateway_ports;
835 case oExitOnForwardFailure:
836 intptr = &options->exit_on_forward_failure;
839 case oUsePrivilegedPort:
840 intptr = &options->use_privileged_port;
843 case oPasswordAuthentication:
844 intptr = &options->password_authentication;
847 case oKbdInteractiveAuthentication:
848 intptr = &options->kbd_interactive_authentication;
851 case oKbdInteractiveDevices:
852 charptr = &options->kbd_interactive_devices;
855 case oPubkeyAuthentication:
856 intptr = &options->pubkey_authentication;
859 case oRSAAuthentication:
860 intptr = &options->rsa_authentication;
863 case oRhostsRSAAuthentication:
864 intptr = &options->rhosts_rsa_authentication;
867 case oHostbasedAuthentication:
868 intptr = &options->hostbased_authentication;
871 case oChallengeResponseAuthentication:
872 intptr = &options->challenge_response_authentication;
875 case oGssAuthentication:
876 intptr = &options->gss_authentication;
879 case oGssDelegateCreds:
880 intptr = &options->gss_deleg_creds;
884 intptr = &options->batch_mode;
888 intptr = &options->check_host_ip;
892 intptr = &options->none_enabled;
895 /* we check to see if the command comes from the */
896 /* command line or not. If it does then enable it */
897 /* otherwise fail. NONE should never be a default configuration */
899 if(strcmp(filename,"command-line")==0)
901 intptr = &options->none_switch;
904 error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
905 error("Continuing...");
906 debug("NoneSwitch directive found in %.200s.", filename);
911 intptr = &options->hpn_disabled;
915 intptr = &options->hpn_buffer_size;
919 intptr = &options->tcp_rcv_buf_poll;
922 case oVerifyHostKeyDNS:
923 intptr = &options->verify_host_key_dns;
924 multistate_ptr = multistate_yesnoask;
925 goto parse_multistate;
927 case oStrictHostKeyChecking:
928 intptr = &options->strict_host_key_checking;
929 multistate_ptr = multistate_yesnoask;
930 goto parse_multistate;
933 intptr = &options->compression;
937 intptr = &options->tcp_keep_alive;
940 case oNoHostAuthenticationForLocalhost:
941 intptr = &options->no_host_authentication_for_localhost;
944 case oNumberOfPasswordPrompts:
945 intptr = &options->number_of_password_prompts;
948 case oCompressionLevel:
949 intptr = &options->compression_level;
954 if (!arg || *arg == '\0')
955 fatal("%.200s line %d: Missing argument.", filename,
957 if (strcmp(arg, "default") == 0) {
960 if (scan_scaled(arg, &val64) == -1)
961 fatal("%.200s line %d: Bad number '%s': %s",
962 filename, linenum, arg, strerror(errno));
963 /* check for too-large or too-small limits */
964 if (val64 > UINT_MAX)
965 fatal("%.200s line %d: RekeyLimit too large",
967 if (val64 != 0 && val64 < 16)
968 fatal("%.200s line %d: RekeyLimit too small",
971 if (*activep && options->rekey_limit == -1)
972 options->rekey_limit = (u_int32_t)val64;
973 if (s != NULL) { /* optional rekey interval present */
974 if (strcmp(s, "none") == 0) {
975 (void)strdelim(&s); /* discard */
978 intptr = &options->rekey_interval;
985 if (!arg || *arg == '\0')
986 fatal("%.200s line %d: Missing argument.", filename, linenum);
988 intptr = &options->num_identity_files;
989 if (*intptr >= SSH_MAX_IDENTITY_FILES)
990 fatal("%.200s line %d: Too many identity files specified (max %d).",
991 filename, linenum, SSH_MAX_IDENTITY_FILES);
992 add_identity_file(options, NULL, arg, userconfig);
997 charptr=&options->xauth_location;
1001 charptr = &options->user;
1004 if (!arg || *arg == '\0')
1005 fatal("%.200s line %d: Missing argument.",
1007 if (*activep && *charptr == NULL)
1008 *charptr = xstrdup(arg);
1011 case oGlobalKnownHostsFile:
1012 cpptr = (char **)&options->system_hostfiles;
1013 uintptr = &options->num_system_hostfiles;
1014 max_entries = SSH_MAX_HOSTS_FILES;
1016 if (*activep && *uintptr == 0) {
1017 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1018 if ((*uintptr) >= max_entries)
1019 fatal("%s line %d: "
1020 "too many authorized keys files.",
1022 cpptr[(*uintptr)++] = xstrdup(arg);
1027 case oUserKnownHostsFile:
1028 cpptr = (char **)&options->user_hostfiles;
1029 uintptr = &options->num_user_hostfiles;
1030 max_entries = SSH_MAX_HOSTS_FILES;
1031 goto parse_char_array;
1034 charptr = &options->hostname;
1038 charptr = &options->host_key_alias;
1041 case oPreferredAuthentications:
1042 charptr = &options->preferred_authentications;
1046 charptr = &options->bind_address;
1049 case oPKCS11Provider:
1050 charptr = &options->pkcs11_provider;
1054 charptr = &options->proxy_command;
1057 fatal("%.200s line %d: Missing argument.", filename, linenum);
1058 len = strspn(s, WHITESPACE "=");
1059 if (*activep && *charptr == NULL)
1060 *charptr = xstrdup(s + len);
1064 intptr = &options->port;
1067 if (!arg || *arg == '\0')
1068 fatal("%.200s line %d: Missing argument.", filename, linenum);
1069 if (arg[0] < '0' || arg[0] > '9')
1070 fatal("%.200s line %d: Bad number.", filename, linenum);
1072 /* Octal, decimal, or hex format? */
1073 value = strtol(arg, &endofnumber, 0);
1074 if (arg == endofnumber)
1075 fatal("%.200s line %d: Bad number.", filename, linenum);
1076 if (*activep && *intptr == -1)
1080 case oConnectionAttempts:
1081 intptr = &options->connection_attempts;
1085 intptr = &options->tcp_rcv_buf;
1089 intptr = &options->cipher;
1091 if (!arg || *arg == '\0')
1092 fatal("%.200s line %d: Missing argument.", filename, linenum);
1093 value = cipher_number(arg);
1095 fatal("%.200s line %d: Bad cipher '%s'.",
1096 filename, linenum, arg ? arg : "<NONE>");
1097 if (*activep && *intptr == -1)
1103 if (!arg || *arg == '\0')
1104 fatal("%.200s line %d: Missing argument.", filename, linenum);
1105 if (!ciphers_valid(arg))
1106 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1107 filename, linenum, arg ? arg : "<NONE>");
1108 if (*activep && options->ciphers == NULL)
1109 options->ciphers = xstrdup(arg);
1114 if (!arg || *arg == '\0')
1115 fatal("%.200s line %d: Missing argument.", filename, linenum);
1116 if (!mac_valid(arg))
1117 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1118 filename, linenum, arg ? arg : "<NONE>");
1119 if (*activep && options->macs == NULL)
1120 options->macs = xstrdup(arg);
1123 case oKexAlgorithms:
1125 if (!arg || *arg == '\0')
1126 fatal("%.200s line %d: Missing argument.",
1128 if (!kex_names_valid(arg))
1129 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1130 filename, linenum, arg ? arg : "<NONE>");
1131 if (*activep && options->kex_algorithms == NULL)
1132 options->kex_algorithms = xstrdup(arg);
1135 case oHostKeyAlgorithms:
1137 if (!arg || *arg == '\0')
1138 fatal("%.200s line %d: Missing argument.", filename, linenum);
1139 if (!key_names_valid2(arg))
1140 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1141 filename, linenum, arg ? arg : "<NONE>");
1142 if (*activep && options->hostkeyalgorithms == NULL)
1143 options->hostkeyalgorithms = xstrdup(arg);
1147 intptr = &options->protocol;
1149 if (!arg || *arg == '\0')
1150 fatal("%.200s line %d: Missing argument.", filename, linenum);
1151 value = proto_spec(arg);
1152 if (value == SSH_PROTO_UNKNOWN)
1153 fatal("%.200s line %d: Bad protocol spec '%s'.",
1154 filename, linenum, arg ? arg : "<NONE>");
1155 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1160 log_level_ptr = &options->log_level;
1162 value = log_level_number(arg);
1163 if (value == SYSLOG_LEVEL_NOT_SET)
1164 fatal("%.200s line %d: unsupported log level '%s'",
1165 filename, linenum, arg ? arg : "<NONE>");
1166 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1167 *log_level_ptr = (LogLevel) value;
1171 case oRemoteForward:
1172 case oDynamicForward:
1174 if (arg == NULL || *arg == '\0')
1175 fatal("%.200s line %d: Missing port argument.",
1178 if (opcode == oLocalForward ||
1179 opcode == oRemoteForward) {
1180 arg2 = strdelim(&s);
1181 if (arg2 == NULL || *arg2 == '\0')
1182 fatal("%.200s line %d: Missing target argument.",
1185 /* construct a string for parse_forward */
1186 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1187 } else if (opcode == oDynamicForward) {
1188 strlcpy(fwdarg, arg, sizeof(fwdarg));
1191 if (parse_forward(&fwd, fwdarg,
1192 opcode == oDynamicForward ? 1 : 0,
1193 opcode == oRemoteForward ? 1 : 0) == 0)
1194 fatal("%.200s line %d: Bad forwarding specification.",
1198 if (opcode == oLocalForward ||
1199 opcode == oDynamicForward)
1200 add_local_forward(options, &fwd);
1201 else if (opcode == oRemoteForward)
1202 add_remote_forward(options, &fwd);
1206 case oClearAllForwardings:
1207 intptr = &options->clear_forwardings;
1212 fatal("Host directive not supported as a command-line "
1216 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1217 negated = *arg == '!';
1220 if (match_pattern(host, arg)) {
1222 debug("%.200s line %d: Skipping Host "
1223 "block because of negated match "
1224 "for %.100s", filename, linenum,
1230 arg2 = arg; /* logged below */
1235 debug("%.200s line %d: Applying options for %.100s",
1236 filename, linenum, arg2);
1237 /* Avoid garbage check below, as strdelim is done. */
1242 fatal("Host directive not supported as a command-line "
1244 value = match_cfg_line(options, &s, pw, host,
1247 fatal("%.200s line %d: Bad Match condition", filename,
1253 intptr = &options->escape_char;
1255 if (!arg || *arg == '\0')
1256 fatal("%.200s line %d: Missing argument.", filename, linenum);
1257 if (arg[0] == '^' && arg[2] == 0 &&
1258 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1259 value = (u_char) arg[1] & 31;
1260 else if (strlen(arg) == 1)
1261 value = (u_char) arg[0];
1262 else if (strcmp(arg, "none") == 0)
1263 value = SSH_ESCAPECHAR_NONE;
1265 fatal("%.200s line %d: Bad escape character.",
1268 value = 0; /* Avoid compiler warning. */
1270 if (*activep && *intptr == -1)
1274 case oAddressFamily:
1275 intptr = &options->address_family;
1276 multistate_ptr = multistate_addressfamily;
1277 goto parse_multistate;
1279 case oEnableSSHKeysign:
1280 intptr = &options->enable_ssh_keysign;
1283 case oIdentitiesOnly:
1284 intptr = &options->identities_only;
1287 case oServerAliveInterval:
1288 intptr = &options->server_alive_interval;
1291 case oServerAliveCountMax:
1292 intptr = &options->server_alive_count_max;
1295 case oVersionAddendum:
1296 ssh_version_set_addendum(strtok(s, "\n"));
1299 } while (arg != NULL && *arg != '\0');
1303 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1304 if (strchr(arg, '=') != NULL)
1305 fatal("%s line %d: Invalid environment name.",
1309 if (options->num_send_env >= MAX_SEND_ENV)
1310 fatal("%s line %d: too many send env.",
1312 options->send_env[options->num_send_env++] =
1318 charptr = &options->control_path;
1321 case oControlMaster:
1322 intptr = &options->control_master;
1323 multistate_ptr = multistate_controlmaster;
1324 goto parse_multistate;
1326 case oControlPersist:
1327 /* no/false/yes/true, or a time spec */
1328 intptr = &options->control_persist;
1330 if (!arg || *arg == '\0')
1331 fatal("%.200s line %d: Missing ControlPersist"
1332 " argument.", filename, linenum);
1334 value2 = 0; /* timeout */
1335 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1337 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1339 else if ((value2 = convtime(arg)) >= 0)
1342 fatal("%.200s line %d: Bad ControlPersist argument.",
1344 if (*activep && *intptr == -1) {
1346 options->control_persist_timeout = value2;
1350 case oHashKnownHosts:
1351 intptr = &options->hash_known_hosts;
1355 intptr = &options->tun_open;
1356 multistate_ptr = multistate_tunnel;
1357 goto parse_multistate;
1361 if (!arg || *arg == '\0')
1362 fatal("%.200s line %d: Missing argument.", filename, linenum);
1363 value = a2tun(arg, &value2);
1364 if (value == SSH_TUNID_ERR)
1365 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1367 options->tun_local = value;
1368 options->tun_remote = value2;
1373 charptr = &options->local_command;
1376 case oPermitLocalCommand:
1377 intptr = &options->permit_local_command;
1380 case oVisualHostKey:
1381 intptr = &options->visual_host_key;
1386 if ((value = parse_ipqos(arg)) == -1)
1387 fatal("%s line %d: Bad IPQoS value: %s",
1388 filename, linenum, arg);
1392 else if ((value2 = parse_ipqos(arg)) == -1)
1393 fatal("%s line %d: Bad IPQoS value: %s",
1394 filename, linenum, arg);
1396 options->ip_qos_interactive = value;
1397 options->ip_qos_bulk = value2;
1402 intptr = &options->use_roaming;
1406 intptr = &options->request_tty;
1407 multistate_ptr = multistate_requesttty;
1408 goto parse_multistate;
1410 case oIgnoreUnknown:
1411 charptr = &options->ignored_unknown;
1414 case oProxyUseFdpass:
1415 intptr = &options->proxy_use_fdpass;
1418 case oCanonicalDomains:
1419 value = options->num_canonical_domains != 0;
1420 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1421 valid_domain(arg, filename, linenum);
1422 if (!*activep || value)
1424 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1425 fatal("%s line %d: too many hostname suffixes.",
1427 options->canonical_domains[
1428 options->num_canonical_domains++] = xstrdup(arg);
1432 case oCanonicalizePermittedCNAMEs:
1433 value = options->num_permitted_cnames != 0;
1434 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1435 /* Either '*' for everything or 'list:list' */
1436 if (strcmp(arg, "*") == 0)
1440 if ((arg2 = strchr(arg, ':')) == NULL ||
1442 fatal("%s line %d: "
1443 "Invalid permitted CNAME \"%s\"",
1444 filename, linenum, arg);
1449 if (!*activep || value)
1451 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1452 fatal("%s line %d: too many permitted CNAMEs.",
1454 cname = options->permitted_cnames +
1455 options->num_permitted_cnames++;
1456 cname->source_list = xstrdup(arg);
1457 cname->target_list = xstrdup(arg2);
1461 case oCanonicalizeHostname:
1462 intptr = &options->canonicalize_hostname;
1463 multistate_ptr = multistate_canonicalizehostname;
1464 goto parse_multistate;
1466 case oCanonicalizeMaxDots:
1467 intptr = &options->canonicalize_max_dots;
1470 case oCanonicalizeFallbackLocal:
1471 intptr = &options->canonicalize_fallback_local;
1474 case oStreamLocalBindMask:
1476 if (!arg || *arg == '\0')
1477 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1478 /* Parse mode in octal format */
1479 value = strtol(arg, &endofnumber, 8);
1480 if (arg == endofnumber || value < 0 || value > 0777)
1481 fatal("%.200s line %d: Bad mask.", filename, linenum);
1482 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1485 case oStreamLocalBindUnlink:
1486 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1490 debug("%s line %d: Deprecated option \"%s\"",
1491 filename, linenum, keyword);
1495 error("%s line %d: Unsupported option \"%s\"",
1496 filename, linenum, keyword);
1500 fatal("process_config_line: Unimplemented opcode %d", opcode);
1503 /* Check that there is no garbage at end of line. */
1504 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1505 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1506 filename, linenum, arg);
1513 * Reads the config file and modifies the options accordingly. Options
1514 * should already be initialized before this call. This never returns if
1515 * there is an error. If the file does not exist, this returns 0.
1519 read_config_file(const char *filename, struct passwd *pw, const char *host,
1520 Options *options, int flags)
1524 int active, linenum;
1525 int bad_options = 0;
1527 if ((f = fopen(filename, "r")) == NULL)
1530 if (flags & SSHCONF_CHECKPERM) {
1533 if (fstat(fileno(f), &sb) == -1)
1534 fatal("fstat %s: %s", filename, strerror(errno));
1535 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1536 (sb.st_mode & 022) != 0))
1537 fatal("Bad owner or permissions on %s", filename);
1540 debug("Reading configuration data %.200s", filename);
1543 * Mark that we are now processing the options. This flag is turned
1544 * on/off by Host specifications.
1548 while (fgets(line, sizeof(line), f)) {
1549 /* Update line number counter. */
1551 if (process_config_line(options, pw, host, line, filename,
1552 linenum, &active, flags & SSHCONF_USERCONF) != 0)
1556 if (bad_options > 0)
1557 fatal("%s: terminating, %d bad configuration options",
1558 filename, bad_options);
1562 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1564 option_clear_or_none(const char *o)
1566 return o == NULL || strcasecmp(o, "none") == 0;
1570 * Initializes options to special values that indicate that they have not yet
1571 * been set. Read_config_file will only set options with this value. Options
1572 * are processed in the following order: command line, user config file,
1573 * system config file. Last, fill_default_options is called.
1577 initialize_options(Options * options)
1579 memset(options, 'X', sizeof(*options));
1580 options->forward_agent = -1;
1581 options->forward_x11 = -1;
1582 options->forward_x11_trusted = -1;
1583 options->forward_x11_timeout = -1;
1584 options->exit_on_forward_failure = -1;
1585 options->xauth_location = NULL;
1586 options->fwd_opts.gateway_ports = -1;
1587 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1588 options->fwd_opts.streamlocal_bind_unlink = -1;
1589 options->use_privileged_port = -1;
1590 options->rsa_authentication = -1;
1591 options->pubkey_authentication = -1;
1592 options->challenge_response_authentication = -1;
1593 options->gss_authentication = -1;
1594 options->gss_deleg_creds = -1;
1595 options->password_authentication = -1;
1596 options->kbd_interactive_authentication = -1;
1597 options->kbd_interactive_devices = NULL;
1598 options->rhosts_rsa_authentication = -1;
1599 options->hostbased_authentication = -1;
1600 options->batch_mode = -1;
1601 options->check_host_ip = -1;
1602 options->strict_host_key_checking = -1;
1603 options->compression = -1;
1604 options->tcp_keep_alive = -1;
1605 options->compression_level = -1;
1607 options->address_family = -1;
1608 options->connection_attempts = -1;
1609 options->connection_timeout = -1;
1610 options->number_of_password_prompts = -1;
1611 options->cipher = -1;
1612 options->ciphers = NULL;
1613 options->macs = NULL;
1614 options->kex_algorithms = NULL;
1615 options->hostkeyalgorithms = NULL;
1616 options->protocol = SSH_PROTO_UNKNOWN;
1617 options->num_identity_files = 0;
1618 options->hostname = NULL;
1619 options->host_key_alias = NULL;
1620 options->proxy_command = NULL;
1621 options->user = NULL;
1622 options->escape_char = -1;
1623 options->num_system_hostfiles = 0;
1624 options->num_user_hostfiles = 0;
1625 options->local_forwards = NULL;
1626 options->num_local_forwards = 0;
1627 options->remote_forwards = NULL;
1628 options->num_remote_forwards = 0;
1629 options->clear_forwardings = -1;
1630 options->log_level = SYSLOG_LEVEL_NOT_SET;
1631 options->preferred_authentications = NULL;
1632 options->bind_address = NULL;
1633 options->pkcs11_provider = NULL;
1634 options->enable_ssh_keysign = - 1;
1635 options->no_host_authentication_for_localhost = - 1;
1636 options->identities_only = - 1;
1637 options->rekey_limit = - 1;
1638 options->rekey_interval = -1;
1639 options->verify_host_key_dns = -1;
1640 options->server_alive_interval = -1;
1641 options->server_alive_count_max = -1;
1642 options->num_send_env = 0;
1643 options->control_path = NULL;
1644 options->control_master = -1;
1645 options->control_persist = -1;
1646 options->control_persist_timeout = 0;
1647 options->hash_known_hosts = -1;
1648 options->tun_open = -1;
1649 options->tun_local = -1;
1650 options->tun_remote = -1;
1651 options->local_command = NULL;
1652 options->permit_local_command = -1;
1653 options->use_roaming = -1;
1654 options->visual_host_key = -1;
1655 options->ip_qos_interactive = -1;
1656 options->ip_qos_bulk = -1;
1657 options->request_tty = -1;
1658 options->none_switch = -1;
1659 options->none_enabled = -1;
1660 options->hpn_disabled = -1;
1661 options->hpn_buffer_size = -1;
1662 options->tcp_rcv_buf_poll = -1;
1663 options->tcp_rcv_buf = -1;
1664 options->proxy_use_fdpass = -1;
1665 options->ignored_unknown = NULL;
1666 options->num_canonical_domains = 0;
1667 options->num_permitted_cnames = 0;
1668 options->canonicalize_max_dots = -1;
1669 options->canonicalize_fallback_local = -1;
1670 options->canonicalize_hostname = -1;
1674 * A petite version of fill_default_options() that just fills the options
1675 * needed for hostname canonicalization to proceed.
1678 fill_default_options_for_canonicalization(Options *options)
1680 if (options->canonicalize_max_dots == -1)
1681 options->canonicalize_max_dots = 1;
1682 if (options->canonicalize_fallback_local == -1)
1683 options->canonicalize_fallback_local = 1;
1684 if (options->canonicalize_hostname == -1)
1685 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1689 * Called after processing other sources of option data, this fills those
1690 * options for which no value has been specified with their default values.
1693 fill_default_options(Options * options)
1695 if (options->forward_agent == -1)
1696 options->forward_agent = 0;
1697 if (options->forward_x11 == -1)
1698 options->forward_x11 = 0;
1699 if (options->forward_x11_trusted == -1)
1700 options->forward_x11_trusted = 0;
1701 if (options->forward_x11_timeout == -1)
1702 options->forward_x11_timeout = 1200;
1703 if (options->exit_on_forward_failure == -1)
1704 options->exit_on_forward_failure = 0;
1705 if (options->xauth_location == NULL)
1706 options->xauth_location = _PATH_XAUTH;
1707 if (options->fwd_opts.gateway_ports == -1)
1708 options->fwd_opts.gateway_ports = 0;
1709 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1710 options->fwd_opts.streamlocal_bind_mask = 0177;
1711 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1712 options->fwd_opts.streamlocal_bind_unlink = 0;
1713 if (options->use_privileged_port == -1)
1714 options->use_privileged_port = 0;
1715 if (options->rsa_authentication == -1)
1716 options->rsa_authentication = 1;
1717 if (options->pubkey_authentication == -1)
1718 options->pubkey_authentication = 1;
1719 if (options->challenge_response_authentication == -1)
1720 options->challenge_response_authentication = 1;
1721 if (options->gss_authentication == -1)
1722 options->gss_authentication = 0;
1723 if (options->gss_deleg_creds == -1)
1724 options->gss_deleg_creds = 0;
1725 if (options->password_authentication == -1)
1726 options->password_authentication = 1;
1727 if (options->kbd_interactive_authentication == -1)
1728 options->kbd_interactive_authentication = 1;
1729 if (options->rhosts_rsa_authentication == -1)
1730 options->rhosts_rsa_authentication = 0;
1731 if (options->hostbased_authentication == -1)
1732 options->hostbased_authentication = 0;
1733 if (options->batch_mode == -1)
1734 options->batch_mode = 0;
1735 if (options->check_host_ip == -1)
1736 options->check_host_ip = 0;
1737 if (options->strict_host_key_checking == -1)
1738 options->strict_host_key_checking = 2; /* 2 is default */
1739 if (options->compression == -1)
1740 options->compression = 0;
1741 if (options->tcp_keep_alive == -1)
1742 options->tcp_keep_alive = 1;
1743 if (options->compression_level == -1)
1744 options->compression_level = 6;
1745 if (options->port == -1)
1746 options->port = 0; /* Filled in ssh_connect. */
1747 if (options->address_family == -1)
1748 options->address_family = AF_UNSPEC;
1749 if (options->connection_attempts == -1)
1750 options->connection_attempts = 1;
1751 if (options->number_of_password_prompts == -1)
1752 options->number_of_password_prompts = 3;
1753 /* Selected in ssh_login(). */
1754 if (options->cipher == -1)
1755 options->cipher = SSH_CIPHER_NOT_SET;
1756 /* options->ciphers, default set in myproposals.h */
1757 /* options->macs, default set in myproposals.h */
1758 /* options->kex_algorithms, default set in myproposals.h */
1759 /* options->hostkeyalgorithms, default set in myproposals.h */
1760 if (options->protocol == SSH_PROTO_UNKNOWN)
1761 options->protocol = SSH_PROTO_2;
1762 if (options->num_identity_files == 0) {
1763 if (options->protocol & SSH_PROTO_1) {
1764 add_identity_file(options, "~/",
1765 _PATH_SSH_CLIENT_IDENTITY, 0);
1767 if (options->protocol & SSH_PROTO_2) {
1768 add_identity_file(options, "~/",
1769 _PATH_SSH_CLIENT_ID_RSA, 0);
1770 add_identity_file(options, "~/",
1771 _PATH_SSH_CLIENT_ID_DSA, 0);
1772 #ifdef OPENSSL_HAS_ECC
1773 add_identity_file(options, "~/",
1774 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1776 add_identity_file(options, "~/",
1777 _PATH_SSH_CLIENT_ID_ED25519, 0);
1780 if (options->escape_char == -1)
1781 options->escape_char = '~';
1782 if (options->num_system_hostfiles == 0) {
1783 options->system_hostfiles[options->num_system_hostfiles++] =
1784 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1785 options->system_hostfiles[options->num_system_hostfiles++] =
1786 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1788 if (options->num_user_hostfiles == 0) {
1789 options->user_hostfiles[options->num_user_hostfiles++] =
1790 xstrdup(_PATH_SSH_USER_HOSTFILE);
1791 options->user_hostfiles[options->num_user_hostfiles++] =
1792 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1794 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1795 options->log_level = SYSLOG_LEVEL_INFO;
1796 if (options->clear_forwardings == 1)
1797 clear_forwardings(options);
1798 if (options->no_host_authentication_for_localhost == - 1)
1799 options->no_host_authentication_for_localhost = 0;
1800 if (options->identities_only == -1)
1801 options->identities_only = 0;
1802 if (options->enable_ssh_keysign == -1)
1803 options->enable_ssh_keysign = 0;
1804 if (options->rekey_limit == -1)
1805 options->rekey_limit = 0;
1806 if (options->rekey_interval == -1)
1807 options->rekey_interval = 0;
1808 if (options->verify_host_key_dns == -1)
1809 options->verify_host_key_dns = 0;
1810 if (options->server_alive_interval == -1)
1811 options->server_alive_interval = 0;
1812 if (options->server_alive_count_max == -1)
1813 options->server_alive_count_max = 3;
1814 if (options->none_switch == -1)
1815 options->none_switch = 0;
1816 if (options->hpn_disabled == -1)
1817 options->hpn_disabled = 0;
1818 if (options->hpn_buffer_size > -1)
1820 /* if a user tries to set the size to 0 set it to 1KB */
1821 if (options->hpn_buffer_size == 0)
1822 options->hpn_buffer_size = 1024;
1823 /*limit the buffer to 64MB*/
1824 if (options->hpn_buffer_size > 65536)
1826 options->hpn_buffer_size = 65536*1024;
1827 debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1829 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1831 if (options->tcp_rcv_buf == 0)
1832 options->tcp_rcv_buf = 1;
1833 if (options->tcp_rcv_buf > -1)
1834 options->tcp_rcv_buf *=1024;
1835 if (options->tcp_rcv_buf_poll == -1)
1836 options->tcp_rcv_buf_poll = 1;
1837 if (options->control_master == -1)
1838 options->control_master = 0;
1839 if (options->control_persist == -1) {
1840 options->control_persist = 0;
1841 options->control_persist_timeout = 0;
1843 if (options->hash_known_hosts == -1)
1844 options->hash_known_hosts = 0;
1845 if (options->tun_open == -1)
1846 options->tun_open = SSH_TUNMODE_NO;
1847 if (options->tun_local == -1)
1848 options->tun_local = SSH_TUNID_ANY;
1849 if (options->tun_remote == -1)
1850 options->tun_remote = SSH_TUNID_ANY;
1851 if (options->permit_local_command == -1)
1852 options->permit_local_command = 0;
1853 if (options->use_roaming == -1)
1854 options->use_roaming = 1;
1855 if (options->visual_host_key == -1)
1856 options->visual_host_key = 0;
1857 if (options->ip_qos_interactive == -1)
1858 options->ip_qos_interactive = IPTOS_LOWDELAY;
1859 if (options->ip_qos_bulk == -1)
1860 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1861 if (options->request_tty == -1)
1862 options->request_tty = REQUEST_TTY_AUTO;
1863 if (options->proxy_use_fdpass == -1)
1864 options->proxy_use_fdpass = 0;
1865 if (options->canonicalize_max_dots == -1)
1866 options->canonicalize_max_dots = 1;
1867 if (options->canonicalize_fallback_local == -1)
1868 options->canonicalize_fallback_local = 1;
1869 if (options->canonicalize_hostname == -1)
1870 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1871 #define CLEAR_ON_NONE(v) \
1873 if (option_clear_or_none(v)) { \
1878 CLEAR_ON_NONE(options->local_command);
1879 CLEAR_ON_NONE(options->proxy_command);
1880 CLEAR_ON_NONE(options->control_path);
1881 /* options->user will be set in the main program if appropriate */
1882 /* options->hostname will be set in the main program if appropriate */
1883 /* options->host_key_alias should not be set by default */
1884 /* options->preferred_authentications will be set in ssh */
1894 * parses the next field in a port forwarding specification.
1895 * sets fwd to the parsed field and advances p past the colon
1896 * or sets it to NULL at end of string.
1897 * returns 0 on success, else non-zero.
1900 parse_fwd_field(char **p, struct fwdarg *fwd)
1907 return -1; /* end of string */
1911 * A field escaped with square brackets is used literally.
1912 * XXX - allow ']' to be escaped via backslash?
1915 /* find matching ']' */
1916 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1920 /* no matching ']' or not at end of field. */
1921 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1923 /* NUL terminate the field and advance p past the colon */
1928 fwd->ispath = ispath;
1933 for (cp = *p; *cp != '\0'; cp++) {
1936 memmove(cp, cp + 1, strlen(cp + 1) + 1);
1949 fwd->ispath = ispath;
1956 * parses a string containing a port forwarding specification of the form:
1958 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
1959 * listenpath:connectpath
1961 * [listenhost:]listenport
1962 * returns number of arguments parsed or zero on error
1965 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1967 struct fwdarg fwdargs[4];
1971 memset(fwd, 0, sizeof(*fwd));
1972 memset(fwdargs, 0, sizeof(fwdargs));
1974 cp = p = xstrdup(fwdspec);
1976 /* skip leading spaces */
1977 while (isspace((u_char)*cp))
1980 for (i = 0; i < 4; ++i) {
1981 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
1985 /* Check for trailing garbage */
1986 if (cp != NULL && *cp != '\0') {
1987 i = 0; /* failure */
1992 if (fwdargs[0].ispath) {
1993 fwd->listen_path = xstrdup(fwdargs[0].arg);
1994 fwd->listen_port = PORT_STREAMLOCAL;
1996 fwd->listen_host = NULL;
1997 fwd->listen_port = a2port(fwdargs[0].arg);
1999 fwd->connect_host = xstrdup("socks");
2003 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2004 fwd->listen_path = xstrdup(fwdargs[0].arg);
2005 fwd->listen_port = PORT_STREAMLOCAL;
2006 fwd->connect_path = xstrdup(fwdargs[1].arg);
2007 fwd->connect_port = PORT_STREAMLOCAL;
2008 } else if (fwdargs[1].ispath) {
2009 fwd->listen_host = NULL;
2010 fwd->listen_port = a2port(fwdargs[0].arg);
2011 fwd->connect_path = xstrdup(fwdargs[1].arg);
2012 fwd->connect_port = PORT_STREAMLOCAL;
2014 fwd->listen_host = xstrdup(fwdargs[0].arg);
2015 fwd->listen_port = a2port(fwdargs[1].arg);
2016 fwd->connect_host = xstrdup("socks");
2021 if (fwdargs[0].ispath) {
2022 fwd->listen_path = xstrdup(fwdargs[0].arg);
2023 fwd->listen_port = PORT_STREAMLOCAL;
2024 fwd->connect_host = xstrdup(fwdargs[1].arg);
2025 fwd->connect_port = a2port(fwdargs[2].arg);
2026 } else if (fwdargs[2].ispath) {
2027 fwd->listen_host = xstrdup(fwdargs[0].arg);
2028 fwd->listen_port = a2port(fwdargs[1].arg);
2029 fwd->connect_path = xstrdup(fwdargs[2].arg);
2030 fwd->connect_port = PORT_STREAMLOCAL;
2032 fwd->listen_host = NULL;
2033 fwd->listen_port = a2port(fwdargs[0].arg);
2034 fwd->connect_host = xstrdup(fwdargs[1].arg);
2035 fwd->connect_port = a2port(fwdargs[2].arg);
2040 fwd->listen_host = xstrdup(fwdargs[0].arg);
2041 fwd->listen_port = a2port(fwdargs[1].arg);
2042 fwd->connect_host = xstrdup(fwdargs[2].arg);
2043 fwd->connect_port = a2port(fwdargs[3].arg);
2046 i = 0; /* failure */
2052 if (!(i == 1 || i == 2))
2055 if (!(i == 3 || i == 4)) {
2056 if (fwd->connect_path == NULL &&
2057 fwd->listen_path == NULL)
2060 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2064 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2065 (!remotefwd && fwd->listen_port == 0))
2067 if (fwd->connect_host != NULL &&
2068 strlen(fwd->connect_host) >= NI_MAXHOST)
2070 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2071 if (fwd->connect_path != NULL &&
2072 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2074 if (fwd->listen_host != NULL &&
2075 strlen(fwd->listen_host) >= NI_MAXHOST)
2077 if (fwd->listen_path != NULL &&
2078 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2084 free(fwd->connect_host);
2085 fwd->connect_host = NULL;
2086 free(fwd->connect_path);
2087 fwd->connect_path = NULL;
2088 free(fwd->listen_host);
2089 fwd->listen_host = NULL;
2090 free(fwd->listen_path);
2091 fwd->listen_path = NULL;