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