eb4a8b9eea6a6159bef5d74faebc545d035eff1b
[openssh.git] / readconf.c
1 /* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14
15 #include "includes.h"
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/socket.h>
20
21 #include <netinet/in.h>
22 #include <netinet/in_systm.h>
23 #include <netinet/ip.h>
24
25 #include <ctype.h>
26 #include <errno.h>
27 #include <netdb.h>
28 #include <signal.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <unistd.h>
33
34 #include "xmalloc.h"
35 #include "ssh.h"
36 #include "compat.h"
37 #include "cipher.h"
38 #include "pathnames.h"
39 #include "log.h"
40 #include "key.h"
41 #include "readconf.h"
42 #include "match.h"
43 #include "misc.h"
44 #include "buffer.h"
45 #include "kex.h"
46 #include "mac.h"
47
48 /* Format of the configuration file:
49
50    # Configuration data is parsed as follows:
51    #  1. command line options
52    #  2. user-specific file
53    #  3. system-wide file
54    # Any configuration value is only changed the first time it is set.
55    # Thus, host-specific definitions should be at the beginning of the
56    # configuration file, and defaults at the end.
57
58    # Host-specific declarations.  These may override anything above.  A single
59    # host may match multiple declarations; these are processed in the order
60    # that they are given in.
61
62    Host *.ngs.fi ngs.fi
63      User foo
64
65    Host fake.com
66      HostName another.host.name.real.org
67      User blaah
68      Port 34289
69      ForwardX11 no
70      ForwardAgent no
71
72    Host books.com
73      RemoteForward 9999 shadows.cs.hut.fi:9999
74      Cipher 3des
75
76    Host fascist.blob.com
77      Port 23123
78      User tylonen
79      PasswordAuthentication no
80
81    Host puukko.hut.fi
82      User t35124p
83      ProxyCommand ssh-proxy %h %p
84
85    Host *.fr
86      PublicKeyAuthentication no
87
88    Host *.su
89      Cipher none
90      PasswordAuthentication no
91
92    Host vpn.fake.com
93      Tunnel yes
94      TunnelDevice 3
95
96    # Defaults for various options
97    Host *
98      ForwardAgent no
99      ForwardX11 no
100      PasswordAuthentication yes
101      RSAAuthentication yes
102      RhostsRSAAuthentication yes
103      StrictHostKeyChecking yes
104      TcpKeepAlive no
105      IdentityFile ~/.ssh/identity
106      Port 22
107      EscapeChar ~
108
109 */
110
111 /* Keyword tokens. */
112
113 typedef enum {
114         oBadOption,
115         oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
116         oGatewayPorts, oExitOnForwardFailure,
117         oPasswordAuthentication, oRSAAuthentication,
118         oChallengeResponseAuthentication, oXAuthLocation,
119         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
120         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
121         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
122         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
123         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
124         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
125         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
126         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
127         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
128         oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
129         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
130         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
131         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
132         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
133         oSendEnv, oControlPath, oControlMaster, oControlPersist,
134         oHashKnownHosts,
135         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
136         oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
137         oKexAlgorithms, oIPQoS,
138         oDeprecated, oUnsupported
139 } OpCodes;
140
141 /* Textual representations of the tokens. */
142
143 static struct {
144         const char *name;
145         OpCodes opcode;
146 } keywords[] = {
147         { "forwardagent", oForwardAgent },
148         { "forwardx11", oForwardX11 },
149         { "forwardx11trusted", oForwardX11Trusted },
150         { "forwardx11timeout", oForwardX11Timeout },
151         { "exitonforwardfailure", oExitOnForwardFailure },
152         { "xauthlocation", oXAuthLocation },
153         { "gatewayports", oGatewayPorts },
154         { "useprivilegedport", oUsePrivilegedPort },
155         { "rhostsauthentication", oDeprecated },
156         { "passwordauthentication", oPasswordAuthentication },
157         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
158         { "kbdinteractivedevices", oKbdInteractiveDevices },
159         { "rsaauthentication", oRSAAuthentication },
160         { "pubkeyauthentication", oPubkeyAuthentication },
161         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
162         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
163         { "hostbasedauthentication", oHostbasedAuthentication },
164         { "challengeresponseauthentication", oChallengeResponseAuthentication },
165         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
166         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
167         { "kerberosauthentication", oUnsupported },
168         { "kerberostgtpassing", oUnsupported },
169         { "afstokenpassing", oUnsupported },
170 #if defined(GSSAPI)
171         { "gssapiauthentication", oGssAuthentication },
172         { "gssapidelegatecredentials", oGssDelegateCreds },
173 #else
174         { "gssapiauthentication", oUnsupported },
175         { "gssapidelegatecredentials", oUnsupported },
176 #endif
177         { "fallbacktorsh", oDeprecated },
178         { "usersh", oDeprecated },
179         { "identityfile", oIdentityFile },
180         { "identityfile2", oIdentityFile },                     /* obsolete */
181         { "identitiesonly", oIdentitiesOnly },
182         { "hostname", oHostName },
183         { "hostkeyalias", oHostKeyAlias },
184         { "proxycommand", oProxyCommand },
185         { "port", oPort },
186         { "cipher", oCipher },
187         { "ciphers", oCiphers },
188         { "macs", oMacs },
189         { "protocol", oProtocol },
190         { "remoteforward", oRemoteForward },
191         { "localforward", oLocalForward },
192         { "user", oUser },
193         { "host", oHost },
194         { "escapechar", oEscapeChar },
195         { "globalknownhostsfile", oGlobalKnownHostsFile },
196         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
197         { "userknownhostsfile", oUserKnownHostsFile },
198         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
199         { "connectionattempts", oConnectionAttempts },
200         { "batchmode", oBatchMode },
201         { "checkhostip", oCheckHostIP },
202         { "stricthostkeychecking", oStrictHostKeyChecking },
203         { "compression", oCompression },
204         { "compressionlevel", oCompressionLevel },
205         { "tcpkeepalive", oTCPKeepAlive },
206         { "keepalive", oTCPKeepAlive },                         /* obsolete */
207         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
208         { "loglevel", oLogLevel },
209         { "dynamicforward", oDynamicForward },
210         { "preferredauthentications", oPreferredAuthentications },
211         { "hostkeyalgorithms", oHostKeyAlgorithms },
212         { "bindaddress", oBindAddress },
213 #ifdef ENABLE_PKCS11
214         { "smartcarddevice", oPKCS11Provider },
215         { "pkcs11provider", oPKCS11Provider },
216 #else
217         { "smartcarddevice", oUnsupported },
218         { "pkcs11provider", oUnsupported },
219 #endif
220         { "clearallforwardings", oClearAllForwardings },
221         { "enablesshkeysign", oEnableSSHKeysign },
222         { "verifyhostkeydns", oVerifyHostKeyDNS },
223         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
224         { "rekeylimit", oRekeyLimit },
225         { "connecttimeout", oConnectTimeout },
226         { "addressfamily", oAddressFamily },
227         { "serveraliveinterval", oServerAliveInterval },
228         { "serveralivecountmax", oServerAliveCountMax },
229         { "sendenv", oSendEnv },
230         { "controlpath", oControlPath },
231         { "controlmaster", oControlMaster },
232         { "controlpersist", oControlPersist },
233         { "hashknownhosts", oHashKnownHosts },
234         { "tunnel", oTunnel },
235         { "tunneldevice", oTunnelDevice },
236         { "localcommand", oLocalCommand },
237         { "permitlocalcommand", oPermitLocalCommand },
238         { "visualhostkey", oVisualHostKey },
239         { "useroaming", oUseRoaming },
240 #ifdef JPAKE
241         { "zeroknowledgepasswordauthentication",
242             oZeroKnowledgePasswordAuthentication },
243 #else
244         { "zeroknowledgepasswordauthentication", oUnsupported },
245 #endif
246         { "kexalgorithms", oKexAlgorithms },
247         { "ipqos", oIPQoS },
248
249         { NULL, oBadOption }
250 };
251
252 /*
253  * Adds a local TCP/IP port forward to options.  Never returns if there is an
254  * error.
255  */
256
257 void
258 add_local_forward(Options *options, const Forward *newfwd)
259 {
260         Forward *fwd;
261 #ifndef NO_IPPORT_RESERVED_CONCEPT
262         extern uid_t original_real_uid;
263         if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
264                 fatal("Privileged ports can only be forwarded by root.");
265 #endif
266         options->local_forwards = xrealloc(options->local_forwards,
267             options->num_local_forwards + 1,
268             sizeof(*options->local_forwards));
269         fwd = &options->local_forwards[options->num_local_forwards++];
270
271         fwd->listen_host = newfwd->listen_host;
272         fwd->listen_port = newfwd->listen_port;
273         fwd->connect_host = newfwd->connect_host;
274         fwd->connect_port = newfwd->connect_port;
275 }
276
277 /*
278  * Adds a remote TCP/IP port forward to options.  Never returns if there is
279  * an error.
280  */
281
282 void
283 add_remote_forward(Options *options, const Forward *newfwd)
284 {
285         Forward *fwd;
286
287         options->remote_forwards = xrealloc(options->remote_forwards,
288             options->num_remote_forwards + 1,
289             sizeof(*options->remote_forwards));
290         fwd = &options->remote_forwards[options->num_remote_forwards++];
291
292         fwd->listen_host = newfwd->listen_host;
293         fwd->listen_port = newfwd->listen_port;
294         fwd->connect_host = newfwd->connect_host;
295         fwd->connect_port = newfwd->connect_port;
296         fwd->allocated_port = 0;
297 }
298
299 static void
300 clear_forwardings(Options *options)
301 {
302         int i;
303
304         for (i = 0; i < options->num_local_forwards; i++) {
305                 if (options->local_forwards[i].listen_host != NULL)
306                         xfree(options->local_forwards[i].listen_host);
307                 xfree(options->local_forwards[i].connect_host);
308         }
309         if (options->num_local_forwards > 0) {
310                 xfree(options->local_forwards);
311                 options->local_forwards = NULL;
312         }
313         options->num_local_forwards = 0;
314         for (i = 0; i < options->num_remote_forwards; i++) {
315                 if (options->remote_forwards[i].listen_host != NULL)
316                         xfree(options->remote_forwards[i].listen_host);
317                 xfree(options->remote_forwards[i].connect_host);
318         }
319         if (options->num_remote_forwards > 0) {
320                 xfree(options->remote_forwards);
321                 options->remote_forwards = NULL;
322         }
323         options->num_remote_forwards = 0;
324         options->tun_open = SSH_TUNMODE_NO;
325 }
326
327 /*
328  * Returns the number of the token pointed to by cp or oBadOption.
329  */
330
331 static OpCodes
332 parse_token(const char *cp, const char *filename, int linenum)
333 {
334         u_int i;
335
336         for (i = 0; keywords[i].name; i++)
337                 if (strcasecmp(cp, keywords[i].name) == 0)
338                         return keywords[i].opcode;
339
340         error("%s: line %d: Bad configuration option: %s",
341             filename, linenum, cp);
342         return oBadOption;
343 }
344
345 /*
346  * Processes a single option line as used in the configuration files. This
347  * only sets those values that have not already been set.
348  */
349 #define WHITESPACE " \t\r\n"
350
351 int
352 process_config_line(Options *options, const char *host,
353                     char *line, const char *filename, int linenum,
354                     int *activep)
355 {
356         char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
357         int opcode, *intptr, value, value2, scale;
358         LogLevel *log_level_ptr;
359         long long orig, val64;
360         size_t len;
361         Forward fwd;
362
363         /* Strip trailing whitespace */
364         for (len = strlen(line) - 1; len > 0; len--) {
365                 if (strchr(WHITESPACE, line[len]) == NULL)
366                         break;
367                 line[len] = '\0';
368         }
369
370         s = line;
371         /* Get the keyword. (Each line is supposed to begin with a keyword). */
372         if ((keyword = strdelim(&s)) == NULL)
373                 return 0;
374         /* Ignore leading whitespace. */
375         if (*keyword == '\0')
376                 keyword = strdelim(&s);
377         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
378                 return 0;
379
380         opcode = parse_token(keyword, filename, linenum);
381
382         switch (opcode) {
383         case oBadOption:
384                 /* don't panic, but count bad options */
385                 return -1;
386                 /* NOTREACHED */
387         case oConnectTimeout:
388                 intptr = &options->connection_timeout;
389 parse_time:
390                 arg = strdelim(&s);
391                 if (!arg || *arg == '\0')
392                         fatal("%s line %d: missing time value.",
393                             filename, linenum);
394                 if ((value = convtime(arg)) == -1)
395                         fatal("%s line %d: invalid time value.",
396                             filename, linenum);
397                 if (*activep && *intptr == -1)
398                         *intptr = value;
399                 break;
400
401         case oForwardAgent:
402                 intptr = &options->forward_agent;
403 parse_flag:
404                 arg = strdelim(&s);
405                 if (!arg || *arg == '\0')
406                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
407                 value = 0;      /* To avoid compiler warning... */
408                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
409                         value = 1;
410                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
411                         value = 0;
412                 else
413                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
414                 if (*activep && *intptr == -1)
415                         *intptr = value;
416                 break;
417
418         case oForwardX11:
419                 intptr = &options->forward_x11;
420                 goto parse_flag;
421
422         case oForwardX11Trusted:
423                 intptr = &options->forward_x11_trusted;
424                 goto parse_flag;
425         
426         case oForwardX11Timeout:
427                 intptr = &options->forward_x11_timeout;
428                 goto parse_time;
429
430         case oGatewayPorts:
431                 intptr = &options->gateway_ports;
432                 goto parse_flag;
433
434         case oExitOnForwardFailure:
435                 intptr = &options->exit_on_forward_failure;
436                 goto parse_flag;
437
438         case oUsePrivilegedPort:
439                 intptr = &options->use_privileged_port;
440                 goto parse_flag;
441
442         case oPasswordAuthentication:
443                 intptr = &options->password_authentication;
444                 goto parse_flag;
445
446         case oZeroKnowledgePasswordAuthentication:
447                 intptr = &options->zero_knowledge_password_authentication;
448                 goto parse_flag;
449
450         case oKbdInteractiveAuthentication:
451                 intptr = &options->kbd_interactive_authentication;
452                 goto parse_flag;
453
454         case oKbdInteractiveDevices:
455                 charptr = &options->kbd_interactive_devices;
456                 goto parse_string;
457
458         case oPubkeyAuthentication:
459                 intptr = &options->pubkey_authentication;
460                 goto parse_flag;
461
462         case oRSAAuthentication:
463                 intptr = &options->rsa_authentication;
464                 goto parse_flag;
465
466         case oRhostsRSAAuthentication:
467                 intptr = &options->rhosts_rsa_authentication;
468                 goto parse_flag;
469
470         case oHostbasedAuthentication:
471                 intptr = &options->hostbased_authentication;
472                 goto parse_flag;
473
474         case oChallengeResponseAuthentication:
475                 intptr = &options->challenge_response_authentication;
476                 goto parse_flag;
477
478         case oGssAuthentication:
479                 intptr = &options->gss_authentication;
480                 goto parse_flag;
481
482         case oGssDelegateCreds:
483                 intptr = &options->gss_deleg_creds;
484                 goto parse_flag;
485
486         case oBatchMode:
487                 intptr = &options->batch_mode;
488                 goto parse_flag;
489
490         case oCheckHostIP:
491                 intptr = &options->check_host_ip;
492                 goto parse_flag;
493
494         case oVerifyHostKeyDNS:
495                 intptr = &options->verify_host_key_dns;
496                 goto parse_yesnoask;
497
498         case oStrictHostKeyChecking:
499                 intptr = &options->strict_host_key_checking;
500 parse_yesnoask:
501                 arg = strdelim(&s);
502                 if (!arg || *arg == '\0')
503                         fatal("%.200s line %d: Missing yes/no/ask argument.",
504                             filename, linenum);
505                 value = 0;      /* To avoid compiler warning... */
506                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
507                         value = 1;
508                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
509                         value = 0;
510                 else if (strcmp(arg, "ask") == 0)
511                         value = 2;
512                 else
513                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
514                 if (*activep && *intptr == -1)
515                         *intptr = value;
516                 break;
517
518         case oCompression:
519                 intptr = &options->compression;
520                 goto parse_flag;
521
522         case oTCPKeepAlive:
523                 intptr = &options->tcp_keep_alive;
524                 goto parse_flag;
525
526         case oNoHostAuthenticationForLocalhost:
527                 intptr = &options->no_host_authentication_for_localhost;
528                 goto parse_flag;
529
530         case oNumberOfPasswordPrompts:
531                 intptr = &options->number_of_password_prompts;
532                 goto parse_int;
533
534         case oCompressionLevel:
535                 intptr = &options->compression_level;
536                 goto parse_int;
537
538         case oRekeyLimit:
539                 arg = strdelim(&s);
540                 if (!arg || *arg == '\0')
541                         fatal("%.200s line %d: Missing argument.", filename, linenum);
542                 if (arg[0] < '0' || arg[0] > '9')
543                         fatal("%.200s line %d: Bad number.", filename, linenum);
544                 orig = val64 = strtoll(arg, &endofnumber, 10);
545                 if (arg == endofnumber)
546                         fatal("%.200s line %d: Bad number.", filename, linenum);
547                 switch (toupper(*endofnumber)) {
548                 case '\0':
549                         scale = 1;
550                         break;
551                 case 'K':
552                         scale = 1<<10;
553                         break;
554                 case 'M':
555                         scale = 1<<20;
556                         break;
557                 case 'G':
558                         scale = 1<<30;
559                         break;
560                 default:
561                         fatal("%.200s line %d: Invalid RekeyLimit suffix",
562                             filename, linenum);
563                 }
564                 val64 *= scale;
565                 /* detect integer wrap and too-large limits */
566                 if ((val64 / scale) != orig || val64 > UINT_MAX)
567                         fatal("%.200s line %d: RekeyLimit too large",
568                             filename, linenum);
569                 if (val64 < 16)
570                         fatal("%.200s line %d: RekeyLimit too small",
571                             filename, linenum);
572                 if (*activep && options->rekey_limit == -1)
573                         options->rekey_limit = (u_int32_t)val64;
574                 break;
575
576         case oIdentityFile:
577                 arg = strdelim(&s);
578                 if (!arg || *arg == '\0')
579                         fatal("%.200s line %d: Missing argument.", filename, linenum);
580                 if (*activep) {
581                         intptr = &options->num_identity_files;
582                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
583                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
584                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
585                         charptr = &options->identity_files[*intptr];
586                         *charptr = xstrdup(arg);
587                         *intptr = *intptr + 1;
588                 }
589                 break;
590
591         case oXAuthLocation:
592                 charptr=&options->xauth_location;
593                 goto parse_string;
594
595         case oUser:
596                 charptr = &options->user;
597 parse_string:
598                 arg = strdelim(&s);
599                 if (!arg || *arg == '\0')
600                         fatal("%.200s line %d: Missing argument.", filename, linenum);
601                 if (*activep && *charptr == NULL)
602                         *charptr = xstrdup(arg);
603                 break;
604
605         case oGlobalKnownHostsFile:
606                 charptr = &options->system_hostfile;
607                 goto parse_string;
608
609         case oUserKnownHostsFile:
610                 charptr = &options->user_hostfile;
611                 goto parse_string;
612
613         case oGlobalKnownHostsFile2:
614                 charptr = &options->system_hostfile2;
615                 goto parse_string;
616
617         case oUserKnownHostsFile2:
618                 charptr = &options->user_hostfile2;
619                 goto parse_string;
620
621         case oHostName:
622                 charptr = &options->hostname;
623                 goto parse_string;
624
625         case oHostKeyAlias:
626                 charptr = &options->host_key_alias;
627                 goto parse_string;
628
629         case oPreferredAuthentications:
630                 charptr = &options->preferred_authentications;
631                 goto parse_string;
632
633         case oBindAddress:
634                 charptr = &options->bind_address;
635                 goto parse_string;
636
637         case oPKCS11Provider:
638                 charptr = &options->pkcs11_provider;
639                 goto parse_string;
640
641         case oProxyCommand:
642                 charptr = &options->proxy_command;
643 parse_command:
644                 if (s == NULL)
645                         fatal("%.200s line %d: Missing argument.", filename, linenum);
646                 len = strspn(s, WHITESPACE "=");
647                 if (*activep && *charptr == NULL)
648                         *charptr = xstrdup(s + len);
649                 return 0;
650
651         case oPort:
652                 intptr = &options->port;
653 parse_int:
654                 arg = strdelim(&s);
655                 if (!arg || *arg == '\0')
656                         fatal("%.200s line %d: Missing argument.", filename, linenum);
657                 if (arg[0] < '0' || arg[0] > '9')
658                         fatal("%.200s line %d: Bad number.", filename, linenum);
659
660                 /* Octal, decimal, or hex format? */
661                 value = strtol(arg, &endofnumber, 0);
662                 if (arg == endofnumber)
663                         fatal("%.200s line %d: Bad number.", filename, linenum);
664                 if (*activep && *intptr == -1)
665                         *intptr = value;
666                 break;
667
668         case oConnectionAttempts:
669                 intptr = &options->connection_attempts;
670                 goto parse_int;
671
672         case oCipher:
673                 intptr = &options->cipher;
674                 arg = strdelim(&s);
675                 if (!arg || *arg == '\0')
676                         fatal("%.200s line %d: Missing argument.", filename, linenum);
677                 value = cipher_number(arg);
678                 if (value == -1)
679                         fatal("%.200s line %d: Bad cipher '%s'.",
680                             filename, linenum, arg ? arg : "<NONE>");
681                 if (*activep && *intptr == -1)
682                         *intptr = value;
683                 break;
684
685         case oCiphers:
686                 arg = strdelim(&s);
687                 if (!arg || *arg == '\0')
688                         fatal("%.200s line %d: Missing argument.", filename, linenum);
689                 if (!ciphers_valid(arg))
690                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
691                             filename, linenum, arg ? arg : "<NONE>");
692                 if (*activep && options->ciphers == NULL)
693                         options->ciphers = xstrdup(arg);
694                 break;
695
696         case oMacs:
697                 arg = strdelim(&s);
698                 if (!arg || *arg == '\0')
699                         fatal("%.200s line %d: Missing argument.", filename, linenum);
700                 if (!mac_valid(arg))
701                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
702                             filename, linenum, arg ? arg : "<NONE>");
703                 if (*activep && options->macs == NULL)
704                         options->macs = xstrdup(arg);
705                 break;
706
707         case oKexAlgorithms:
708                 arg = strdelim(&s);
709                 if (!arg || *arg == '\0')
710                         fatal("%.200s line %d: Missing argument.",
711                             filename, linenum);
712                 if (!kex_names_valid(arg))
713                         fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
714                             filename, linenum, arg ? arg : "<NONE>");
715                 if (*activep && options->kex_algorithms == NULL)
716                         options->kex_algorithms = xstrdup(arg);
717                 break;
718
719         case oHostKeyAlgorithms:
720                 arg = strdelim(&s);
721                 if (!arg || *arg == '\0')
722                         fatal("%.200s line %d: Missing argument.", filename, linenum);
723                 if (!key_names_valid2(arg))
724                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
725                             filename, linenum, arg ? arg : "<NONE>");
726                 if (*activep && options->hostkeyalgorithms == NULL)
727                         options->hostkeyalgorithms = xstrdup(arg);
728                 break;
729
730         case oProtocol:
731                 intptr = &options->protocol;
732                 arg = strdelim(&s);
733                 if (!arg || *arg == '\0')
734                         fatal("%.200s line %d: Missing argument.", filename, linenum);
735                 value = proto_spec(arg);
736                 if (value == SSH_PROTO_UNKNOWN)
737                         fatal("%.200s line %d: Bad protocol spec '%s'.",
738                             filename, linenum, arg ? arg : "<NONE>");
739                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
740                         *intptr = value;
741                 break;
742
743         case oLogLevel:
744                 log_level_ptr = &options->log_level;
745                 arg = strdelim(&s);
746                 value = log_level_number(arg);
747                 if (value == SYSLOG_LEVEL_NOT_SET)
748                         fatal("%.200s line %d: unsupported log level '%s'",
749                             filename, linenum, arg ? arg : "<NONE>");
750                 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
751                         *log_level_ptr = (LogLevel) value;
752                 break;
753
754         case oLocalForward:
755         case oRemoteForward:
756         case oDynamicForward:
757                 arg = strdelim(&s);
758                 if (arg == NULL || *arg == '\0')
759                         fatal("%.200s line %d: Missing port argument.",
760                             filename, linenum);
761
762                 if (opcode == oLocalForward ||
763                     opcode == oRemoteForward) {
764                         arg2 = strdelim(&s);
765                         if (arg2 == NULL || *arg2 == '\0')
766                                 fatal("%.200s line %d: Missing target argument.",
767                                     filename, linenum);
768
769                         /* construct a string for parse_forward */
770                         snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
771                 } else if (opcode == oDynamicForward) {
772                         strlcpy(fwdarg, arg, sizeof(fwdarg));
773                 }
774
775                 if (parse_forward(&fwd, fwdarg,
776                     opcode == oDynamicForward ? 1 : 0,
777                     opcode == oRemoteForward ? 1 : 0) == 0)
778                         fatal("%.200s line %d: Bad forwarding specification.",
779                             filename, linenum);
780
781                 if (*activep) {
782                         if (opcode == oLocalForward ||
783                             opcode == oDynamicForward)
784                                 add_local_forward(options, &fwd);
785                         else if (opcode == oRemoteForward)
786                                 add_remote_forward(options, &fwd);
787                 }
788                 break;
789
790         case oClearAllForwardings:
791                 intptr = &options->clear_forwardings;
792                 goto parse_flag;
793
794         case oHost:
795                 *activep = 0;
796                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
797                         if (match_pattern(host, arg)) {
798                                 debug("Applying options for %.100s", arg);
799                                 *activep = 1;
800                                 break;
801                         }
802                 /* Avoid garbage check below, as strdelim is done. */
803                 return 0;
804
805         case oEscapeChar:
806                 intptr = &options->escape_char;
807                 arg = strdelim(&s);
808                 if (!arg || *arg == '\0')
809                         fatal("%.200s line %d: Missing argument.", filename, linenum);
810                 if (arg[0] == '^' && arg[2] == 0 &&
811                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
812                         value = (u_char) arg[1] & 31;
813                 else if (strlen(arg) == 1)
814                         value = (u_char) arg[0];
815                 else if (strcmp(arg, "none") == 0)
816                         value = SSH_ESCAPECHAR_NONE;
817                 else {
818                         fatal("%.200s line %d: Bad escape character.",
819                             filename, linenum);
820                         /* NOTREACHED */
821                         value = 0;      /* Avoid compiler warning. */
822                 }
823                 if (*activep && *intptr == -1)
824                         *intptr = value;
825                 break;
826
827         case oAddressFamily:
828                 arg = strdelim(&s);
829                 if (!arg || *arg == '\0')
830                         fatal("%s line %d: missing address family.",
831                             filename, linenum);
832                 intptr = &options->address_family;
833                 if (strcasecmp(arg, "inet") == 0)
834                         value = AF_INET;
835                 else if (strcasecmp(arg, "inet6") == 0)
836                         value = AF_INET6;
837                 else if (strcasecmp(arg, "any") == 0)
838                         value = AF_UNSPEC;
839                 else
840                         fatal("Unsupported AddressFamily \"%s\"", arg);
841                 if (*activep && *intptr == -1)
842                         *intptr = value;
843                 break;
844
845         case oEnableSSHKeysign:
846                 intptr = &options->enable_ssh_keysign;
847                 goto parse_flag;
848
849         case oIdentitiesOnly:
850                 intptr = &options->identities_only;
851                 goto parse_flag;
852
853         case oServerAliveInterval:
854                 intptr = &options->server_alive_interval;
855                 goto parse_time;
856
857         case oServerAliveCountMax:
858                 intptr = &options->server_alive_count_max;
859                 goto parse_int;
860
861         case oSendEnv:
862                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
863                         if (strchr(arg, '=') != NULL)
864                                 fatal("%s line %d: Invalid environment name.",
865                                     filename, linenum);
866                         if (!*activep)
867                                 continue;
868                         if (options->num_send_env >= MAX_SEND_ENV)
869                                 fatal("%s line %d: too many send env.",
870                                     filename, linenum);
871                         options->send_env[options->num_send_env++] =
872                             xstrdup(arg);
873                 }
874                 break;
875
876         case oControlPath:
877                 charptr = &options->control_path;
878                 goto parse_string;
879
880         case oControlMaster:
881                 intptr = &options->control_master;
882                 arg = strdelim(&s);
883                 if (!arg || *arg == '\0')
884                         fatal("%.200s line %d: Missing ControlMaster argument.",
885                             filename, linenum);
886                 value = 0;      /* To avoid compiler warning... */
887                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
888                         value = SSHCTL_MASTER_YES;
889                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
890                         value = SSHCTL_MASTER_NO;
891                 else if (strcmp(arg, "auto") == 0)
892                         value = SSHCTL_MASTER_AUTO;
893                 else if (strcmp(arg, "ask") == 0)
894                         value = SSHCTL_MASTER_ASK;
895                 else if (strcmp(arg, "autoask") == 0)
896                         value = SSHCTL_MASTER_AUTO_ASK;
897                 else
898                         fatal("%.200s line %d: Bad ControlMaster argument.",
899                             filename, linenum);
900                 if (*activep && *intptr == -1)
901                         *intptr = value;
902                 break;
903
904         case oControlPersist:
905                 /* no/false/yes/true, or a time spec */
906                 intptr = &options->control_persist;
907                 arg = strdelim(&s);
908                 if (!arg || *arg == '\0')
909                         fatal("%.200s line %d: Missing ControlPersist"
910                             " argument.", filename, linenum);
911                 value = 0;
912                 value2 = 0;     /* timeout */
913                 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
914                         value = 0;
915                 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
916                         value = 1;
917                 else if ((value2 = convtime(arg)) >= 0)
918                         value = 1;
919                 else
920                         fatal("%.200s line %d: Bad ControlPersist argument.",
921                             filename, linenum);
922                 if (*activep && *intptr == -1) {
923                         *intptr = value;
924                         options->control_persist_timeout = value2;
925                 }
926                 break;
927
928         case oHashKnownHosts:
929                 intptr = &options->hash_known_hosts;
930                 goto parse_flag;
931
932         case oTunnel:
933                 intptr = &options->tun_open;
934                 arg = strdelim(&s);
935                 if (!arg || *arg == '\0')
936                         fatal("%s line %d: Missing yes/point-to-point/"
937                             "ethernet/no argument.", filename, linenum);
938                 value = 0;      /* silence compiler */
939                 if (strcasecmp(arg, "ethernet") == 0)
940                         value = SSH_TUNMODE_ETHERNET;
941                 else if (strcasecmp(arg, "point-to-point") == 0)
942                         value = SSH_TUNMODE_POINTOPOINT;
943                 else if (strcasecmp(arg, "yes") == 0)
944                         value = SSH_TUNMODE_DEFAULT;
945                 else if (strcasecmp(arg, "no") == 0)
946                         value = SSH_TUNMODE_NO;
947                 else
948                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
949                             "no argument: %s", filename, linenum, arg);
950                 if (*activep)
951                         *intptr = value;
952                 break;
953
954         case oTunnelDevice:
955                 arg = strdelim(&s);
956                 if (!arg || *arg == '\0')
957                         fatal("%.200s line %d: Missing argument.", filename, linenum);
958                 value = a2tun(arg, &value2);
959                 if (value == SSH_TUNID_ERR)
960                         fatal("%.200s line %d: Bad tun device.", filename, linenum);
961                 if (*activep) {
962                         options->tun_local = value;
963                         options->tun_remote = value2;
964                 }
965                 break;
966
967         case oLocalCommand:
968                 charptr = &options->local_command;
969                 goto parse_command;
970
971         case oPermitLocalCommand:
972                 intptr = &options->permit_local_command;
973                 goto parse_flag;
974
975         case oVisualHostKey:
976                 intptr = &options->visual_host_key;
977                 goto parse_flag;
978
979         case oIPQoS:
980                 arg = strdelim(&s);
981                 if ((value = parse_ipqos(arg)) == -1)
982                         fatal("%s line %d: Bad IPQoS value: %s",
983                             filename, linenum, arg);
984                 arg = strdelim(&s);
985                 if (arg == NULL)
986                         value2 = value;
987                 else if ((value2 = parse_ipqos(arg)) == -1)
988                         fatal("%s line %d: Bad IPQoS value: %s",
989                             filename, linenum, arg);
990                 if (*activep) {
991                         options->ip_qos_interactive = value;
992                         options->ip_qos_bulk = value2;
993                 }
994                 break;
995
996         case oUseRoaming:
997                 intptr = &options->use_roaming;
998                 goto parse_flag;
999
1000         case oDeprecated:
1001                 debug("%s line %d: Deprecated option \"%s\"",
1002                     filename, linenum, keyword);
1003                 return 0;
1004
1005         case oUnsupported:
1006                 error("%s line %d: Unsupported option \"%s\"",
1007                     filename, linenum, keyword);
1008                 return 0;
1009
1010         default:
1011                 fatal("process_config_line: Unimplemented opcode %d", opcode);
1012         }
1013
1014         /* Check that there is no garbage at end of line. */
1015         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1016                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1017                     filename, linenum, arg);
1018         }
1019         return 0;
1020 }
1021
1022
1023 /*
1024  * Reads the config file and modifies the options accordingly.  Options
1025  * should already be initialized before this call.  This never returns if
1026  * there is an error.  If the file does not exist, this returns 0.
1027  */
1028
1029 int
1030 read_config_file(const char *filename, const char *host, Options *options,
1031     int checkperm)
1032 {
1033         FILE *f;
1034         char line[1024];
1035         int active, linenum;
1036         int bad_options = 0;
1037
1038         if ((f = fopen(filename, "r")) == NULL)
1039                 return 0;
1040
1041         if (checkperm) {
1042                 struct stat sb;
1043
1044                 if (fstat(fileno(f), &sb) == -1)
1045                         fatal("fstat %s: %s", filename, strerror(errno));
1046                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1047                     (sb.st_mode & 022) != 0))
1048                         fatal("Bad owner or permissions on %s", filename);
1049         }
1050
1051         debug("Reading configuration data %.200s", filename);
1052
1053         /*
1054          * Mark that we are now processing the options.  This flag is turned
1055          * on/off by Host specifications.
1056          */
1057         active = 1;
1058         linenum = 0;
1059         while (fgets(line, sizeof(line), f)) {
1060                 /* Update line number counter. */
1061                 linenum++;
1062                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1063                         bad_options++;
1064         }
1065         fclose(f);
1066         if (bad_options > 0)
1067                 fatal("%s: terminating, %d bad configuration options",
1068                     filename, bad_options);
1069         return 1;
1070 }
1071
1072 /*
1073  * Initializes options to special values that indicate that they have not yet
1074  * been set.  Read_config_file will only set options with this value. Options
1075  * are processed in the following order: command line, user config file,
1076  * system config file.  Last, fill_default_options is called.
1077  */
1078
1079 void
1080 initialize_options(Options * options)
1081 {
1082         memset(options, 'X', sizeof(*options));
1083         options->forward_agent = -1;
1084         options->forward_x11 = -1;
1085         options->forward_x11_trusted = -1;
1086         options->forward_x11_timeout = -1;
1087         options->exit_on_forward_failure = -1;
1088         options->xauth_location = NULL;
1089         options->gateway_ports = -1;
1090         options->use_privileged_port = -1;
1091         options->rsa_authentication = -1;
1092         options->pubkey_authentication = -1;
1093         options->challenge_response_authentication = -1;
1094         options->gss_authentication = -1;
1095         options->gss_deleg_creds = -1;
1096         options->password_authentication = -1;
1097         options->kbd_interactive_authentication = -1;
1098         options->kbd_interactive_devices = NULL;
1099         options->rhosts_rsa_authentication = -1;
1100         options->hostbased_authentication = -1;
1101         options->batch_mode = -1;
1102         options->check_host_ip = -1;
1103         options->strict_host_key_checking = -1;
1104         options->compression = -1;
1105         options->tcp_keep_alive = -1;
1106         options->compression_level = -1;
1107         options->port = -1;
1108         options->address_family = -1;
1109         options->connection_attempts = -1;
1110         options->connection_timeout = -1;
1111         options->number_of_password_prompts = -1;
1112         options->cipher = -1;
1113         options->ciphers = NULL;
1114         options->macs = NULL;
1115         options->kex_algorithms = NULL;
1116         options->hostkeyalgorithms = NULL;
1117         options->protocol = SSH_PROTO_UNKNOWN;
1118         options->num_identity_files = 0;
1119         options->hostname = NULL;
1120         options->host_key_alias = NULL;
1121         options->proxy_command = NULL;
1122         options->user = NULL;
1123         options->escape_char = -1;
1124         options->system_hostfile = NULL;
1125         options->user_hostfile = NULL;
1126         options->system_hostfile2 = NULL;
1127         options->user_hostfile2 = NULL;
1128         options->local_forwards = NULL;
1129         options->num_local_forwards = 0;
1130         options->remote_forwards = NULL;
1131         options->num_remote_forwards = 0;
1132         options->clear_forwardings = -1;
1133         options->log_level = SYSLOG_LEVEL_NOT_SET;
1134         options->preferred_authentications = NULL;
1135         options->bind_address = NULL;
1136         options->pkcs11_provider = NULL;
1137         options->enable_ssh_keysign = - 1;
1138         options->no_host_authentication_for_localhost = - 1;
1139         options->identities_only = - 1;
1140         options->rekey_limit = - 1;
1141         options->verify_host_key_dns = -1;
1142         options->server_alive_interval = -1;
1143         options->server_alive_count_max = -1;
1144         options->num_send_env = 0;
1145         options->control_path = NULL;
1146         options->control_master = -1;
1147         options->control_persist = -1;
1148         options->control_persist_timeout = 0;
1149         options->hash_known_hosts = -1;
1150         options->tun_open = -1;
1151         options->tun_local = -1;
1152         options->tun_remote = -1;
1153         options->local_command = NULL;
1154         options->permit_local_command = -1;
1155         options->use_roaming = -1;
1156         options->visual_host_key = -1;
1157         options->zero_knowledge_password_authentication = -1;
1158         options->ip_qos_interactive = -1;
1159         options->ip_qos_bulk = -1;
1160 }
1161
1162 /*
1163  * Called after processing other sources of option data, this fills those
1164  * options for which no value has been specified with their default values.
1165  */
1166
1167 void
1168 fill_default_options(Options * options)
1169 {
1170         int len;
1171
1172         if (options->forward_agent == -1)
1173                 options->forward_agent = 0;
1174         if (options->forward_x11 == -1)
1175                 options->forward_x11 = 0;
1176         if (options->forward_x11_trusted == -1)
1177                 options->forward_x11_trusted = 0;
1178         if (options->forward_x11_timeout == -1)
1179                 options->forward_x11_timeout = 1200;
1180         if (options->exit_on_forward_failure == -1)
1181                 options->exit_on_forward_failure = 0;
1182         if (options->xauth_location == NULL)
1183                 options->xauth_location = _PATH_XAUTH;
1184         if (options->gateway_ports == -1)
1185                 options->gateway_ports = 0;
1186         if (options->use_privileged_port == -1)
1187                 options->use_privileged_port = 0;
1188         if (options->rsa_authentication == -1)
1189                 options->rsa_authentication = 1;
1190         if (options->pubkey_authentication == -1)
1191                 options->pubkey_authentication = 1;
1192         if (options->challenge_response_authentication == -1)
1193                 options->challenge_response_authentication = 1;
1194         if (options->gss_authentication == -1)
1195                 options->gss_authentication = 0;
1196         if (options->gss_deleg_creds == -1)
1197                 options->gss_deleg_creds = 0;
1198         if (options->password_authentication == -1)
1199                 options->password_authentication = 1;
1200         if (options->kbd_interactive_authentication == -1)
1201                 options->kbd_interactive_authentication = 1;
1202         if (options->rhosts_rsa_authentication == -1)
1203                 options->rhosts_rsa_authentication = 0;
1204         if (options->hostbased_authentication == -1)
1205                 options->hostbased_authentication = 0;
1206         if (options->batch_mode == -1)
1207                 options->batch_mode = 0;
1208         if (options->check_host_ip == -1)
1209                 options->check_host_ip = 1;
1210         if (options->strict_host_key_checking == -1)
1211                 options->strict_host_key_checking = 2;  /* 2 is default */
1212         if (options->compression == -1)
1213                 options->compression = 0;
1214         if (options->tcp_keep_alive == -1)
1215                 options->tcp_keep_alive = 1;
1216         if (options->compression_level == -1)
1217                 options->compression_level = 6;
1218         if (options->port == -1)
1219                 options->port = 0;      /* Filled in ssh_connect. */
1220         if (options->address_family == -1)
1221                 options->address_family = AF_UNSPEC;
1222         if (options->connection_attempts == -1)
1223                 options->connection_attempts = 1;
1224         if (options->number_of_password_prompts == -1)
1225                 options->number_of_password_prompts = 3;
1226         /* Selected in ssh_login(). */
1227         if (options->cipher == -1)
1228                 options->cipher = SSH_CIPHER_NOT_SET;
1229         /* options->ciphers, default set in myproposals.h */
1230         /* options->macs, default set in myproposals.h */
1231         /* options->kex_algorithms, default set in myproposals.h */
1232         /* options->hostkeyalgorithms, default set in myproposals.h */
1233         if (options->protocol == SSH_PROTO_UNKNOWN)
1234                 options->protocol = SSH_PROTO_2;
1235         if (options->num_identity_files == 0) {
1236                 if (options->protocol & SSH_PROTO_1) {
1237                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1238                         options->identity_files[options->num_identity_files] =
1239                             xmalloc(len);
1240                         snprintf(options->identity_files[options->num_identity_files++],
1241                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1242                 }
1243                 if (options->protocol & SSH_PROTO_2) {
1244                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1245                         options->identity_files[options->num_identity_files] =
1246                             xmalloc(len);
1247                         snprintf(options->identity_files[options->num_identity_files++],
1248                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1249
1250                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1251                         options->identity_files[options->num_identity_files] =
1252                             xmalloc(len);
1253                         snprintf(options->identity_files[options->num_identity_files++],
1254                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1255 #ifdef OPENSSL_HAS_ECC
1256                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
1257                         options->identity_files[options->num_identity_files] =
1258                             xmalloc(len);
1259                         snprintf(options->identity_files[options->num_identity_files++],
1260                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
1261 #endif
1262                 }
1263         }
1264         if (options->escape_char == -1)
1265                 options->escape_char = '~';
1266         if (options->system_hostfile == NULL)
1267                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1268         if (options->user_hostfile == NULL)
1269                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1270         if (options->system_hostfile2 == NULL)
1271                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1272         if (options->user_hostfile2 == NULL)
1273                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1274         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1275                 options->log_level = SYSLOG_LEVEL_INFO;
1276         if (options->clear_forwardings == 1)
1277                 clear_forwardings(options);
1278         if (options->no_host_authentication_for_localhost == - 1)
1279                 options->no_host_authentication_for_localhost = 0;
1280         if (options->identities_only == -1)
1281                 options->identities_only = 0;
1282         if (options->enable_ssh_keysign == -1)
1283                 options->enable_ssh_keysign = 0;
1284         if (options->rekey_limit == -1)
1285                 options->rekey_limit = 0;
1286         if (options->verify_host_key_dns == -1)
1287                 options->verify_host_key_dns = 0;
1288         if (options->server_alive_interval == -1)
1289                 options->server_alive_interval = 0;
1290         if (options->server_alive_count_max == -1)
1291                 options->server_alive_count_max = 3;
1292         if (options->control_master == -1)
1293                 options->control_master = 0;
1294         if (options->control_persist == -1) {
1295                 options->control_persist = 0;
1296                 options->control_persist_timeout = 0;
1297         }
1298         if (options->hash_known_hosts == -1)
1299                 options->hash_known_hosts = 0;
1300         if (options->tun_open == -1)
1301                 options->tun_open = SSH_TUNMODE_NO;
1302         if (options->tun_local == -1)
1303                 options->tun_local = SSH_TUNID_ANY;
1304         if (options->tun_remote == -1)
1305                 options->tun_remote = SSH_TUNID_ANY;
1306         if (options->permit_local_command == -1)
1307                 options->permit_local_command = 0;
1308         if (options->use_roaming == -1)
1309                 options->use_roaming = 1;
1310         if (options->visual_host_key == -1)
1311                 options->visual_host_key = 0;
1312         if (options->zero_knowledge_password_authentication == -1)
1313                 options->zero_knowledge_password_authentication = 0;
1314         if (options->ip_qos_interactive == -1)
1315                 options->ip_qos_interactive = IPTOS_LOWDELAY;
1316         if (options->ip_qos_bulk == -1)
1317                 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1318         /* options->local_command should not be set by default */
1319         /* options->proxy_command should not be set by default */
1320         /* options->user will be set in the main program if appropriate */
1321         /* options->hostname will be set in the main program if appropriate */
1322         /* options->host_key_alias should not be set by default */
1323         /* options->preferred_authentications will be set in ssh */
1324 }
1325
1326 /*
1327  * parse_forward
1328  * parses a string containing a port forwarding specification of the form:
1329  *   dynamicfwd == 0
1330  *      [listenhost:]listenport:connecthost:connectport
1331  *   dynamicfwd == 1
1332  *      [listenhost:]listenport
1333  * returns number of arguments parsed or zero on error
1334  */
1335 int
1336 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1337 {
1338         int i;
1339         char *p, *cp, *fwdarg[4];
1340
1341         memset(fwd, '\0', sizeof(*fwd));
1342
1343         cp = p = xstrdup(fwdspec);
1344
1345         /* skip leading spaces */
1346         while (isspace(*cp))
1347                 cp++;
1348
1349         for (i = 0; i < 4; ++i)
1350                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1351                         break;
1352
1353         /* Check for trailing garbage */
1354         if (cp != NULL)
1355                 i = 0;  /* failure */
1356
1357         switch (i) {
1358         case 1:
1359                 fwd->listen_host = NULL;
1360                 fwd->listen_port = a2port(fwdarg[0]);
1361                 fwd->connect_host = xstrdup("socks");
1362                 break;
1363
1364         case 2:
1365                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1366                 fwd->listen_port = a2port(fwdarg[1]);
1367                 fwd->connect_host = xstrdup("socks");
1368                 break;
1369
1370         case 3:
1371                 fwd->listen_host = NULL;
1372                 fwd->listen_port = a2port(fwdarg[0]);
1373                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1374                 fwd->connect_port = a2port(fwdarg[2]);
1375                 break;
1376
1377         case 4:
1378                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1379                 fwd->listen_port = a2port(fwdarg[1]);
1380                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1381                 fwd->connect_port = a2port(fwdarg[3]);
1382                 break;
1383         default:
1384                 i = 0; /* failure */
1385         }
1386
1387         xfree(p);
1388
1389         if (dynamicfwd) {
1390                 if (!(i == 1 || i == 2))
1391                         goto fail_free;
1392         } else {
1393                 if (!(i == 3 || i == 4))
1394                         goto fail_free;
1395                 if (fwd->connect_port <= 0)
1396                         goto fail_free;
1397         }
1398
1399         if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1400                 goto fail_free;
1401
1402         if (fwd->connect_host != NULL &&
1403             strlen(fwd->connect_host) >= NI_MAXHOST)
1404                 goto fail_free;
1405         if (fwd->listen_host != NULL &&
1406             strlen(fwd->listen_host) >= NI_MAXHOST)
1407                 goto fail_free;
1408
1409
1410         return (i);
1411
1412  fail_free:
1413         if (fwd->connect_host != NULL) {
1414                 xfree(fwd->connect_host);
1415                 fwd->connect_host = NULL;
1416         }
1417         if (fwd->listen_host != NULL) {
1418                 xfree(fwd->listen_host);
1419                 fwd->listen_host = NULL;
1420         }
1421         return (0);
1422 }