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