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