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