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