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