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