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