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