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