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