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