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