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