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