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