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