]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/readconf.c
Import mandoc snapshot 2017-06-08
[FreeBSD/FreeBSD.git] / crypto / openssh / readconf.c
1 /* $OpenBSD: readconf.c,v 1.262 2016/10/25 04:08:13 jsg Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
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".
13  */
14
15 #include "includes.h"
16 __RCSID("$FreeBSD$");
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/socket.h>
21 #include <sys/wait.h>
22 #include <sys/un.h>
23
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <limits.h>
33 #include <netdb.h>
34 #ifdef HAVE_PATHS_H
35 # include <paths.h>
36 #endif
37 #include <pwd.h>
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 #ifdef USE_SYSTEM_GLOB
44 # include <glob.h>
45 #else
46 # include "openbsd-compat/glob.h"
47 #endif
48 #ifdef HAVE_UTIL_H
49 #include <util.h>
50 #endif
51 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
52 # include <vis.h>
53 #endif
54
55 #include "xmalloc.h"
56 #include "ssh.h"
57 #include "compat.h"
58 #include "cipher.h"
59 #include "pathnames.h"
60 #include "log.h"
61 #include "sshkey.h"
62 #include "misc.h"
63 #include "readconf.h"
64 #include "match.h"
65 #include "kex.h"
66 #include "mac.h"
67 #include "uidswap.h"
68 #include "myproposal.h"
69 #include "digest.h"
70 #include "version.h"
71
72 /* Format of the configuration file:
73
74    # Configuration data is parsed as follows:
75    #  1. command line options
76    #  2. user-specific file
77    #  3. system-wide file
78    # Any configuration value is only changed the first time it is set.
79    # Thus, host-specific definitions should be at the beginning of the
80    # configuration file, and defaults at the end.
81
82    # Host-specific declarations.  These may override anything above.  A single
83    # host may match multiple declarations; these are processed in the order
84    # that they are given in.
85
86    Host *.ngs.fi ngs.fi
87      User foo
88
89    Host fake.com
90      HostName another.host.name.real.org
91      User blaah
92      Port 34289
93      ForwardX11 no
94      ForwardAgent no
95
96    Host books.com
97      RemoteForward 9999 shadows.cs.hut.fi:9999
98      Cipher 3des
99
100    Host fascist.blob.com
101      Port 23123
102      User tylonen
103      PasswordAuthentication no
104
105    Host puukko.hut.fi
106      User t35124p
107      ProxyCommand ssh-proxy %h %p
108
109    Host *.fr
110      PublicKeyAuthentication no
111
112    Host *.su
113      Cipher none
114      PasswordAuthentication no
115
116    Host vpn.fake.com
117      Tunnel yes
118      TunnelDevice 3
119
120    # Defaults for various options
121    Host *
122      ForwardAgent no
123      ForwardX11 no
124      PasswordAuthentication yes
125      RSAAuthentication yes
126      RhostsRSAAuthentication yes
127      StrictHostKeyChecking yes
128      TcpKeepAlive no
129      IdentityFile ~/.ssh/identity
130      Port 22
131      EscapeChar ~
132
133 */
134
135 static int read_config_file_depth(const char *filename, struct passwd *pw,
136     const char *host, const char *original_host, Options *options,
137     int flags, int *activep, int depth);
138 static int process_config_line_depth(Options *options, struct passwd *pw,
139     const char *host, const char *original_host, char *line,
140     const char *filename, int linenum, int *activep, int flags, int depth);
141
142 /* Keyword tokens. */
143
144 typedef enum {
145         oBadOption,
146         oVersionAddendum,
147         oHost, oMatch, oInclude,
148         oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
149         oGatewayPorts, oExitOnForwardFailure,
150         oPasswordAuthentication, oRSAAuthentication,
151         oChallengeResponseAuthentication, oXAuthLocation,
152         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
153         oCertificateFile, oAddKeysToAgent, oIdentityAgent,
154         oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
155         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
156         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
157         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
158         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
159         oPubkeyAuthentication,
160         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
161         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
162         oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
163         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
164         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
165         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
166         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
167         oSendEnv, oControlPath, oControlMaster, oControlPersist,
168         oHashKnownHosts,
169         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
170         oVisualHostKey,
171         oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
172         oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
173         oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
174         oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
175         oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
176         oPubkeyAcceptedKeyTypes, oProxyJump,
177         oIgnoredUnknownOption, oDeprecated, oUnsupported
178 } OpCodes;
179
180 /* Textual representations of the tokens. */
181
182 static struct {
183         const char *name;
184         OpCodes opcode;
185 } keywords[] = {
186         { "forwardagent", oForwardAgent },
187         { "forwardx11", oForwardX11 },
188         { "forwardx11trusted", oForwardX11Trusted },
189         { "forwardx11timeout", oForwardX11Timeout },
190         { "exitonforwardfailure", oExitOnForwardFailure },
191         { "xauthlocation", oXAuthLocation },
192         { "gatewayports", oGatewayPorts },
193         { "useprivilegedport", oUsePrivilegedPort },
194         { "rhostsauthentication", oDeprecated },
195         { "passwordauthentication", oPasswordAuthentication },
196         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
197         { "kbdinteractivedevices", oKbdInteractiveDevices },
198         { "rsaauthentication", oRSAAuthentication },
199         { "pubkeyauthentication", oPubkeyAuthentication },
200         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
201         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
202         { "hostbasedauthentication", oHostbasedAuthentication },
203         { "challengeresponseauthentication", oChallengeResponseAuthentication },
204         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
205         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
206         { "kerberosauthentication", oUnsupported },
207         { "kerberostgtpassing", oUnsupported },
208         { "afstokenpassing", oUnsupported },
209 #if defined(GSSAPI)
210         { "gssapiauthentication", oGssAuthentication },
211         { "gssapidelegatecredentials", oGssDelegateCreds },
212 #else
213         { "gssapiauthentication", oUnsupported },
214         { "gssapidelegatecredentials", oUnsupported },
215 #endif
216         { "fallbacktorsh", oDeprecated },
217         { "usersh", oDeprecated },
218         { "identityfile", oIdentityFile },
219         { "identityfile2", oIdentityFile },                     /* obsolete */
220         { "identitiesonly", oIdentitiesOnly },
221         { "certificatefile", oCertificateFile },
222         { "addkeystoagent", oAddKeysToAgent },
223         { "identityagent", oIdentityAgent },
224         { "hostname", oHostName },
225         { "hostkeyalias", oHostKeyAlias },
226         { "proxycommand", oProxyCommand },
227         { "port", oPort },
228         { "cipher", oCipher },
229         { "ciphers", oCiphers },
230         { "macs", oMacs },
231         { "protocol", oProtocol },
232         { "remoteforward", oRemoteForward },
233         { "localforward", oLocalForward },
234         { "user", oUser },
235         { "host", oHost },
236         { "match", oMatch },
237         { "escapechar", oEscapeChar },
238         { "globalknownhostsfile", oGlobalKnownHostsFile },
239         { "globalknownhostsfile2", oDeprecated },
240         { "userknownhostsfile", oUserKnownHostsFile },
241         { "userknownhostsfile2", oDeprecated },
242         { "connectionattempts", oConnectionAttempts },
243         { "batchmode", oBatchMode },
244         { "checkhostip", oCheckHostIP },
245         { "stricthostkeychecking", oStrictHostKeyChecking },
246         { "compression", oCompression },
247         { "compressionlevel", oCompressionLevel },
248         { "tcpkeepalive", oTCPKeepAlive },
249         { "keepalive", oTCPKeepAlive },                         /* obsolete */
250         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
251         { "loglevel", oLogLevel },
252         { "dynamicforward", oDynamicForward },
253         { "preferredauthentications", oPreferredAuthentications },
254         { "hostkeyalgorithms", oHostKeyAlgorithms },
255         { "bindaddress", oBindAddress },
256 #ifdef ENABLE_PKCS11
257         { "smartcarddevice", oPKCS11Provider },
258         { "pkcs11provider", oPKCS11Provider },
259 #else
260         { "smartcarddevice", oUnsupported },
261         { "pkcs11provider", oUnsupported },
262 #endif
263         { "clearallforwardings", oClearAllForwardings },
264         { "enablesshkeysign", oEnableSSHKeysign },
265         { "verifyhostkeydns", oVerifyHostKeyDNS },
266         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
267         { "rekeylimit", oRekeyLimit },
268         { "connecttimeout", oConnectTimeout },
269         { "addressfamily", oAddressFamily },
270         { "serveraliveinterval", oServerAliveInterval },
271         { "serveralivecountmax", oServerAliveCountMax },
272         { "sendenv", oSendEnv },
273         { "controlpath", oControlPath },
274         { "controlmaster", oControlMaster },
275         { "controlpersist", oControlPersist },
276         { "hashknownhosts", oHashKnownHosts },
277         { "include", oInclude },
278         { "tunnel", oTunnel },
279         { "tunneldevice", oTunnelDevice },
280         { "localcommand", oLocalCommand },
281         { "permitlocalcommand", oPermitLocalCommand },
282         { "visualhostkey", oVisualHostKey },
283         { "useroaming", oDeprecated },
284         { "kexalgorithms", oKexAlgorithms },
285         { "ipqos", oIPQoS },
286         { "requesttty", oRequestTTY },
287         { "proxyusefdpass", oProxyUseFdpass },
288         { "canonicaldomains", oCanonicalDomains },
289         { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
290         { "canonicalizehostname", oCanonicalizeHostname },
291         { "canonicalizemaxdots", oCanonicalizeMaxDots },
292         { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
293         { "streamlocalbindmask", oStreamLocalBindMask },
294         { "streamlocalbindunlink", oStreamLocalBindUnlink },
295         { "revokedhostkeys", oRevokedHostKeys },
296         { "fingerprinthash", oFingerprintHash },
297         { "updatehostkeys", oUpdateHostkeys },
298         { "hostbasedkeytypes", oHostbasedKeyTypes },
299         { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
300         { "ignoreunknown", oIgnoreUnknown },
301         { "proxyjump", oProxyJump },
302
303         { "hpndisabled", oDeprecated },
304         { "hpnbuffersize", oDeprecated },
305         { "tcprcvbufpoll", oDeprecated },
306         { "tcprcvbuf", oDeprecated },
307         { "noneenabled", oUnsupported },
308         { "noneswitch", oUnsupported },
309         { "versionaddendum", oVersionAddendum },
310
311         { NULL, oBadOption }
312 };
313
314 /*
315  * Adds a local TCP/IP port forward to options.  Never returns if there is an
316  * error.
317  */
318
319 void
320 add_local_forward(Options *options, const struct Forward *newfwd)
321 {
322         struct Forward *fwd;
323         extern uid_t original_real_uid;
324         int i, ipport_reserved;
325
326         if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
327             newfwd->listen_path == NULL)
328                 fatal("Privileged ports can only be forwarded by root.");
329         /* Don't add duplicates */
330         for (i = 0; i < options->num_local_forwards; i++) {
331                 if (forward_equals(newfwd, options->local_forwards + i))
332                         return;
333         }
334         options->local_forwards = xreallocarray(options->local_forwards,
335             options->num_local_forwards + 1,
336             sizeof(*options->local_forwards));
337         fwd = &options->local_forwards[options->num_local_forwards++];
338
339         fwd->listen_host = newfwd->listen_host;
340         fwd->listen_port = newfwd->listen_port;
341         fwd->listen_path = newfwd->listen_path;
342         fwd->connect_host = newfwd->connect_host;
343         fwd->connect_port = newfwd->connect_port;
344         fwd->connect_path = newfwd->connect_path;
345 }
346
347 /*
348  * Adds a remote TCP/IP port forward to options.  Never returns if there is
349  * an error.
350  */
351
352 void
353 add_remote_forward(Options *options, const struct Forward *newfwd)
354 {
355         struct Forward *fwd;
356         int i;
357
358         /* Don't add duplicates */
359         for (i = 0; i < options->num_remote_forwards; i++) {
360                 if (forward_equals(newfwd, options->remote_forwards + i))
361                         return;
362         }
363         options->remote_forwards = xreallocarray(options->remote_forwards,
364             options->num_remote_forwards + 1,
365             sizeof(*options->remote_forwards));
366         fwd = &options->remote_forwards[options->num_remote_forwards++];
367
368         fwd->listen_host = newfwd->listen_host;
369         fwd->listen_port = newfwd->listen_port;
370         fwd->listen_path = newfwd->listen_path;
371         fwd->connect_host = newfwd->connect_host;
372         fwd->connect_port = newfwd->connect_port;
373         fwd->connect_path = newfwd->connect_path;
374         fwd->handle = newfwd->handle;
375         fwd->allocated_port = 0;
376 }
377
378 static void
379 clear_forwardings(Options *options)
380 {
381         int i;
382
383         for (i = 0; i < options->num_local_forwards; i++) {
384                 free(options->local_forwards[i].listen_host);
385                 free(options->local_forwards[i].listen_path);
386                 free(options->local_forwards[i].connect_host);
387                 free(options->local_forwards[i].connect_path);
388         }
389         if (options->num_local_forwards > 0) {
390                 free(options->local_forwards);
391                 options->local_forwards = NULL;
392         }
393         options->num_local_forwards = 0;
394         for (i = 0; i < options->num_remote_forwards; i++) {
395                 free(options->remote_forwards[i].listen_host);
396                 free(options->remote_forwards[i].listen_path);
397                 free(options->remote_forwards[i].connect_host);
398                 free(options->remote_forwards[i].connect_path);
399         }
400         if (options->num_remote_forwards > 0) {
401                 free(options->remote_forwards);
402                 options->remote_forwards = NULL;
403         }
404         options->num_remote_forwards = 0;
405         options->tun_open = SSH_TUNMODE_NO;
406 }
407
408 void
409 add_certificate_file(Options *options, const char *path, int userprovided)
410 {
411         int i;
412
413         if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
414                 fatal("Too many certificate files specified (max %d)",
415                     SSH_MAX_CERTIFICATE_FILES);
416
417         /* Avoid registering duplicates */
418         for (i = 0; i < options->num_certificate_files; i++) {
419                 if (options->certificate_file_userprovided[i] == userprovided &&
420                     strcmp(options->certificate_files[i], path) == 0) {
421                         debug2("%s: ignoring duplicate key %s", __func__, path);
422                         return;
423                 }
424         }
425
426         options->certificate_file_userprovided[options->num_certificate_files] =
427             userprovided;
428         options->certificate_files[options->num_certificate_files++] =
429             xstrdup(path);
430 }
431
432 void
433 add_identity_file(Options *options, const char *dir, const char *filename,
434     int userprovided)
435 {
436         char *path;
437         int i;
438
439         if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
440                 fatal("Too many identity files specified (max %d)",
441                     SSH_MAX_IDENTITY_FILES);
442
443         if (dir == NULL) /* no dir, filename is absolute */
444                 path = xstrdup(filename);
445         else
446                 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
447
448         /* Avoid registering duplicates */
449         for (i = 0; i < options->num_identity_files; i++) {
450                 if (options->identity_file_userprovided[i] == userprovided &&
451                     strcmp(options->identity_files[i], path) == 0) {
452                         debug2("%s: ignoring duplicate key %s", __func__, path);
453                         free(path);
454                         return;
455                 }
456         }
457
458         options->identity_file_userprovided[options->num_identity_files] =
459             userprovided;
460         options->identity_files[options->num_identity_files++] = path;
461 }
462
463 int
464 default_ssh_port(void)
465 {
466         static int port;
467         struct servent *sp;
468
469         if (port == 0) {
470                 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
471                 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
472         }
473         return port;
474 }
475
476 /*
477  * Execute a command in a shell.
478  * Return its exit status or -1 on abnormal exit.
479  */
480 static int
481 execute_in_shell(const char *cmd)
482 {
483         char *shell;
484         pid_t pid;
485         int devnull, status;
486         extern uid_t original_real_uid;
487
488         if ((shell = getenv("SHELL")) == NULL)
489                 shell = _PATH_BSHELL;
490
491         /* Need this to redirect subprocess stdin/out */
492         if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
493                 fatal("open(/dev/null): %s", strerror(errno));
494
495         debug("Executing command: '%.500s'", cmd);
496
497         /* Fork and execute the command. */
498         if ((pid = fork()) == 0) {
499                 char *argv[4];
500
501                 /* Child.  Permanently give up superuser privileges. */
502                 permanently_drop_suid(original_real_uid);
503
504                 /* Redirect child stdin and stdout. Leave stderr */
505                 if (dup2(devnull, STDIN_FILENO) == -1)
506                         fatal("dup2: %s", strerror(errno));
507                 if (dup2(devnull, STDOUT_FILENO) == -1)
508                         fatal("dup2: %s", strerror(errno));
509                 if (devnull > STDERR_FILENO)
510                         close(devnull);
511                 closefrom(STDERR_FILENO + 1);
512
513                 argv[0] = shell;
514                 argv[1] = "-c";
515                 argv[2] = xstrdup(cmd);
516                 argv[3] = NULL;
517
518                 execv(argv[0], argv);
519                 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
520                 /* Die with signal to make this error apparent to parent. */
521                 signal(SIGTERM, SIG_DFL);
522                 kill(getpid(), SIGTERM);
523                 _exit(1);
524         }
525         /* Parent. */
526         if (pid < 0)
527                 fatal("%s: fork: %.100s", __func__, strerror(errno));
528
529         close(devnull);
530
531         while (waitpid(pid, &status, 0) == -1) {
532                 if (errno != EINTR && errno != EAGAIN)
533                         fatal("%s: waitpid: %s", __func__, strerror(errno));
534         }
535         if (!WIFEXITED(status)) {
536                 error("command '%.100s' exited abnormally", cmd);
537                 return -1;
538         }
539         debug3("command returned status %d", WEXITSTATUS(status));
540         return WEXITSTATUS(status);
541 }
542
543 /*
544  * Parse and execute a Match directive.
545  */
546 static int
547 match_cfg_line(Options *options, char **condition, struct passwd *pw,
548     const char *host_arg, const char *original_host, int post_canon,
549     const char *filename, int linenum)
550 {
551         char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
552         const char *ruser;
553         int r, port, this_result, result = 1, attributes = 0, negate;
554         char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
555
556         /*
557          * Configuration is likely to be incomplete at this point so we
558          * must be prepared to use default values.
559          */
560         port = options->port <= 0 ? default_ssh_port() : options->port;
561         ruser = options->user == NULL ? pw->pw_name : options->user;
562         if (post_canon) {
563                 host = xstrdup(options->hostname);
564         } else if (options->hostname != NULL) {
565                 /* NB. Please keep in sync with ssh.c:main() */
566                 host = percent_expand(options->hostname,
567                     "h", host_arg, (char *)NULL);
568         } else {
569                 host = xstrdup(host_arg);
570         }
571
572         debug2("checking match for '%s' host %s originally %s",
573             cp, host, original_host);
574         while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
575                 criteria = NULL;
576                 this_result = 1;
577                 if ((negate = attrib[0] == '!'))
578                         attrib++;
579                 /* criteria "all" and "canonical" have no argument */
580                 if (strcasecmp(attrib, "all") == 0) {
581                         if (attributes > 1 ||
582                             ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
583                                 error("%.200s line %d: '%s' cannot be combined "
584                                     "with other Match attributes",
585                                     filename, linenum, oattrib);
586                                 result = -1;
587                                 goto out;
588                         }
589                         if (result)
590                                 result = negate ? 0 : 1;
591                         goto out;
592                 }
593                 attributes++;
594                 if (strcasecmp(attrib, "canonical") == 0) {
595                         r = !!post_canon;  /* force bitmask member to boolean */
596                         if (r == (negate ? 1 : 0))
597                                 this_result = result = 0;
598                         debug3("%.200s line %d: %smatched '%s'",
599                             filename, linenum,
600                             this_result ? "" : "not ", oattrib);
601                         continue;
602                 }
603                 /* All other criteria require an argument */
604                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
605                         error("Missing Match criteria for %s", attrib);
606                         result = -1;
607                         goto out;
608                 }
609                 if (strcasecmp(attrib, "host") == 0) {
610                         criteria = xstrdup(host);
611                         r = match_hostname(host, arg) == 1;
612                         if (r == (negate ? 1 : 0))
613                                 this_result = result = 0;
614                 } else if (strcasecmp(attrib, "originalhost") == 0) {
615                         criteria = xstrdup(original_host);
616                         r = match_hostname(original_host, arg) == 1;
617                         if (r == (negate ? 1 : 0))
618                                 this_result = result = 0;
619                 } else if (strcasecmp(attrib, "user") == 0) {
620                         criteria = xstrdup(ruser);
621                         r = match_pattern_list(ruser, arg, 0) == 1;
622                         if (r == (negate ? 1 : 0))
623                                 this_result = result = 0;
624                 } else if (strcasecmp(attrib, "localuser") == 0) {
625                         criteria = xstrdup(pw->pw_name);
626                         r = match_pattern_list(pw->pw_name, arg, 0) == 1;
627                         if (r == (negate ? 1 : 0))
628                                 this_result = result = 0;
629                 } else if (strcasecmp(attrib, "exec") == 0) {
630                         if (gethostname(thishost, sizeof(thishost)) == -1)
631                                 fatal("gethostname: %s", strerror(errno));
632                         strlcpy(shorthost, thishost, sizeof(shorthost));
633                         shorthost[strcspn(thishost, ".")] = '\0';
634                         snprintf(portstr, sizeof(portstr), "%d", port);
635
636                         cmd = percent_expand(arg,
637                             "L", shorthost,
638                             "d", pw->pw_dir,
639                             "h", host,
640                             "l", thishost,
641                             "n", original_host,
642                             "p", portstr,
643                             "r", ruser,
644                             "u", pw->pw_name,
645                             (char *)NULL);
646                         if (result != 1) {
647                                 /* skip execution if prior predicate failed */
648                                 debug3("%.200s line %d: skipped exec "
649                                     "\"%.100s\"", filename, linenum, cmd);
650                                 free(cmd);
651                                 continue;
652                         }
653                         r = execute_in_shell(cmd);
654                         if (r == -1) {
655                                 fatal("%.200s line %d: match exec "
656                                     "'%.100s' error", filename,
657                                     linenum, cmd);
658                         }
659                         criteria = xstrdup(cmd);
660                         free(cmd);
661                         /* Force exit status to boolean */
662                         r = r == 0;
663                         if (r == (negate ? 1 : 0))
664                                 this_result = result = 0;
665                 } else {
666                         error("Unsupported Match attribute %s", attrib);
667                         result = -1;
668                         goto out;
669                 }
670                 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
671                     filename, linenum, this_result ? "": "not ",
672                     oattrib, criteria);
673                 free(criteria);
674         }
675         if (attributes == 0) {
676                 error("One or more attributes required for Match");
677                 result = -1;
678                 goto out;
679         }
680  out:
681         if (result != -1)
682                 debug2("match %sfound", result ? "" : "not ");
683         *condition = cp;
684         free(host);
685         return result;
686 }
687
688 /* Check and prepare a domain name: removes trailing '.' and lowercases */
689 static void
690 valid_domain(char *name, const char *filename, int linenum)
691 {
692         size_t i, l = strlen(name);
693         u_char c, last = '\0';
694
695         if (l == 0)
696                 fatal("%s line %d: empty hostname suffix", filename, linenum);
697         if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
698                 fatal("%s line %d: hostname suffix \"%.100s\" "
699                     "starts with invalid character", filename, linenum, name);
700         for (i = 0; i < l; i++) {
701                 c = tolower((u_char)name[i]);
702                 name[i] = (char)c;
703                 if (last == '.' && c == '.')
704                         fatal("%s line %d: hostname suffix \"%.100s\" contains "
705                             "consecutive separators", filename, linenum, name);
706                 if (c != '.' && c != '-' && !isalnum(c) &&
707                     c != '_') /* technically invalid, but common */
708                         fatal("%s line %d: hostname suffix \"%.100s\" contains "
709                             "invalid characters", filename, linenum, name);
710                 last = c;
711         }
712         if (name[l - 1] == '.')
713                 name[l - 1] = '\0';
714 }
715
716 /*
717  * Returns the number of the token pointed to by cp or oBadOption.
718  */
719 static OpCodes
720 parse_token(const char *cp, const char *filename, int linenum,
721     const char *ignored_unknown)
722 {
723         int i;
724
725         for (i = 0; keywords[i].name; i++)
726                 if (strcmp(cp, keywords[i].name) == 0)
727                         return keywords[i].opcode;
728         if (ignored_unknown != NULL &&
729             match_pattern_list(cp, ignored_unknown, 1) == 1)
730                 return oIgnoredUnknownOption;
731         error("%s: line %d: Bad configuration option: %s",
732             filename, linenum, cp);
733         return oBadOption;
734 }
735
736 /* Multistate option parsing */
737 struct multistate {
738         char *key;
739         int value;
740 };
741 static const struct multistate multistate_flag[] = {
742         { "true",                       1 },
743         { "false",                      0 },
744         { "yes",                        1 },
745         { "no",                         0 },
746         { NULL, -1 }
747 };
748 static const struct multistate multistate_yesnoask[] = {
749         { "true",                       1 },
750         { "false",                      0 },
751         { "yes",                        1 },
752         { "no",                         0 },
753         { "ask",                        2 },
754         { NULL, -1 }
755 };
756 static const struct multistate multistate_yesnoaskconfirm[] = {
757         { "true",                       1 },
758         { "false",                      0 },
759         { "yes",                        1 },
760         { "no",                         0 },
761         { "ask",                        2 },
762         { "confirm",                    3 },
763         { NULL, -1 }
764 };
765 static const struct multistate multistate_addressfamily[] = {
766         { "inet",                       AF_INET },
767         { "inet6",                      AF_INET6 },
768         { "any",                        AF_UNSPEC },
769         { NULL, -1 }
770 };
771 static const struct multistate multistate_controlmaster[] = {
772         { "true",                       SSHCTL_MASTER_YES },
773         { "yes",                        SSHCTL_MASTER_YES },
774         { "false",                      SSHCTL_MASTER_NO },
775         { "no",                         SSHCTL_MASTER_NO },
776         { "auto",                       SSHCTL_MASTER_AUTO },
777         { "ask",                        SSHCTL_MASTER_ASK },
778         { "autoask",                    SSHCTL_MASTER_AUTO_ASK },
779         { NULL, -1 }
780 };
781 static const struct multistate multistate_tunnel[] = {
782         { "ethernet",                   SSH_TUNMODE_ETHERNET },
783         { "point-to-point",             SSH_TUNMODE_POINTOPOINT },
784         { "true",                       SSH_TUNMODE_DEFAULT },
785         { "yes",                        SSH_TUNMODE_DEFAULT },
786         { "false",                      SSH_TUNMODE_NO },
787         { "no",                         SSH_TUNMODE_NO },
788         { NULL, -1 }
789 };
790 static const struct multistate multistate_requesttty[] = {
791         { "true",                       REQUEST_TTY_YES },
792         { "yes",                        REQUEST_TTY_YES },
793         { "false",                      REQUEST_TTY_NO },
794         { "no",                         REQUEST_TTY_NO },
795         { "force",                      REQUEST_TTY_FORCE },
796         { "auto",                       REQUEST_TTY_AUTO },
797         { NULL, -1 }
798 };
799 static const struct multistate multistate_canonicalizehostname[] = {
800         { "true",                       SSH_CANONICALISE_YES },
801         { "false",                      SSH_CANONICALISE_NO },
802         { "yes",                        SSH_CANONICALISE_YES },
803         { "no",                         SSH_CANONICALISE_NO },
804         { "always",                     SSH_CANONICALISE_ALWAYS },
805         { NULL, -1 }
806 };
807
808 /*
809  * Processes a single option line as used in the configuration files. This
810  * only sets those values that have not already been set.
811  */
812 int
813 process_config_line(Options *options, struct passwd *pw, const char *host,
814     const char *original_host, char *line, const char *filename,
815     int linenum, int *activep, int flags)
816 {
817         return process_config_line_depth(options, pw, host, original_host,
818             line, filename, linenum, activep, flags, 0);
819 }
820
821 #define WHITESPACE " \t\r\n"
822 static int
823 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
824     const char *original_host, char *line, const char *filename,
825     int linenum, int *activep, int flags, int depth)
826 {
827         char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
828         char **cpptr, fwdarg[256];
829         u_int i, *uintptr, max_entries = 0;
830         int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
831         LogLevel *log_level_ptr;
832         long long val64;
833         size_t len;
834         struct Forward fwd;
835         const struct multistate *multistate_ptr;
836         struct allowed_cname *cname;
837         glob_t gl;
838
839         if (activep == NULL) { /* We are processing a command line directive */
840                 cmdline = 1;
841                 activep = &cmdline;
842         }
843
844         /* Strip trailing whitespace */
845         if ((len = strlen(line)) == 0)
846                 return 0;
847         for (len--; len > 0; len--) {
848                 if (strchr(WHITESPACE, line[len]) == NULL)
849                         break;
850                 line[len] = '\0';
851         }
852
853         s = line;
854         /* Get the keyword. (Each line is supposed to begin with a keyword). */
855         if ((keyword = strdelim(&s)) == NULL)
856                 return 0;
857         /* Ignore leading whitespace. */
858         if (*keyword == '\0')
859                 keyword = strdelim(&s);
860         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
861                 return 0;
862         /* Match lowercase keyword */
863         lowercase(keyword);
864
865         opcode = parse_token(keyword, filename, linenum,
866             options->ignored_unknown);
867
868         switch (opcode) {
869         case oBadOption:
870                 /* don't panic, but count bad options */
871                 return -1;
872         case oIgnoredUnknownOption:
873                 debug("%s line %d: Ignored unknown option \"%s\"",
874                     filename, linenum, keyword);
875                 return 0;
876         case oConnectTimeout:
877                 intptr = &options->connection_timeout;
878 parse_time:
879                 arg = strdelim(&s);
880                 if (!arg || *arg == '\0')
881                         fatal("%s line %d: missing time value.",
882                             filename, linenum);
883                 if (strcmp(arg, "none") == 0)
884                         value = -1;
885                 else if ((value = convtime(arg)) == -1)
886                         fatal("%s line %d: invalid time value.",
887                             filename, linenum);
888                 if (*activep && *intptr == -1)
889                         *intptr = value;
890                 break;
891
892         case oForwardAgent:
893                 intptr = &options->forward_agent;
894  parse_flag:
895                 multistate_ptr = multistate_flag;
896  parse_multistate:
897                 arg = strdelim(&s);
898                 if (!arg || *arg == '\0')
899                         fatal("%s line %d: missing argument.",
900                             filename, linenum);
901                 value = -1;
902                 for (i = 0; multistate_ptr[i].key != NULL; i++) {
903                         if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
904                                 value = multistate_ptr[i].value;
905                                 break;
906                         }
907                 }
908                 if (value == -1)
909                         fatal("%s line %d: unsupported option \"%s\".",
910                             filename, linenum, arg);
911                 if (*activep && *intptr == -1)
912                         *intptr = value;
913                 break;
914
915         case oForwardX11:
916                 intptr = &options->forward_x11;
917                 goto parse_flag;
918
919         case oForwardX11Trusted:
920                 intptr = &options->forward_x11_trusted;
921                 goto parse_flag;
922
923         case oForwardX11Timeout:
924                 intptr = &options->forward_x11_timeout;
925                 goto parse_time;
926
927         case oGatewayPorts:
928                 intptr = &options->fwd_opts.gateway_ports;
929                 goto parse_flag;
930
931         case oExitOnForwardFailure:
932                 intptr = &options->exit_on_forward_failure;
933                 goto parse_flag;
934
935         case oUsePrivilegedPort:
936                 intptr = &options->use_privileged_port;
937                 goto parse_flag;
938
939         case oPasswordAuthentication:
940                 intptr = &options->password_authentication;
941                 goto parse_flag;
942
943         case oKbdInteractiveAuthentication:
944                 intptr = &options->kbd_interactive_authentication;
945                 goto parse_flag;
946
947         case oKbdInteractiveDevices:
948                 charptr = &options->kbd_interactive_devices;
949                 goto parse_string;
950
951         case oPubkeyAuthentication:
952                 intptr = &options->pubkey_authentication;
953                 goto parse_flag;
954
955         case oRSAAuthentication:
956                 intptr = &options->rsa_authentication;
957                 goto parse_flag;
958
959         case oRhostsRSAAuthentication:
960                 intptr = &options->rhosts_rsa_authentication;
961                 goto parse_flag;
962
963         case oHostbasedAuthentication:
964                 intptr = &options->hostbased_authentication;
965                 goto parse_flag;
966
967         case oChallengeResponseAuthentication:
968                 intptr = &options->challenge_response_authentication;
969                 goto parse_flag;
970
971         case oGssAuthentication:
972                 intptr = &options->gss_authentication;
973                 goto parse_flag;
974
975         case oGssDelegateCreds:
976                 intptr = &options->gss_deleg_creds;
977                 goto parse_flag;
978
979         case oBatchMode:
980                 intptr = &options->batch_mode;
981                 goto parse_flag;
982
983         case oCheckHostIP:
984                 intptr = &options->check_host_ip;
985                 goto parse_flag;
986
987         case oVerifyHostKeyDNS:
988                 intptr = &options->verify_host_key_dns;
989                 multistate_ptr = multistate_yesnoask;
990                 goto parse_multistate;
991
992         case oStrictHostKeyChecking:
993                 intptr = &options->strict_host_key_checking;
994                 multistate_ptr = multistate_yesnoask;
995                 goto parse_multistate;
996
997         case oCompression:
998                 intptr = &options->compression;
999                 goto parse_flag;
1000
1001         case oTCPKeepAlive:
1002                 intptr = &options->tcp_keep_alive;
1003                 goto parse_flag;
1004
1005         case oNoHostAuthenticationForLocalhost:
1006                 intptr = &options->no_host_authentication_for_localhost;
1007                 goto parse_flag;
1008
1009         case oNumberOfPasswordPrompts:
1010                 intptr = &options->number_of_password_prompts;
1011                 goto parse_int;
1012
1013         case oCompressionLevel:
1014                 intptr = &options->compression_level;
1015                 goto parse_int;
1016
1017         case oRekeyLimit:
1018                 arg = strdelim(&s);
1019                 if (!arg || *arg == '\0')
1020                         fatal("%.200s line %d: Missing argument.", filename,
1021                             linenum);
1022                 if (strcmp(arg, "default") == 0) {
1023                         val64 = 0;
1024                 } else {
1025                         if (scan_scaled(arg, &val64) == -1)
1026                                 fatal("%.200s line %d: Bad number '%s': %s",
1027                                     filename, linenum, arg, strerror(errno));
1028                         if (val64 != 0 && val64 < 16)
1029                                 fatal("%.200s line %d: RekeyLimit too small",
1030                                     filename, linenum);
1031                 }
1032                 if (*activep && options->rekey_limit == -1)
1033                         options->rekey_limit = val64;
1034                 if (s != NULL) { /* optional rekey interval present */
1035                         if (strcmp(s, "none") == 0) {
1036                                 (void)strdelim(&s);     /* discard */
1037                                 break;
1038                         }
1039                         intptr = &options->rekey_interval;
1040                         goto parse_time;
1041                 }
1042                 break;
1043
1044         case oIdentityFile:
1045                 arg = strdelim(&s);
1046                 if (!arg || *arg == '\0')
1047                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1048                 if (*activep) {
1049                         intptr = &options->num_identity_files;
1050                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
1051                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
1052                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
1053                         add_identity_file(options, NULL,
1054                             arg, flags & SSHCONF_USERCONF);
1055                 }
1056                 break;
1057
1058         case oCertificateFile:
1059                 arg = strdelim(&s);
1060                 if (!arg || *arg == '\0')
1061                         fatal("%.200s line %d: Missing argument.",
1062                             filename, linenum);
1063                 if (*activep) {
1064                         intptr = &options->num_certificate_files;
1065                         if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1066                                 fatal("%.200s line %d: Too many certificate "
1067                                     "files specified (max %d).",
1068                                     filename, linenum,
1069                                     SSH_MAX_CERTIFICATE_FILES);
1070                         }
1071                         add_certificate_file(options, arg,
1072                             flags & SSHCONF_USERCONF);
1073                 }
1074                 break;
1075
1076         case oXAuthLocation:
1077                 charptr=&options->xauth_location;
1078                 goto parse_string;
1079
1080         case oUser:
1081                 charptr = &options->user;
1082 parse_string:
1083                 arg = strdelim(&s);
1084                 if (!arg || *arg == '\0')
1085                         fatal("%.200s line %d: Missing argument.",
1086                             filename, linenum);
1087                 if (*activep && *charptr == NULL)
1088                         *charptr = xstrdup(arg);
1089                 break;
1090
1091         case oGlobalKnownHostsFile:
1092                 cpptr = (char **)&options->system_hostfiles;
1093                 uintptr = &options->num_system_hostfiles;
1094                 max_entries = SSH_MAX_HOSTS_FILES;
1095 parse_char_array:
1096                 if (*activep && *uintptr == 0) {
1097                         while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1098                                 if ((*uintptr) >= max_entries)
1099                                         fatal("%s line %d: "
1100                                             "too many authorized keys files.",
1101                                             filename, linenum);
1102                                 cpptr[(*uintptr)++] = xstrdup(arg);
1103                         }
1104                 }
1105                 return 0;
1106
1107         case oUserKnownHostsFile:
1108                 cpptr = (char **)&options->user_hostfiles;
1109                 uintptr = &options->num_user_hostfiles;
1110                 max_entries = SSH_MAX_HOSTS_FILES;
1111                 goto parse_char_array;
1112
1113         case oHostName:
1114                 charptr = &options->hostname;
1115                 goto parse_string;
1116
1117         case oHostKeyAlias:
1118                 charptr = &options->host_key_alias;
1119                 goto parse_string;
1120
1121         case oPreferredAuthentications:
1122                 charptr = &options->preferred_authentications;
1123                 goto parse_string;
1124
1125         case oBindAddress:
1126                 charptr = &options->bind_address;
1127                 goto parse_string;
1128
1129         case oPKCS11Provider:
1130                 charptr = &options->pkcs11_provider;
1131                 goto parse_string;
1132
1133         case oProxyCommand:
1134                 charptr = &options->proxy_command;
1135                 /* Ignore ProxyCommand if ProxyJump already specified */
1136                 if (options->jump_host != NULL)
1137                         charptr = &options->jump_host; /* Skip below */
1138 parse_command:
1139                 if (s == NULL)
1140                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1141                 len = strspn(s, WHITESPACE "=");
1142                 if (*activep && *charptr == NULL)
1143                         *charptr = xstrdup(s + len);
1144                 return 0;
1145
1146         case oProxyJump:
1147                 if (s == NULL) {
1148                         fatal("%.200s line %d: Missing argument.",
1149                             filename, linenum);
1150                 }
1151                 len = strspn(s, WHITESPACE "=");
1152                 if (parse_jump(s + len, options, *activep) == -1) {
1153                         fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1154                             filename, linenum, s + len);
1155                 }
1156                 return 0;
1157
1158         case oPort:
1159                 intptr = &options->port;
1160 parse_int:
1161                 arg = strdelim(&s);
1162                 if (!arg || *arg == '\0')
1163                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1164                 if (arg[0] < '0' || arg[0] > '9')
1165                         fatal("%.200s line %d: Bad number.", filename, linenum);
1166
1167                 /* Octal, decimal, or hex format? */
1168                 value = strtol(arg, &endofnumber, 0);
1169                 if (arg == endofnumber)
1170                         fatal("%.200s line %d: Bad number.", filename, linenum);
1171                 if (*activep && *intptr == -1)
1172                         *intptr = value;
1173                 break;
1174
1175         case oConnectionAttempts:
1176                 intptr = &options->connection_attempts;
1177                 goto parse_int;
1178
1179         case oCipher:
1180                 intptr = &options->cipher;
1181                 arg = strdelim(&s);
1182                 if (!arg || *arg == '\0')
1183                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1184                 value = cipher_number(arg);
1185                 if (value == -1)
1186                         fatal("%.200s line %d: Bad cipher '%s'.",
1187                             filename, linenum, arg ? arg : "<NONE>");
1188                 if (*activep && *intptr == -1)
1189                         *intptr = value;
1190                 break;
1191
1192         case oCiphers:
1193                 arg = strdelim(&s);
1194                 if (!arg || *arg == '\0')
1195                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1196                 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1197                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1198                             filename, linenum, arg ? arg : "<NONE>");
1199                 if (*activep && options->ciphers == NULL)
1200                         options->ciphers = xstrdup(arg);
1201                 break;
1202
1203         case oMacs:
1204                 arg = strdelim(&s);
1205                 if (!arg || *arg == '\0')
1206                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1207                 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1208                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1209                             filename, linenum, arg ? arg : "<NONE>");
1210                 if (*activep && options->macs == NULL)
1211                         options->macs = xstrdup(arg);
1212                 break;
1213
1214         case oKexAlgorithms:
1215                 arg = strdelim(&s);
1216                 if (!arg || *arg == '\0')
1217                         fatal("%.200s line %d: Missing argument.",
1218                             filename, linenum);
1219                 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1220                         fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1221                             filename, linenum, arg ? arg : "<NONE>");
1222                 if (*activep && options->kex_algorithms == NULL)
1223                         options->kex_algorithms = xstrdup(arg);
1224                 break;
1225
1226         case oHostKeyAlgorithms:
1227                 charptr = &options->hostkeyalgorithms;
1228 parse_keytypes:
1229                 arg = strdelim(&s);
1230                 if (!arg || *arg == '\0')
1231                         fatal("%.200s line %d: Missing argument.",
1232                             filename, linenum);
1233                 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1234                         fatal("%s line %d: Bad key types '%s'.",
1235                                 filename, linenum, arg ? arg : "<NONE>");
1236                 if (*activep && *charptr == NULL)
1237                         *charptr = xstrdup(arg);
1238                 break;
1239
1240         case oProtocol:
1241                 intptr = &options->protocol;
1242                 arg = strdelim(&s);
1243                 if (!arg || *arg == '\0')
1244                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1245                 value = proto_spec(arg);
1246                 if (value == SSH_PROTO_UNKNOWN)
1247                         fatal("%.200s line %d: Bad protocol spec '%s'.",
1248                             filename, linenum, arg ? arg : "<NONE>");
1249                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1250                         *intptr = value;
1251                 break;
1252
1253         case oLogLevel:
1254                 log_level_ptr = &options->log_level;
1255                 arg = strdelim(&s);
1256                 value = log_level_number(arg);
1257                 if (value == SYSLOG_LEVEL_NOT_SET)
1258                         fatal("%.200s line %d: unsupported log level '%s'",
1259                             filename, linenum, arg ? arg : "<NONE>");
1260                 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1261                         *log_level_ptr = (LogLevel) value;
1262                 break;
1263
1264         case oLocalForward:
1265         case oRemoteForward:
1266         case oDynamicForward:
1267                 arg = strdelim(&s);
1268                 if (arg == NULL || *arg == '\0')
1269                         fatal("%.200s line %d: Missing port argument.",
1270                             filename, linenum);
1271
1272                 if (opcode == oLocalForward ||
1273                     opcode == oRemoteForward) {
1274                         arg2 = strdelim(&s);
1275                         if (arg2 == NULL || *arg2 == '\0')
1276                                 fatal("%.200s line %d: Missing target argument.",
1277                                     filename, linenum);
1278
1279                         /* construct a string for parse_forward */
1280                         snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1281                 } else if (opcode == oDynamicForward) {
1282                         strlcpy(fwdarg, arg, sizeof(fwdarg));
1283                 }
1284
1285                 if (parse_forward(&fwd, fwdarg,
1286                     opcode == oDynamicForward ? 1 : 0,
1287                     opcode == oRemoteForward ? 1 : 0) == 0)
1288                         fatal("%.200s line %d: Bad forwarding specification.",
1289                             filename, linenum);
1290
1291                 if (*activep) {
1292                         if (opcode == oLocalForward ||
1293                             opcode == oDynamicForward)
1294                                 add_local_forward(options, &fwd);
1295                         else if (opcode == oRemoteForward)
1296                                 add_remote_forward(options, &fwd);
1297                 }
1298                 break;
1299
1300         case oClearAllForwardings:
1301                 intptr = &options->clear_forwardings;
1302                 goto parse_flag;
1303
1304         case oHost:
1305                 if (cmdline)
1306                         fatal("Host directive not supported as a command-line "
1307                             "option");
1308                 *activep = 0;
1309                 arg2 = NULL;
1310                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1311                         if ((flags & SSHCONF_NEVERMATCH) != 0)
1312                                 break;
1313                         negated = *arg == '!';
1314                         if (negated)
1315                                 arg++;
1316                         if (match_pattern(host, arg)) {
1317                                 if (negated) {
1318                                         debug("%.200s line %d: Skipping Host "
1319                                             "block because of negated match "
1320                                             "for %.100s", filename, linenum,
1321                                             arg);
1322                                         *activep = 0;
1323                                         break;
1324                                 }
1325                                 if (!*activep)
1326                                         arg2 = arg; /* logged below */
1327                                 *activep = 1;
1328                         }
1329                 }
1330                 if (*activep)
1331                         debug("%.200s line %d: Applying options for %.100s",
1332                             filename, linenum, arg2);
1333                 /* Avoid garbage check below, as strdelim is done. */
1334                 return 0;
1335
1336         case oMatch:
1337                 if (cmdline)
1338                         fatal("Host directive not supported as a command-line "
1339                             "option");
1340                 value = match_cfg_line(options, &s, pw, host, original_host,
1341                     flags & SSHCONF_POSTCANON, filename, linenum);
1342                 if (value < 0)
1343                         fatal("%.200s line %d: Bad Match condition", filename,
1344                             linenum);
1345                 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1346                 break;
1347
1348         case oEscapeChar:
1349                 intptr = &options->escape_char;
1350                 arg = strdelim(&s);
1351                 if (!arg || *arg == '\0')
1352                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1353                 if (strcmp(arg, "none") == 0)
1354                         value = SSH_ESCAPECHAR_NONE;
1355                 else if (arg[1] == '\0')
1356                         value = (u_char) arg[0];
1357                 else if (arg[0] == '^' && arg[2] == 0 &&
1358                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1359                         value = (u_char) arg[1] & 31;
1360                 else {
1361                         fatal("%.200s line %d: Bad escape character.",
1362                             filename, linenum);
1363                         /* NOTREACHED */
1364                         value = 0;      /* Avoid compiler warning. */
1365                 }
1366                 if (*activep && *intptr == -1)
1367                         *intptr = value;
1368                 break;
1369
1370         case oAddressFamily:
1371                 intptr = &options->address_family;
1372                 multistate_ptr = multistate_addressfamily;
1373                 goto parse_multistate;
1374
1375         case oEnableSSHKeysign:
1376                 intptr = &options->enable_ssh_keysign;
1377                 goto parse_flag;
1378
1379         case oIdentitiesOnly:
1380                 intptr = &options->identities_only;
1381                 goto parse_flag;
1382
1383         case oServerAliveInterval:
1384                 intptr = &options->server_alive_interval;
1385                 goto parse_time;
1386
1387         case oServerAliveCountMax:
1388                 intptr = &options->server_alive_count_max;
1389                 goto parse_int;
1390
1391         case oSendEnv:
1392                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1393                         if (strchr(arg, '=') != NULL)
1394                                 fatal("%s line %d: Invalid environment name.",
1395                                     filename, linenum);
1396                         if (!*activep)
1397                                 continue;
1398                         if (options->num_send_env >= MAX_SEND_ENV)
1399                                 fatal("%s line %d: too many send env.",
1400                                     filename, linenum);
1401                         options->send_env[options->num_send_env++] =
1402                             xstrdup(arg);
1403                 }
1404                 break;
1405
1406         case oControlPath:
1407                 charptr = &options->control_path;
1408                 goto parse_string;
1409
1410         case oControlMaster:
1411                 intptr = &options->control_master;
1412                 multistate_ptr = multistate_controlmaster;
1413                 goto parse_multistate;
1414
1415         case oControlPersist:
1416                 /* no/false/yes/true, or a time spec */
1417                 intptr = &options->control_persist;
1418                 arg = strdelim(&s);
1419                 if (!arg || *arg == '\0')
1420                         fatal("%.200s line %d: Missing ControlPersist"
1421                             " argument.", filename, linenum);
1422                 value = 0;
1423                 value2 = 0;     /* timeout */
1424                 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1425                         value = 0;
1426                 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1427                         value = 1;
1428                 else if ((value2 = convtime(arg)) >= 0)
1429                         value = 1;
1430                 else
1431                         fatal("%.200s line %d: Bad ControlPersist argument.",
1432                             filename, linenum);
1433                 if (*activep && *intptr == -1) {
1434                         *intptr = value;
1435                         options->control_persist_timeout = value2;
1436                 }
1437                 break;
1438
1439         case oHashKnownHosts:
1440                 intptr = &options->hash_known_hosts;
1441                 goto parse_flag;
1442
1443         case oTunnel:
1444                 intptr = &options->tun_open;
1445                 multistate_ptr = multistate_tunnel;
1446                 goto parse_multistate;
1447
1448         case oTunnelDevice:
1449                 arg = strdelim(&s);
1450                 if (!arg || *arg == '\0')
1451                         fatal("%.200s line %d: Missing argument.", filename, linenum);
1452                 value = a2tun(arg, &value2);
1453                 if (value == SSH_TUNID_ERR)
1454                         fatal("%.200s line %d: Bad tun device.", filename, linenum);
1455                 if (*activep) {
1456                         options->tun_local = value;
1457                         options->tun_remote = value2;
1458                 }
1459                 break;
1460
1461         case oLocalCommand:
1462                 charptr = &options->local_command;
1463                 goto parse_command;
1464
1465         case oPermitLocalCommand:
1466                 intptr = &options->permit_local_command;
1467                 goto parse_flag;
1468
1469         case oVisualHostKey:
1470                 intptr = &options->visual_host_key;
1471                 goto parse_flag;
1472
1473         case oInclude:
1474                 if (cmdline)
1475                         fatal("Include directive not supported as a "
1476                             "command-line option");
1477                 value = 0;
1478                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1479                         /*
1480                          * Ensure all paths are anchored. User configuration
1481                          * files may begin with '~/' but system configurations
1482                          * must not. If the path is relative, then treat it
1483                          * as living in ~/.ssh for user configurations or
1484                          * /etc/ssh for system ones.
1485                          */
1486                         if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1487                                 fatal("%.200s line %d: bad include path %s.",
1488                                     filename, linenum, arg);
1489                         if (*arg != '/' && *arg != '~') {
1490                                 xasprintf(&arg2, "%s/%s",
1491                                     (flags & SSHCONF_USERCONF) ?
1492                                     "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1493                         } else
1494                                 arg2 = xstrdup(arg);
1495                         memset(&gl, 0, sizeof(gl));
1496                         r = glob(arg2, GLOB_TILDE, NULL, &gl);
1497                         if (r == GLOB_NOMATCH) {
1498                                 debug("%.200s line %d: include %s matched no "
1499                                     "files",filename, linenum, arg2);
1500                                 continue;
1501                         } else if (r != 0 || gl.gl_pathc < 0)
1502                                 fatal("%.200s line %d: glob failed for %s.",
1503                                     filename, linenum, arg2);
1504                         free(arg2);
1505                         oactive = *activep;
1506                         for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1507                                 debug3("%.200s line %d: Including file %s "
1508                                     "depth %d%s", filename, linenum,
1509                                     gl.gl_pathv[i], depth,
1510                                     oactive ? "" : " (parse only)");
1511                                 r = read_config_file_depth(gl.gl_pathv[i],
1512                                     pw, host, original_host, options,
1513                                     flags | SSHCONF_CHECKPERM |
1514                                     (oactive ? 0 : SSHCONF_NEVERMATCH),
1515                                     activep, depth + 1);
1516                                 /*
1517                                  * don't let Match in includes clobber the
1518                                  * containing file's Match state.
1519                                  */
1520                                 *activep = oactive;
1521                                 if (r != 1)
1522                                         value = -1;
1523                         }
1524                         globfree(&gl);
1525                 }
1526                 if (value != 0)
1527                         return value;
1528                 break;
1529
1530         case oIPQoS:
1531                 arg = strdelim(&s);
1532                 if ((value = parse_ipqos(arg)) == -1)
1533                         fatal("%s line %d: Bad IPQoS value: %s",
1534                             filename, linenum, arg);
1535                 arg = strdelim(&s);
1536                 if (arg == NULL)
1537                         value2 = value;
1538                 else if ((value2 = parse_ipqos(arg)) == -1)
1539                         fatal("%s line %d: Bad IPQoS value: %s",
1540                             filename, linenum, arg);
1541                 if (*activep) {
1542                         options->ip_qos_interactive = value;
1543                         options->ip_qos_bulk = value2;
1544                 }
1545                 break;
1546
1547         case oRequestTTY:
1548                 intptr = &options->request_tty;
1549                 multistate_ptr = multistate_requesttty;
1550                 goto parse_multistate;
1551
1552         case oVersionAddendum:
1553                 if (s == NULL)
1554                         fatal("%.200s line %d: Missing argument.", filename,
1555                             linenum);
1556                 len = strspn(s, WHITESPACE);
1557                 if (*activep && options->version_addendum == NULL) {
1558                         if (strcasecmp(s + len, "none") == 0)
1559                                 options->version_addendum = xstrdup("");
1560                         else if (strchr(s + len, '\r') != NULL)
1561                                 fatal("%.200s line %d: Invalid argument",
1562                                     filename, linenum);
1563                         else
1564                                 options->version_addendum = xstrdup(s + len);
1565                 }
1566                 return 0;
1567
1568         case oIgnoreUnknown:
1569                 charptr = &options->ignored_unknown;
1570                 goto parse_string;
1571
1572         case oProxyUseFdpass:
1573                 intptr = &options->proxy_use_fdpass;
1574                 goto parse_flag;
1575
1576         case oCanonicalDomains:
1577                 value = options->num_canonical_domains != 0;
1578                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1579                         valid_domain(arg, filename, linenum);
1580                         if (!*activep || value)
1581                                 continue;
1582                         if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1583                                 fatal("%s line %d: too many hostname suffixes.",
1584                                     filename, linenum);
1585                         options->canonical_domains[
1586                             options->num_canonical_domains++] = xstrdup(arg);
1587                 }
1588                 break;
1589
1590         case oCanonicalizePermittedCNAMEs:
1591                 value = options->num_permitted_cnames != 0;
1592                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1593                         /* Either '*' for everything or 'list:list' */
1594                         if (strcmp(arg, "*") == 0)
1595                                 arg2 = arg;
1596                         else {
1597                                 lowercase(arg);
1598                                 if ((arg2 = strchr(arg, ':')) == NULL ||
1599                                     arg2[1] == '\0') {
1600                                         fatal("%s line %d: "
1601                                             "Invalid permitted CNAME \"%s\"",
1602                                             filename, linenum, arg);
1603                                 }
1604                                 *arg2 = '\0';
1605                                 arg2++;
1606                         }
1607                         if (!*activep || value)
1608                                 continue;
1609                         if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1610                                 fatal("%s line %d: too many permitted CNAMEs.",
1611                                     filename, linenum);
1612                         cname = options->permitted_cnames +
1613                             options->num_permitted_cnames++;
1614                         cname->source_list = xstrdup(arg);
1615                         cname->target_list = xstrdup(arg2);
1616                 }
1617                 break;
1618
1619         case oCanonicalizeHostname:
1620                 intptr = &options->canonicalize_hostname;
1621                 multistate_ptr = multistate_canonicalizehostname;
1622                 goto parse_multistate;
1623
1624         case oCanonicalizeMaxDots:
1625                 intptr = &options->canonicalize_max_dots;
1626                 goto parse_int;
1627
1628         case oCanonicalizeFallbackLocal:
1629                 intptr = &options->canonicalize_fallback_local;
1630                 goto parse_flag;
1631
1632         case oStreamLocalBindMask:
1633                 arg = strdelim(&s);
1634                 if (!arg || *arg == '\0')
1635                         fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1636                 /* Parse mode in octal format */
1637                 value = strtol(arg, &endofnumber, 8);
1638                 if (arg == endofnumber || value < 0 || value > 0777)
1639                         fatal("%.200s line %d: Bad mask.", filename, linenum);
1640                 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1641                 break;
1642
1643         case oStreamLocalBindUnlink:
1644                 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1645                 goto parse_flag;
1646
1647         case oRevokedHostKeys:
1648                 charptr = &options->revoked_host_keys;
1649                 goto parse_string;
1650
1651         case oFingerprintHash:
1652                 intptr = &options->fingerprint_hash;
1653                 arg = strdelim(&s);
1654                 if (!arg || *arg == '\0')
1655                         fatal("%.200s line %d: Missing argument.",
1656                             filename, linenum);
1657                 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1658                         fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1659                             filename, linenum, arg);
1660                 if (*activep && *intptr == -1)
1661                         *intptr = value;
1662                 break;
1663
1664         case oUpdateHostkeys:
1665                 intptr = &options->update_hostkeys;
1666                 multistate_ptr = multistate_yesnoask;
1667                 goto parse_multistate;
1668
1669         case oHostbasedKeyTypes:
1670                 charptr = &options->hostbased_key_types;
1671                 goto parse_keytypes;
1672
1673         case oPubkeyAcceptedKeyTypes:
1674                 charptr = &options->pubkey_key_types;
1675                 goto parse_keytypes;
1676
1677         case oAddKeysToAgent:
1678                 intptr = &options->add_keys_to_agent;
1679                 multistate_ptr = multistate_yesnoaskconfirm;
1680                 goto parse_multistate;
1681
1682         case oIdentityAgent:
1683                 charptr = &options->identity_agent;
1684                 goto parse_string;
1685
1686         case oDeprecated:
1687                 debug("%s line %d: Deprecated option \"%s\"",
1688                     filename, linenum, keyword);
1689                 return 0;
1690
1691         case oUnsupported:
1692                 error("%s line %d: Unsupported option \"%s\"",
1693                     filename, linenum, keyword);
1694                 return 0;
1695
1696         default:
1697                 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1698         }
1699
1700         /* Check that there is no garbage at end of line. */
1701         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1702                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1703                     filename, linenum, arg);
1704         }
1705         return 0;
1706 }
1707
1708 /*
1709  * Reads the config file and modifies the options accordingly.  Options
1710  * should already be initialized before this call.  This never returns if
1711  * there is an error.  If the file does not exist, this returns 0.
1712  */
1713 int
1714 read_config_file(const char *filename, struct passwd *pw, const char *host,
1715     const char *original_host, Options *options, int flags)
1716 {
1717         int active = 1;
1718
1719         return read_config_file_depth(filename, pw, host, original_host,
1720             options, flags, &active, 0);
1721 }
1722
1723 #define READCONF_MAX_DEPTH      16
1724 static int
1725 read_config_file_depth(const char *filename, struct passwd *pw,
1726     const char *host, const char *original_host, Options *options,
1727     int flags, int *activep, int depth)
1728 {
1729         FILE *f;
1730         char line[1024];
1731         int linenum;
1732         int bad_options = 0;
1733
1734         if (depth < 0 || depth > READCONF_MAX_DEPTH)
1735                 fatal("Too many recursive configuration includes");
1736
1737         if ((f = fopen(filename, "r")) == NULL)
1738                 return 0;
1739
1740         if (flags & SSHCONF_CHECKPERM) {
1741                 struct stat sb;
1742
1743                 if (fstat(fileno(f), &sb) == -1)
1744                         fatal("fstat %s: %s", filename, strerror(errno));
1745                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1746                     (sb.st_mode & 022) != 0))
1747                         fatal("Bad owner or permissions on %s", filename);
1748         }
1749
1750         debug("Reading configuration data %.200s", filename);
1751
1752         /*
1753          * Mark that we are now processing the options.  This flag is turned
1754          * on/off by Host specifications.
1755          */
1756         linenum = 0;
1757         while (fgets(line, sizeof(line), f)) {
1758                 /* Update line number counter. */
1759                 linenum++;
1760                 if (process_config_line_depth(options, pw, host, original_host,
1761                     line, filename, linenum, activep, flags, depth) != 0)
1762                         bad_options++;
1763         }
1764         fclose(f);
1765         if (bad_options > 0)
1766                 fatal("%s: terminating, %d bad configuration options",
1767                     filename, bad_options);
1768         return 1;
1769 }
1770
1771 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1772 int
1773 option_clear_or_none(const char *o)
1774 {
1775         return o == NULL || strcasecmp(o, "none") == 0;
1776 }
1777
1778 /*
1779  * Initializes options to special values that indicate that they have not yet
1780  * been set.  Read_config_file will only set options with this value. Options
1781  * are processed in the following order: command line, user config file,
1782  * system config file.  Last, fill_default_options is called.
1783  */
1784
1785 void
1786 initialize_options(Options * options)
1787 {
1788         memset(options, 'X', sizeof(*options));
1789         options->version_addendum = NULL;
1790         options->forward_agent = -1;
1791         options->forward_x11 = -1;
1792         options->forward_x11_trusted = -1;
1793         options->forward_x11_timeout = -1;
1794         options->stdio_forward_host = NULL;
1795         options->stdio_forward_port = 0;
1796         options->clear_forwardings = -1;
1797         options->exit_on_forward_failure = -1;
1798         options->xauth_location = NULL;
1799         options->fwd_opts.gateway_ports = -1;
1800         options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1801         options->fwd_opts.streamlocal_bind_unlink = -1;
1802         options->use_privileged_port = -1;
1803         options->rsa_authentication = -1;
1804         options->pubkey_authentication = -1;
1805         options->challenge_response_authentication = -1;
1806         options->gss_authentication = -1;
1807         options->gss_deleg_creds = -1;
1808         options->password_authentication = -1;
1809         options->kbd_interactive_authentication = -1;
1810         options->kbd_interactive_devices = NULL;
1811         options->rhosts_rsa_authentication = -1;
1812         options->hostbased_authentication = -1;
1813         options->batch_mode = -1;
1814         options->check_host_ip = -1;
1815         options->strict_host_key_checking = -1;
1816         options->compression = -1;
1817         options->tcp_keep_alive = -1;
1818         options->compression_level = -1;
1819         options->port = -1;
1820         options->address_family = -1;
1821         options->connection_attempts = -1;
1822         options->connection_timeout = -1;
1823         options->number_of_password_prompts = -1;
1824         options->cipher = -1;
1825         options->ciphers = NULL;
1826         options->macs = NULL;
1827         options->kex_algorithms = NULL;
1828         options->hostkeyalgorithms = NULL;
1829         options->protocol = SSH_PROTO_UNKNOWN;
1830         options->num_identity_files = 0;
1831         options->num_certificate_files = 0;
1832         options->hostname = NULL;
1833         options->host_key_alias = NULL;
1834         options->proxy_command = NULL;
1835         options->jump_user = NULL;
1836         options->jump_host = NULL;
1837         options->jump_port = -1;
1838         options->jump_extra = NULL;
1839         options->user = NULL;
1840         options->escape_char = -1;
1841         options->num_system_hostfiles = 0;
1842         options->num_user_hostfiles = 0;
1843         options->local_forwards = NULL;
1844         options->num_local_forwards = 0;
1845         options->remote_forwards = NULL;
1846         options->num_remote_forwards = 0;
1847         options->log_level = SYSLOG_LEVEL_NOT_SET;
1848         options->preferred_authentications = NULL;
1849         options->bind_address = NULL;
1850         options->pkcs11_provider = NULL;
1851         options->enable_ssh_keysign = - 1;
1852         options->no_host_authentication_for_localhost = - 1;
1853         options->identities_only = - 1;
1854         options->rekey_limit = - 1;
1855         options->rekey_interval = -1;
1856         options->verify_host_key_dns = -1;
1857         options->server_alive_interval = -1;
1858         options->server_alive_count_max = -1;
1859         options->num_send_env = 0;
1860         options->control_path = NULL;
1861         options->control_master = -1;
1862         options->control_persist = -1;
1863         options->control_persist_timeout = 0;
1864         options->hash_known_hosts = -1;
1865         options->tun_open = -1;
1866         options->tun_local = -1;
1867         options->tun_remote = -1;
1868         options->local_command = NULL;
1869         options->permit_local_command = -1;
1870         options->add_keys_to_agent = -1;
1871         options->identity_agent = NULL;
1872         options->visual_host_key = -1;
1873         options->ip_qos_interactive = -1;
1874         options->ip_qos_bulk = -1;
1875         options->request_tty = -1;
1876         options->proxy_use_fdpass = -1;
1877         options->ignored_unknown = NULL;
1878         options->num_canonical_domains = 0;
1879         options->num_permitted_cnames = 0;
1880         options->canonicalize_max_dots = -1;
1881         options->canonicalize_fallback_local = -1;
1882         options->canonicalize_hostname = -1;
1883         options->revoked_host_keys = NULL;
1884         options->fingerprint_hash = -1;
1885         options->update_hostkeys = -1;
1886         options->hostbased_key_types = NULL;
1887         options->pubkey_key_types = NULL;
1888 }
1889
1890 /*
1891  * A petite version of fill_default_options() that just fills the options
1892  * needed for hostname canonicalization to proceed.
1893  */
1894 void
1895 fill_default_options_for_canonicalization(Options *options)
1896 {
1897         if (options->canonicalize_max_dots == -1)
1898                 options->canonicalize_max_dots = 1;
1899         if (options->canonicalize_fallback_local == -1)
1900                 options->canonicalize_fallback_local = 1;
1901         if (options->canonicalize_hostname == -1)
1902                 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1903 }
1904
1905 /*
1906  * Called after processing other sources of option data, this fills those
1907  * options for which no value has been specified with their default values.
1908  */
1909 void
1910 fill_default_options(Options * options)
1911 {
1912         if (options->forward_agent == -1)
1913                 options->forward_agent = 0;
1914         if (options->forward_x11 == -1)
1915                 options->forward_x11 = 0;
1916         if (options->forward_x11_trusted == -1)
1917                 options->forward_x11_trusted = 0;
1918         if (options->forward_x11_timeout == -1)
1919                 options->forward_x11_timeout = 1200;
1920         /*
1921          * stdio forwarding (-W) changes the default for these but we defer
1922          * setting the values so they can be overridden.
1923          */
1924         if (options->exit_on_forward_failure == -1)
1925                 options->exit_on_forward_failure =
1926                     options->stdio_forward_host != NULL ? 1 : 0;
1927         if (options->clear_forwardings == -1)
1928                 options->clear_forwardings =
1929                     options->stdio_forward_host != NULL ? 1 : 0;
1930         if (options->clear_forwardings == 1)
1931                 clear_forwardings(options);
1932
1933         if (options->xauth_location == NULL)
1934                 options->xauth_location = _PATH_XAUTH;
1935         if (options->fwd_opts.gateway_ports == -1)
1936                 options->fwd_opts.gateway_ports = 0;
1937         if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1938                 options->fwd_opts.streamlocal_bind_mask = 0177;
1939         if (options->fwd_opts.streamlocal_bind_unlink == -1)
1940                 options->fwd_opts.streamlocal_bind_unlink = 0;
1941         if (options->use_privileged_port == -1)
1942                 options->use_privileged_port = 0;
1943         if (options->rsa_authentication == -1)
1944                 options->rsa_authentication = 1;
1945         if (options->pubkey_authentication == -1)
1946                 options->pubkey_authentication = 1;
1947         if (options->challenge_response_authentication == -1)
1948                 options->challenge_response_authentication = 1;
1949         if (options->gss_authentication == -1)
1950                 options->gss_authentication = 0;
1951         if (options->gss_deleg_creds == -1)
1952                 options->gss_deleg_creds = 0;
1953         if (options->password_authentication == -1)
1954                 options->password_authentication = 1;
1955         if (options->kbd_interactive_authentication == -1)
1956                 options->kbd_interactive_authentication = 1;
1957         if (options->rhosts_rsa_authentication == -1)
1958                 options->rhosts_rsa_authentication = 0;
1959         if (options->hostbased_authentication == -1)
1960                 options->hostbased_authentication = 0;
1961         if (options->batch_mode == -1)
1962                 options->batch_mode = 0;
1963         if (options->check_host_ip == -1)
1964                 options->check_host_ip = 0;
1965         if (options->strict_host_key_checking == -1)
1966                 options->strict_host_key_checking = 2;  /* 2 is default */
1967         if (options->compression == -1)
1968                 options->compression = 0;
1969         if (options->tcp_keep_alive == -1)
1970                 options->tcp_keep_alive = 1;
1971         if (options->compression_level == -1)
1972                 options->compression_level = 6;
1973         if (options->port == -1)
1974                 options->port = 0;      /* Filled in ssh_connect. */
1975         if (options->address_family == -1)
1976                 options->address_family = AF_UNSPEC;
1977         if (options->connection_attempts == -1)
1978                 options->connection_attempts = 1;
1979         if (options->number_of_password_prompts == -1)
1980                 options->number_of_password_prompts = 3;
1981         /* Selected in ssh_login(). */
1982         if (options->cipher == -1)
1983                 options->cipher = SSH_CIPHER_NOT_SET;
1984         /* options->hostkeyalgorithms, default set in myproposals.h */
1985         if (options->protocol == SSH_PROTO_UNKNOWN)
1986                 options->protocol = SSH_PROTO_2;
1987         if (options->add_keys_to_agent == -1)
1988                 options->add_keys_to_agent = 0;
1989         if (options->num_identity_files == 0) {
1990                 if (options->protocol & SSH_PROTO_1) {
1991                         add_identity_file(options, "~/",
1992                             _PATH_SSH_CLIENT_IDENTITY, 0);
1993                 }
1994                 if (options->protocol & SSH_PROTO_2) {
1995                         add_identity_file(options, "~/",
1996                             _PATH_SSH_CLIENT_ID_RSA, 0);
1997                         add_identity_file(options, "~/",
1998                             _PATH_SSH_CLIENT_ID_DSA, 0);
1999 #ifdef OPENSSL_HAS_ECC
2000                         add_identity_file(options, "~/",
2001                             _PATH_SSH_CLIENT_ID_ECDSA, 0);
2002 #endif
2003                         add_identity_file(options, "~/",
2004                             _PATH_SSH_CLIENT_ID_ED25519, 0);
2005                 }
2006         }
2007         if (options->escape_char == -1)
2008                 options->escape_char = '~';
2009         if (options->num_system_hostfiles == 0) {
2010                 options->system_hostfiles[options->num_system_hostfiles++] =
2011                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2012                 options->system_hostfiles[options->num_system_hostfiles++] =
2013                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2014         }
2015         if (options->num_user_hostfiles == 0) {
2016                 options->user_hostfiles[options->num_user_hostfiles++] =
2017                     xstrdup(_PATH_SSH_USER_HOSTFILE);
2018                 options->user_hostfiles[options->num_user_hostfiles++] =
2019                     xstrdup(_PATH_SSH_USER_HOSTFILE2);
2020         }
2021         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2022                 options->log_level = SYSLOG_LEVEL_INFO;
2023         if (options->no_host_authentication_for_localhost == - 1)
2024                 options->no_host_authentication_for_localhost = 0;
2025         if (options->identities_only == -1)
2026                 options->identities_only = 0;
2027         if (options->enable_ssh_keysign == -1)
2028                 options->enable_ssh_keysign = 0;
2029         if (options->rekey_limit == -1)
2030                 options->rekey_limit = 0;
2031         if (options->rekey_interval == -1)
2032                 options->rekey_interval = 0;
2033 #if HAVE_LDNS
2034         if (options->verify_host_key_dns == -1)
2035                 /* automatically trust a verified SSHFP record */
2036                 options->verify_host_key_dns = 1;
2037 #else
2038         if (options->verify_host_key_dns == -1)
2039                 options->verify_host_key_dns = 0;
2040 #endif
2041         if (options->server_alive_interval == -1)
2042                 options->server_alive_interval = 0;
2043         if (options->server_alive_count_max == -1)
2044                 options->server_alive_count_max = 3;
2045         if (options->control_master == -1)
2046                 options->control_master = 0;
2047         if (options->control_persist == -1) {
2048                 options->control_persist = 0;
2049                 options->control_persist_timeout = 0;
2050         }
2051         if (options->hash_known_hosts == -1)
2052                 options->hash_known_hosts = 0;
2053         if (options->tun_open == -1)
2054                 options->tun_open = SSH_TUNMODE_NO;
2055         if (options->tun_local == -1)
2056                 options->tun_local = SSH_TUNID_ANY;
2057         if (options->tun_remote == -1)
2058                 options->tun_remote = SSH_TUNID_ANY;
2059         if (options->permit_local_command == -1)
2060                 options->permit_local_command = 0;
2061         if (options->visual_host_key == -1)
2062                 options->visual_host_key = 0;
2063         if (options->ip_qos_interactive == -1)
2064                 options->ip_qos_interactive = IPTOS_LOWDELAY;
2065         if (options->ip_qos_bulk == -1)
2066                 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2067         if (options->request_tty == -1)
2068                 options->request_tty = REQUEST_TTY_AUTO;
2069         if (options->proxy_use_fdpass == -1)
2070                 options->proxy_use_fdpass = 0;
2071         if (options->canonicalize_max_dots == -1)
2072                 options->canonicalize_max_dots = 1;
2073         if (options->canonicalize_fallback_local == -1)
2074                 options->canonicalize_fallback_local = 1;
2075         if (options->canonicalize_hostname == -1)
2076                 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2077         if (options->fingerprint_hash == -1)
2078                 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2079         if (options->update_hostkeys == -1)
2080                 options->update_hostkeys = 0;
2081         if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2082             kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2083             kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2084             kex_assemble_names(KEX_DEFAULT_PK_ALG,
2085             &options->hostbased_key_types) != 0 ||
2086             kex_assemble_names(KEX_DEFAULT_PK_ALG,
2087             &options->pubkey_key_types) != 0)
2088                 fatal("%s: kex_assemble_names failed", __func__);
2089
2090 #define CLEAR_ON_NONE(v) \
2091         do { \
2092                 if (option_clear_or_none(v)) { \
2093                         free(v); \
2094                         v = NULL; \
2095                 } \
2096         } while(0)
2097         CLEAR_ON_NONE(options->local_command);
2098         CLEAR_ON_NONE(options->proxy_command);
2099         CLEAR_ON_NONE(options->control_path);
2100         CLEAR_ON_NONE(options->revoked_host_keys);
2101         /* options->identity_agent distinguishes NULL from 'none' */
2102         /* options->user will be set in the main program if appropriate */
2103         /* options->hostname will be set in the main program if appropriate */
2104         /* options->host_key_alias should not be set by default */
2105         /* options->preferred_authentications will be set in ssh */
2106         if (options->version_addendum == NULL)
2107                 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2108 }
2109
2110 struct fwdarg {
2111         char *arg;
2112         int ispath;
2113 };
2114
2115 /*
2116  * parse_fwd_field
2117  * parses the next field in a port forwarding specification.
2118  * sets fwd to the parsed field and advances p past the colon
2119  * or sets it to NULL at end of string.
2120  * returns 0 on success, else non-zero.
2121  */
2122 static int
2123 parse_fwd_field(char **p, struct fwdarg *fwd)
2124 {
2125         char *ep, *cp = *p;
2126         int ispath = 0;
2127
2128         if (*cp == '\0') {
2129                 *p = NULL;
2130                 return -1;      /* end of string */
2131         }
2132
2133         /*
2134          * A field escaped with square brackets is used literally.
2135          * XXX - allow ']' to be escaped via backslash?
2136          */
2137         if (*cp == '[') {
2138                 /* find matching ']' */
2139                 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2140                         if (*ep == '/')
2141                                 ispath = 1;
2142                 }
2143                 /* no matching ']' or not at end of field. */
2144                 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2145                         return -1;
2146                 /* NUL terminate the field and advance p past the colon */
2147                 *ep++ = '\0';
2148                 if (*ep != '\0')
2149                         *ep++ = '\0';
2150                 fwd->arg = cp + 1;
2151                 fwd->ispath = ispath;
2152                 *p = ep;
2153                 return 0;
2154         }
2155
2156         for (cp = *p; *cp != '\0'; cp++) {
2157                 switch (*cp) {
2158                 case '\\':
2159                         memmove(cp, cp + 1, strlen(cp + 1) + 1);
2160                         if (*cp == '\0')
2161                                 return -1;
2162                         break;
2163                 case '/':
2164                         ispath = 1;
2165                         break;
2166                 case ':':
2167                         *cp++ = '\0';
2168                         goto done;
2169                 }
2170         }
2171 done:
2172         fwd->arg = *p;
2173         fwd->ispath = ispath;
2174         *p = cp;
2175         return 0;
2176 }
2177
2178 /*
2179  * parse_forward
2180  * parses a string containing a port forwarding specification of the form:
2181  *   dynamicfwd == 0
2182  *      [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2183  *      listenpath:connectpath
2184  *   dynamicfwd == 1
2185  *      [listenhost:]listenport
2186  * returns number of arguments parsed or zero on error
2187  */
2188 int
2189 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2190 {
2191         struct fwdarg fwdargs[4];
2192         char *p, *cp;
2193         int i;
2194
2195         memset(fwd, 0, sizeof(*fwd));
2196         memset(fwdargs, 0, sizeof(fwdargs));
2197
2198         cp = p = xstrdup(fwdspec);
2199
2200         /* skip leading spaces */
2201         while (isspace((u_char)*cp))
2202                 cp++;
2203
2204         for (i = 0; i < 4; ++i) {
2205                 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2206                         break;
2207         }
2208
2209         /* Check for trailing garbage */
2210         if (cp != NULL && *cp != '\0') {
2211                 i = 0;  /* failure */
2212         }
2213
2214         switch (i) {
2215         case 1:
2216                 if (fwdargs[0].ispath) {
2217                         fwd->listen_path = xstrdup(fwdargs[0].arg);
2218                         fwd->listen_port = PORT_STREAMLOCAL;
2219                 } else {
2220                         fwd->listen_host = NULL;
2221                         fwd->listen_port = a2port(fwdargs[0].arg);
2222                 }
2223                 fwd->connect_host = xstrdup("socks");
2224                 break;
2225
2226         case 2:
2227                 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2228                         fwd->listen_path = xstrdup(fwdargs[0].arg);
2229                         fwd->listen_port = PORT_STREAMLOCAL;
2230                         fwd->connect_path = xstrdup(fwdargs[1].arg);
2231                         fwd->connect_port = PORT_STREAMLOCAL;
2232                 } else if (fwdargs[1].ispath) {
2233                         fwd->listen_host = NULL;
2234                         fwd->listen_port = a2port(fwdargs[0].arg);
2235                         fwd->connect_path = xstrdup(fwdargs[1].arg);
2236                         fwd->connect_port = PORT_STREAMLOCAL;
2237                 } else {
2238                         fwd->listen_host = xstrdup(fwdargs[0].arg);
2239                         fwd->listen_port = a2port(fwdargs[1].arg);
2240                         fwd->connect_host = xstrdup("socks");
2241                 }
2242                 break;
2243
2244         case 3:
2245                 if (fwdargs[0].ispath) {
2246                         fwd->listen_path = xstrdup(fwdargs[0].arg);
2247                         fwd->listen_port = PORT_STREAMLOCAL;
2248                         fwd->connect_host = xstrdup(fwdargs[1].arg);
2249                         fwd->connect_port = a2port(fwdargs[2].arg);
2250                 } else if (fwdargs[2].ispath) {
2251                         fwd->listen_host = xstrdup(fwdargs[0].arg);
2252                         fwd->listen_port = a2port(fwdargs[1].arg);
2253                         fwd->connect_path = xstrdup(fwdargs[2].arg);
2254                         fwd->connect_port = PORT_STREAMLOCAL;
2255                 } else {
2256                         fwd->listen_host = NULL;
2257                         fwd->listen_port = a2port(fwdargs[0].arg);
2258                         fwd->connect_host = xstrdup(fwdargs[1].arg);
2259                         fwd->connect_port = a2port(fwdargs[2].arg);
2260                 }
2261                 break;
2262
2263         case 4:
2264                 fwd->listen_host = xstrdup(fwdargs[0].arg);
2265                 fwd->listen_port = a2port(fwdargs[1].arg);
2266                 fwd->connect_host = xstrdup(fwdargs[2].arg);
2267                 fwd->connect_port = a2port(fwdargs[3].arg);
2268                 break;
2269         default:
2270                 i = 0; /* failure */
2271         }
2272
2273         free(p);
2274
2275         if (dynamicfwd) {
2276                 if (!(i == 1 || i == 2))
2277                         goto fail_free;
2278         } else {
2279                 if (!(i == 3 || i == 4)) {
2280                         if (fwd->connect_path == NULL &&
2281                             fwd->listen_path == NULL)
2282                                 goto fail_free;
2283                 }
2284                 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2285                         goto fail_free;
2286         }
2287
2288         if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2289             (!remotefwd && fwd->listen_port == 0))
2290                 goto fail_free;
2291         if (fwd->connect_host != NULL &&
2292             strlen(fwd->connect_host) >= NI_MAXHOST)
2293                 goto fail_free;
2294         /* XXX - if connecting to a remote socket, max sun len may not match this host */
2295         if (fwd->connect_path != NULL &&
2296             strlen(fwd->connect_path) >= PATH_MAX_SUN)
2297                 goto fail_free;
2298         if (fwd->listen_host != NULL &&
2299             strlen(fwd->listen_host) >= NI_MAXHOST)
2300                 goto fail_free;
2301         if (fwd->listen_path != NULL &&
2302             strlen(fwd->listen_path) >= PATH_MAX_SUN)
2303                 goto fail_free;
2304
2305         return (i);
2306
2307  fail_free:
2308         free(fwd->connect_host);
2309         fwd->connect_host = NULL;
2310         free(fwd->connect_path);
2311         fwd->connect_path = NULL;
2312         free(fwd->listen_host);
2313         fwd->listen_host = NULL;
2314         free(fwd->listen_path);
2315         fwd->listen_path = NULL;
2316         return (0);
2317 }
2318
2319 int
2320 parse_jump(const char *s, Options *o, int active)
2321 {
2322         char *orig, *sdup, *cp;
2323         char *host = NULL, *user = NULL;
2324         int ret = -1, port = -1, first;
2325
2326         active &= o->proxy_command == NULL && o->jump_host == NULL;
2327
2328         orig = sdup = xstrdup(s);
2329         first = active;
2330         do {
2331                 if ((cp = strrchr(sdup, ',')) == NULL)
2332                         cp = sdup; /* last */
2333                 else
2334                         *cp++ = '\0';
2335
2336                 if (first) {
2337                         /* First argument and configuration is active */
2338                         if (parse_user_host_port(cp, &user, &host, &port) != 0)
2339                                 goto out;
2340                 } else {
2341                         /* Subsequent argument or inactive configuration */
2342                         if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2343                                 goto out;
2344                 }
2345                 first = 0; /* only check syntax for subsequent hosts */
2346         } while (cp != sdup);
2347         /* success */
2348         if (active) {
2349                 o->jump_user = user;
2350                 o->jump_host = host;
2351                 o->jump_port = port;
2352                 o->proxy_command = xstrdup("none");
2353                 user = host = NULL;
2354                 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2355                         o->jump_extra = xstrdup(s);
2356                         o->jump_extra[cp - s] = '\0';
2357                 }
2358         }
2359         ret = 0;
2360  out:
2361         free(orig);
2362         free(user);
2363         free(host);
2364         return ret;
2365 }
2366
2367 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2368 static const char *
2369 fmt_multistate_int(int val, const struct multistate *m)
2370 {
2371         u_int i;
2372
2373         for (i = 0; m[i].key != NULL; i++) {
2374                 if (m[i].value == val)
2375                         return m[i].key;
2376         }
2377         return "UNKNOWN";
2378 }
2379
2380 static const char *
2381 fmt_intarg(OpCodes code, int val)
2382 {
2383         if (val == -1)
2384                 return "unset";
2385         switch (code) {
2386         case oAddressFamily:
2387                 return fmt_multistate_int(val, multistate_addressfamily);
2388         case oVerifyHostKeyDNS:
2389         case oStrictHostKeyChecking:
2390         case oUpdateHostkeys:
2391                 return fmt_multistate_int(val, multistate_yesnoask);
2392         case oControlMaster:
2393                 return fmt_multistate_int(val, multistate_controlmaster);
2394         case oTunnel:
2395                 return fmt_multistate_int(val, multistate_tunnel);
2396         case oRequestTTY:
2397                 return fmt_multistate_int(val, multistate_requesttty);
2398         case oCanonicalizeHostname:
2399                 return fmt_multistate_int(val, multistate_canonicalizehostname);
2400         case oFingerprintHash:
2401                 return ssh_digest_alg_name(val);
2402         case oProtocol:
2403                 switch (val) {
2404                 case SSH_PROTO_1:
2405                         return "1";
2406                 case SSH_PROTO_2:
2407                         return "2";
2408                 case (SSH_PROTO_1|SSH_PROTO_2):
2409                         return "2,1";
2410                 default:
2411                         return "UNKNOWN";
2412                 }
2413         default:
2414                 switch (val) {
2415                 case 0:
2416                         return "no";
2417                 case 1:
2418                         return "yes";
2419                 default:
2420                         return "UNKNOWN";
2421                 }
2422         }
2423 }
2424
2425 static const char *
2426 lookup_opcode_name(OpCodes code)
2427 {
2428         u_int i;
2429
2430         for (i = 0; keywords[i].name != NULL; i++)
2431                 if (keywords[i].opcode == code)
2432                         return(keywords[i].name);
2433         return "UNKNOWN";
2434 }
2435
2436 static void
2437 dump_cfg_int(OpCodes code, int val)
2438 {
2439         printf("%s %d\n", lookup_opcode_name(code), val);
2440 }
2441
2442 static void
2443 dump_cfg_fmtint(OpCodes code, int val)
2444 {
2445         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2446 }
2447
2448 static void
2449 dump_cfg_string(OpCodes code, const char *val)
2450 {
2451         if (val == NULL)
2452                 return;
2453         printf("%s %s\n", lookup_opcode_name(code), val);
2454 }
2455
2456 static void
2457 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2458 {
2459         u_int i;
2460
2461         for (i = 0; i < count; i++)
2462                 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2463 }
2464
2465 static void
2466 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2467 {
2468         u_int i;
2469
2470         printf("%s", lookup_opcode_name(code));
2471         for (i = 0; i < count; i++)
2472                 printf(" %s",  vals[i]);
2473         printf("\n");
2474 }
2475
2476 static void
2477 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2478 {
2479         const struct Forward *fwd;
2480         u_int i;
2481
2482         /* oDynamicForward */
2483         for (i = 0; i < count; i++) {
2484                 fwd = &fwds[i];
2485                 if (code == oDynamicForward &&
2486                     strcmp(fwd->connect_host, "socks") != 0)
2487                         continue;
2488                 if (code == oLocalForward &&
2489                     strcmp(fwd->connect_host, "socks") == 0)
2490                         continue;
2491                 printf("%s", lookup_opcode_name(code));
2492                 if (fwd->listen_port == PORT_STREAMLOCAL)
2493                         printf(" %s", fwd->listen_path);
2494                 else if (fwd->listen_host == NULL)
2495                         printf(" %d", fwd->listen_port);
2496                 else {
2497                         printf(" [%s]:%d",
2498                             fwd->listen_host, fwd->listen_port);
2499                 }
2500                 if (code != oDynamicForward) {
2501                         if (fwd->connect_port == PORT_STREAMLOCAL)
2502                                 printf(" %s", fwd->connect_path);
2503                         else if (fwd->connect_host == NULL)
2504                                 printf(" %d", fwd->connect_port);
2505                         else {
2506                                 printf(" [%s]:%d",
2507                                     fwd->connect_host, fwd->connect_port);
2508                         }
2509                 }
2510                 printf("\n");
2511         }
2512 }
2513
2514 void
2515 dump_client_config(Options *o, const char *host)
2516 {
2517         int i;
2518         char buf[8];
2519
2520         /* This is normally prepared in ssh_kex2 */
2521         if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2522                 fatal("%s: kex_assemble_names failed", __func__);
2523
2524         /* Most interesting options first: user, host, port */
2525         dump_cfg_string(oUser, o->user);
2526         dump_cfg_string(oHostName, host);
2527         dump_cfg_int(oPort, o->port);
2528
2529         /* Flag options */
2530         dump_cfg_fmtint(oAddressFamily, o->address_family);
2531         dump_cfg_fmtint(oBatchMode, o->batch_mode);
2532         dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2533         dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2534         dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2535         dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2536         dump_cfg_fmtint(oCompression, o->compression);
2537         dump_cfg_fmtint(oControlMaster, o->control_master);
2538         dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2539         dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2540         dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2541         dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2542         dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2543         dump_cfg_fmtint(oForwardX11, o->forward_x11);
2544         dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2545         dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2546 #ifdef GSSAPI
2547         dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2548         dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2549 #endif /* GSSAPI */
2550         dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2551         dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2552         dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2553         dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2554         dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2555         dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2556         dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2557         dump_cfg_fmtint(oProtocol, o->protocol);
2558         dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2559         dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2560         dump_cfg_fmtint(oRequestTTY, o->request_tty);
2561         dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2562         dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2563         dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2564         dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2565         dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2566         dump_cfg_fmtint(oTunnel, o->tun_open);
2567         dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2568         dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2569         dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2570         dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2571
2572         /* Integer options */
2573         dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2574         dump_cfg_int(oCompressionLevel, o->compression_level);
2575         dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2576         dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2577         dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2578         dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2579         dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2580
2581         /* String options */
2582         dump_cfg_string(oBindAddress, o->bind_address);
2583         dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2584         dump_cfg_string(oControlPath, o->control_path);
2585         dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2586         dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2587         dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2588         dump_cfg_string(oIdentityAgent, o->identity_agent);
2589         dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2590         dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2591         dump_cfg_string(oLocalCommand, o->local_command);
2592         dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2593         dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2594         dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2595         dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2596         dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2597         dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2598         dump_cfg_string(oXAuthLocation, o->xauth_location);
2599
2600         /* Forwards */
2601         dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2602         dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2603         dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2604
2605         /* String array options */
2606         dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2607         dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2608         dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2609         dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2610         dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2611
2612         /* Special cases */
2613
2614         /* oConnectTimeout */
2615         if (o->connection_timeout == -1)
2616                 printf("connecttimeout none\n");
2617         else
2618                 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2619
2620         /* oTunnelDevice */
2621         printf("tunneldevice");
2622         if (o->tun_local == SSH_TUNID_ANY)
2623                 printf(" any");
2624         else
2625                 printf(" %d", o->tun_local);
2626         if (o->tun_remote == SSH_TUNID_ANY)
2627                 printf(":any");
2628         else
2629                 printf(":%d", o->tun_remote);
2630         printf("\n");
2631
2632         /* oCanonicalizePermittedCNAMEs */
2633         if ( o->num_permitted_cnames > 0) {
2634                 printf("canonicalizePermittedcnames");
2635                 for (i = 0; i < o->num_permitted_cnames; i++) {
2636                         printf(" %s:%s", o->permitted_cnames[i].source_list,
2637                             o->permitted_cnames[i].target_list);
2638                 }
2639                 printf("\n");
2640         }
2641
2642         /* oCipher */
2643         if (o->cipher != SSH_CIPHER_NOT_SET)
2644                 printf("Cipher %s\n", cipher_name(o->cipher));
2645
2646         /* oControlPersist */
2647         if (o->control_persist == 0 || o->control_persist_timeout == 0)
2648                 dump_cfg_fmtint(oControlPersist, o->control_persist);
2649         else
2650                 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2651
2652         /* oEscapeChar */
2653         if (o->escape_char == SSH_ESCAPECHAR_NONE)
2654                 printf("escapechar none\n");
2655         else {
2656                 vis(buf, o->escape_char, VIS_WHITE, 0);
2657                 printf("escapechar %s\n", buf);
2658         }
2659
2660         /* oIPQoS */
2661         printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2662         printf("%s\n", iptos2str(o->ip_qos_bulk));
2663
2664         /* oRekeyLimit */
2665         printf("rekeylimit %llu %d\n",
2666             (unsigned long long)o->rekey_limit, o->rekey_interval);
2667
2668         /* oStreamLocalBindMask */
2669         printf("streamlocalbindmask 0%o\n",
2670             o->fwd_opts.streamlocal_bind_mask);
2671
2672         /* oProxyCommand / oProxyJump */
2673         if (o->jump_host == NULL)
2674                 dump_cfg_string(oProxyCommand, o->proxy_command);
2675         else {
2676                 /* Check for numeric addresses */
2677                 i = strchr(o->jump_host, ':') != NULL ||
2678                     strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2679                 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2680                 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2681                     /* optional additional jump spec */
2682                     o->jump_extra == NULL ? "" : o->jump_extra,
2683                     o->jump_extra == NULL ? "" : ",",
2684                     /* optional user */
2685                     o->jump_user == NULL ? "" : o->jump_user,
2686                     o->jump_user == NULL ? "" : "@",
2687                     /* opening [ if hostname is numeric */
2688                     i ? "[" : "",
2689                     /* mandatory hostname */
2690                     o->jump_host,
2691                     /* closing ] if hostname is numeric */
2692                     i ? "]" : "",
2693                     /* optional port number */
2694                     o->jump_port <= 0 ? "" : ":",
2695                     o->jump_port <= 0 ? "" : buf);
2696         }
2697 }