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