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