]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssh/readconf.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssh / readconf.c
1 /* $OpenBSD: readconf.c,v 1.196 2013/02/22 04:45:08 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, int userconfig)
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, userconfig);
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 flags)
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 (flags & SSHCONF_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,
1215                     &active, flags & SSHCONF_USERCONF) != 0)
1216                         bad_options++;
1217         }
1218         fclose(f);
1219         if (bad_options > 0)
1220                 fatal("%s: terminating, %d bad configuration options",
1221                     filename, bad_options);
1222         return 1;
1223 }
1224
1225 /*
1226  * Initializes options to special values that indicate that they have not yet
1227  * been set.  Read_config_file will only set options with this value. Options
1228  * are processed in the following order: command line, user config file,
1229  * system config file.  Last, fill_default_options is called.
1230  */
1231
1232 void
1233 initialize_options(Options * options)
1234 {
1235         memset(options, 'X', sizeof(*options));
1236         options->forward_agent = -1;
1237         options->forward_x11 = -1;
1238         options->forward_x11_trusted = -1;
1239         options->forward_x11_timeout = -1;
1240         options->exit_on_forward_failure = -1;
1241         options->xauth_location = NULL;
1242         options->gateway_ports = -1;
1243         options->use_privileged_port = -1;
1244         options->rsa_authentication = -1;
1245         options->pubkey_authentication = -1;
1246         options->challenge_response_authentication = -1;
1247         options->gss_authentication = -1;
1248         options->gss_deleg_creds = -1;
1249         options->password_authentication = -1;
1250         options->kbd_interactive_authentication = -1;
1251         options->kbd_interactive_devices = NULL;
1252         options->rhosts_rsa_authentication = -1;
1253         options->hostbased_authentication = -1;
1254         options->batch_mode = -1;
1255         options->check_host_ip = -1;
1256         options->strict_host_key_checking = -1;
1257         options->compression = -1;
1258         options->tcp_keep_alive = -1;
1259         options->compression_level = -1;
1260         options->port = -1;
1261         options->address_family = -1;
1262         options->connection_attempts = -1;
1263         options->connection_timeout = -1;
1264         options->number_of_password_prompts = -1;
1265         options->cipher = -1;
1266         options->ciphers = NULL;
1267         options->macs = NULL;
1268         options->kex_algorithms = NULL;
1269         options->hostkeyalgorithms = NULL;
1270         options->protocol = SSH_PROTO_UNKNOWN;
1271         options->num_identity_files = 0;
1272         options->hostname = NULL;
1273         options->host_key_alias = NULL;
1274         options->proxy_command = NULL;
1275         options->user = NULL;
1276         options->escape_char = -1;
1277         options->num_system_hostfiles = 0;
1278         options->num_user_hostfiles = 0;
1279         options->local_forwards = NULL;
1280         options->num_local_forwards = 0;
1281         options->remote_forwards = NULL;
1282         options->num_remote_forwards = 0;
1283         options->clear_forwardings = -1;
1284         options->log_level = SYSLOG_LEVEL_NOT_SET;
1285         options->preferred_authentications = NULL;
1286         options->bind_address = NULL;
1287         options->pkcs11_provider = NULL;
1288         options->enable_ssh_keysign = - 1;
1289         options->no_host_authentication_for_localhost = - 1;
1290         options->identities_only = - 1;
1291         options->rekey_limit = - 1;
1292         options->verify_host_key_dns = -1;
1293         options->server_alive_interval = -1;
1294         options->server_alive_count_max = -1;
1295         options->num_send_env = 0;
1296         options->control_path = NULL;
1297         options->control_master = -1;
1298         options->control_persist = -1;
1299         options->control_persist_timeout = 0;
1300         options->hash_known_hosts = -1;
1301         options->tun_open = -1;
1302         options->tun_local = -1;
1303         options->tun_remote = -1;
1304         options->local_command = NULL;
1305         options->permit_local_command = -1;
1306         options->use_roaming = -1;
1307         options->visual_host_key = -1;
1308         options->zero_knowledge_password_authentication = -1;
1309         options->ip_qos_interactive = -1;
1310         options->ip_qos_bulk = -1;
1311         options->request_tty = -1;
1312         options->version_addendum = NULL;
1313         options->hpn_disabled = -1;
1314         options->hpn_buffer_size = -1;
1315         options->tcp_rcv_buf_poll = -1;
1316         options->tcp_rcv_buf = -1;
1317 #ifdef NONE_CIPHER_ENABLED
1318         options->none_enabled = -1;
1319         options->none_switch = -1;
1320 #endif
1321 }
1322
1323 /*
1324  * Called after processing other sources of option data, this fills those
1325  * options for which no value has been specified with their default values.
1326  */
1327
1328 void
1329 fill_default_options(Options * options)
1330 {
1331         int len;
1332
1333         if (options->forward_agent == -1)
1334                 options->forward_agent = 0;
1335         if (options->forward_x11 == -1)
1336                 options->forward_x11 = 0;
1337         if (options->forward_x11_trusted == -1)
1338                 options->forward_x11_trusted = 0;
1339         if (options->forward_x11_timeout == -1)
1340                 options->forward_x11_timeout = 1200;
1341         if (options->exit_on_forward_failure == -1)
1342                 options->exit_on_forward_failure = 0;
1343         if (options->xauth_location == NULL)
1344                 options->xauth_location = _PATH_XAUTH;
1345         if (options->gateway_ports == -1)
1346                 options->gateway_ports = 0;
1347         if (options->use_privileged_port == -1)
1348                 options->use_privileged_port = 0;
1349         if (options->rsa_authentication == -1)
1350                 options->rsa_authentication = 1;
1351         if (options->pubkey_authentication == -1)
1352                 options->pubkey_authentication = 1;
1353         if (options->challenge_response_authentication == -1)
1354                 options->challenge_response_authentication = 1;
1355         if (options->gss_authentication == -1)
1356                 options->gss_authentication = 0;
1357         if (options->gss_deleg_creds == -1)
1358                 options->gss_deleg_creds = 0;
1359         if (options->password_authentication == -1)
1360                 options->password_authentication = 1;
1361         if (options->kbd_interactive_authentication == -1)
1362                 options->kbd_interactive_authentication = 1;
1363         if (options->rhosts_rsa_authentication == -1)
1364                 options->rhosts_rsa_authentication = 0;
1365         if (options->hostbased_authentication == -1)
1366                 options->hostbased_authentication = 0;
1367         if (options->batch_mode == -1)
1368                 options->batch_mode = 0;
1369         if (options->check_host_ip == -1)
1370                 options->check_host_ip = 0;
1371         if (options->strict_host_key_checking == -1)
1372                 options->strict_host_key_checking = 2;  /* 2 is default */
1373         if (options->compression == -1)
1374                 options->compression = 0;
1375         if (options->tcp_keep_alive == -1)
1376                 options->tcp_keep_alive = 1;
1377         if (options->compression_level == -1)
1378                 options->compression_level = 6;
1379         if (options->port == -1)
1380                 options->port = 0;      /* Filled in ssh_connect. */
1381         if (options->address_family == -1)
1382                 options->address_family = AF_UNSPEC;
1383         if (options->connection_attempts == -1)
1384                 options->connection_attempts = 1;
1385         if (options->number_of_password_prompts == -1)
1386                 options->number_of_password_prompts = 3;
1387         /* Selected in ssh_login(). */
1388         if (options->cipher == -1)
1389                 options->cipher = SSH_CIPHER_NOT_SET;
1390         /* options->ciphers, default set in myproposals.h */
1391         /* options->macs, default set in myproposals.h */
1392         /* options->kex_algorithms, default set in myproposals.h */
1393         /* options->hostkeyalgorithms, default set in myproposals.h */
1394         if (options->protocol == SSH_PROTO_UNKNOWN)
1395                 options->protocol = SSH_PROTO_2;
1396         if (options->num_identity_files == 0) {
1397                 if (options->protocol & SSH_PROTO_1) {
1398                         add_identity_file(options, "~/",
1399                             _PATH_SSH_CLIENT_IDENTITY, 0);
1400                 }
1401                 if (options->protocol & SSH_PROTO_2) {
1402                         add_identity_file(options, "~/",
1403                             _PATH_SSH_CLIENT_ID_RSA, 0);
1404                         add_identity_file(options, "~/",
1405                             _PATH_SSH_CLIENT_ID_DSA, 0);
1406 #ifdef OPENSSL_HAS_ECC
1407                         add_identity_file(options, "~/",
1408                             _PATH_SSH_CLIENT_ID_ECDSA, 0);
1409 #endif
1410                 }
1411         }
1412         if (options->escape_char == -1)
1413                 options->escape_char = '~';
1414         if (options->num_system_hostfiles == 0) {
1415                 options->system_hostfiles[options->num_system_hostfiles++] =
1416                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1417                 options->system_hostfiles[options->num_system_hostfiles++] =
1418                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1419         }
1420         if (options->num_user_hostfiles == 0) {
1421                 options->user_hostfiles[options->num_user_hostfiles++] =
1422                     xstrdup(_PATH_SSH_USER_HOSTFILE);
1423                 options->user_hostfiles[options->num_user_hostfiles++] =
1424                     xstrdup(_PATH_SSH_USER_HOSTFILE2);
1425         }
1426         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1427                 options->log_level = SYSLOG_LEVEL_INFO;
1428         if (options->clear_forwardings == 1)
1429                 clear_forwardings(options);
1430         if (options->no_host_authentication_for_localhost == - 1)
1431                 options->no_host_authentication_for_localhost = 0;
1432         if (options->identities_only == -1)
1433                 options->identities_only = 0;
1434         if (options->enable_ssh_keysign == -1)
1435                 options->enable_ssh_keysign = 0;
1436         if (options->rekey_limit == -1)
1437                 options->rekey_limit = 0;
1438         if (options->verify_host_key_dns == -1)
1439                 options->verify_host_key_dns = 0;
1440         if (options->server_alive_interval == -1)
1441                 options->server_alive_interval = 0;
1442         if (options->server_alive_count_max == -1)
1443                 options->server_alive_count_max = 3;
1444         if (options->control_master == -1)
1445                 options->control_master = 0;
1446         if (options->control_persist == -1) {
1447                 options->control_persist = 0;
1448                 options->control_persist_timeout = 0;
1449         }
1450         if (options->hash_known_hosts == -1)
1451                 options->hash_known_hosts = 0;
1452         if (options->tun_open == -1)
1453                 options->tun_open = SSH_TUNMODE_NO;
1454         if (options->tun_local == -1)
1455                 options->tun_local = SSH_TUNID_ANY;
1456         if (options->tun_remote == -1)
1457                 options->tun_remote = SSH_TUNID_ANY;
1458         if (options->permit_local_command == -1)
1459                 options->permit_local_command = 0;
1460         if (options->use_roaming == -1)
1461                 options->use_roaming = 1;
1462         if (options->visual_host_key == -1)
1463                 options->visual_host_key = 0;
1464         if (options->zero_knowledge_password_authentication == -1)
1465                 options->zero_knowledge_password_authentication = 0;
1466         if (options->ip_qos_interactive == -1)
1467                 options->ip_qos_interactive = IPTOS_LOWDELAY;
1468         if (options->ip_qos_bulk == -1)
1469                 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1470         if (options->request_tty == -1)
1471                 options->request_tty = REQUEST_TTY_AUTO;
1472         /* options->local_command should not be set by default */
1473         /* options->proxy_command should not be set by default */
1474         /* options->user will be set in the main program if appropriate */
1475         /* options->hostname will be set in the main program if appropriate */
1476         /* options->host_key_alias should not be set by default */
1477         /* options->preferred_authentications will be set in ssh */
1478         if (options->version_addendum == NULL)
1479                 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1480         if (options->hpn_disabled == -1)
1481                 options->hpn_disabled = 0;
1482         if (options->hpn_buffer_size > -1)
1483         {
1484                 u_int maxlen;
1485
1486                 /* If a user tries to set the size to 0 set it to 1KB. */
1487                 if (options->hpn_buffer_size == 0)
1488                         options->hpn_buffer_size = 1024;
1489                 /* Limit the buffer to BUFFER_MAX_LEN. */
1490                 maxlen = buffer_get_max_len();
1491                 if (options->hpn_buffer_size > (maxlen / 1024)) {
1492                         debug("User requested buffer larger than %ub: %ub. "
1493                             "Request reverted to %ub", maxlen,
1494                             options->hpn_buffer_size * 1024, maxlen);
1495                         options->hpn_buffer_size = maxlen;
1496                 }
1497                 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1498         }
1499         if (options->tcp_rcv_buf == 0)
1500                 options->tcp_rcv_buf = 1;
1501         if (options->tcp_rcv_buf > -1)
1502                 options->tcp_rcv_buf *= 1024;
1503         if (options->tcp_rcv_buf_poll == -1)
1504                 options->tcp_rcv_buf_poll = 1;
1505 #ifdef  NONE_CIPHER_ENABLED
1506         /* options->none_enabled must not be set by default */
1507         if (options->none_switch == -1)
1508                 options->none_switch = 0;
1509 #endif
1510 }
1511
1512 /*
1513  * parse_forward
1514  * parses a string containing a port forwarding specification of the form:
1515  *   dynamicfwd == 0
1516  *      [listenhost:]listenport:connecthost:connectport
1517  *   dynamicfwd == 1
1518  *      [listenhost:]listenport
1519  * returns number of arguments parsed or zero on error
1520  */
1521 int
1522 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1523 {
1524         int i;
1525         char *p, *cp, *fwdarg[4];
1526
1527         memset(fwd, '\0', sizeof(*fwd));
1528
1529         cp = p = xstrdup(fwdspec);
1530
1531         /* skip leading spaces */
1532         while (isspace(*cp))
1533                 cp++;
1534
1535         for (i = 0; i < 4; ++i)
1536                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1537                         break;
1538
1539         /* Check for trailing garbage */
1540         if (cp != NULL)
1541                 i = 0;  /* failure */
1542
1543         switch (i) {
1544         case 1:
1545                 fwd->listen_host = NULL;
1546                 fwd->listen_port = a2port(fwdarg[0]);
1547                 fwd->connect_host = xstrdup("socks");
1548                 break;
1549
1550         case 2:
1551                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1552                 fwd->listen_port = a2port(fwdarg[1]);
1553                 fwd->connect_host = xstrdup("socks");
1554                 break;
1555
1556         case 3:
1557                 fwd->listen_host = NULL;
1558                 fwd->listen_port = a2port(fwdarg[0]);
1559                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1560                 fwd->connect_port = a2port(fwdarg[2]);
1561                 break;
1562
1563         case 4:
1564                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1565                 fwd->listen_port = a2port(fwdarg[1]);
1566                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1567                 fwd->connect_port = a2port(fwdarg[3]);
1568                 break;
1569         default:
1570                 i = 0; /* failure */
1571         }
1572
1573         xfree(p);
1574
1575         if (dynamicfwd) {
1576                 if (!(i == 1 || i == 2))
1577                         goto fail_free;
1578         } else {
1579                 if (!(i == 3 || i == 4))
1580                         goto fail_free;
1581                 if (fwd->connect_port <= 0)
1582                         goto fail_free;
1583         }
1584
1585         if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1586                 goto fail_free;
1587
1588         if (fwd->connect_host != NULL &&
1589             strlen(fwd->connect_host) >= NI_MAXHOST)
1590                 goto fail_free;
1591         if (fwd->listen_host != NULL &&
1592             strlen(fwd->listen_host) >= NI_MAXHOST)
1593                 goto fail_free;
1594
1595
1596         return (i);
1597
1598  fail_free:
1599         if (fwd->connect_host != NULL) {
1600                 xfree(fwd->connect_host);
1601                 fwd->connect_host = NULL;
1602         }
1603         if (fwd->listen_host != NULL) {
1604                 xfree(fwd->listen_host);
1605                 fwd->listen_host = NULL;
1606         }
1607         return (0);
1608 }