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