lvalue casts.
[dragonfly.git] / crypto / openssh-3.9p1 / 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.134 2004/07/11 17:48:47 deraadt 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    # Defaults for various options
74    Host *
75      ForwardAgent no
76      ForwardX11 no
77      PasswordAuthentication yes
78      RSAAuthentication yes
79      RhostsRSAAuthentication yes
80      StrictHostKeyChecking yes
81      TcpKeepAlive no
82      IdentityFile ~/.ssh/identity
83      Port 22
84      EscapeChar ~
85
86 */
87
88 /* Keyword tokens. */
89
90 typedef enum {
91         oBadOption,
92         oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
93         oPasswordAuthentication, oRSAAuthentication,
94         oChallengeResponseAuthentication, oXAuthLocation,
95         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
96         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
97         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
98         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
99         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
100         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
101         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
102         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
103         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
104         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
105         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
106         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
108         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
109         oSendEnv, oControlPath, oControlMaster,
110         oDeprecated, oUnsupported
111 } OpCodes;
112
113 /* Textual representations of the tokens. */
114
115 static struct {
116         const char *name;
117         OpCodes opcode;
118 } keywords[] = {
119         { "forwardagent", oForwardAgent },
120         { "forwardx11", oForwardX11 },
121         { "forwardx11trusted", oForwardX11Trusted },
122         { "xauthlocation", oXAuthLocation },
123         { "gatewayports", oGatewayPorts },
124         { "useprivilegedport", oUsePrivilegedPort },
125         { "rhostsauthentication", oDeprecated },
126         { "passwordauthentication", oPasswordAuthentication },
127         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
128         { "kbdinteractivedevices", oKbdInteractiveDevices },
129         { "rsaauthentication", oRSAAuthentication },
130         { "pubkeyauthentication", oPubkeyAuthentication },
131         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
132         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
133         { "hostbasedauthentication", oHostbasedAuthentication },
134         { "challengeresponseauthentication", oChallengeResponseAuthentication },
135         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
136         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
137         { "kerberosauthentication", oUnsupported },
138         { "kerberostgtpassing", oUnsupported },
139         { "afstokenpassing", oUnsupported },
140 #if defined(GSSAPI)
141         { "gssapiauthentication", oGssAuthentication },
142         { "gssapidelegatecredentials", oGssDelegateCreds },
143 #else
144         { "gssapiauthentication", oUnsupported },
145         { "gssapidelegatecredentials", oUnsupported },
146 #endif
147         { "fallbacktorsh", oDeprecated },
148         { "usersh", oDeprecated },
149         { "identityfile", oIdentityFile },
150         { "identityfile2", oIdentityFile },                     /* alias */
151         { "identitiesonly", oIdentitiesOnly },
152         { "hostname", oHostName },
153         { "hostkeyalias", oHostKeyAlias },
154         { "proxycommand", oProxyCommand },
155         { "port", oPort },
156         { "cipher", oCipher },
157         { "ciphers", oCiphers },
158         { "macs", oMacs },
159         { "protocol", oProtocol },
160         { "remoteforward", oRemoteForward },
161         { "localforward", oLocalForward },
162         { "user", oUser },
163         { "host", oHost },
164         { "escapechar", oEscapeChar },
165         { "globalknownhostsfile", oGlobalKnownHostsFile },
166         { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
167         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
168         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
169         { "connectionattempts", oConnectionAttempts },
170         { "batchmode", oBatchMode },
171         { "checkhostip", oCheckHostIP },
172         { "stricthostkeychecking", oStrictHostKeyChecking },
173         { "compression", oCompression },
174         { "compressionlevel", oCompressionLevel },
175         { "tcpkeepalive", oTCPKeepAlive },
176         { "keepalive", oTCPKeepAlive },                         /* obsolete */
177         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
178         { "loglevel", oLogLevel },
179         { "dynamicforward", oDynamicForward },
180         { "preferredauthentications", oPreferredAuthentications },
181         { "hostkeyalgorithms", oHostKeyAlgorithms },
182         { "bindaddress", oBindAddress },
183 #ifdef SMARTCARD
184         { "smartcarddevice", oSmartcardDevice },
185 #else
186         { "smartcarddevice", oUnsupported },
187 #endif
188         { "clearallforwardings", oClearAllForwardings },
189         { "enablesshkeysign", oEnableSSHKeysign },
190         { "verifyhostkeydns", oVerifyHostKeyDNS },
191         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
192         { "rekeylimit", oRekeyLimit },
193         { "connecttimeout", oConnectTimeout },
194         { "addressfamily", oAddressFamily },
195         { "serveraliveinterval", oServerAliveInterval },
196         { "serveralivecountmax", oServerAliveCountMax },
197         { "sendenv", oSendEnv },
198         { "controlpath", oControlPath },
199         { "controlmaster", oControlMaster },
200         { NULL, oBadOption }
201 };
202
203 /*
204  * Adds a local TCP/IP port forward to options.  Never returns if there is an
205  * error.
206  */
207
208 void
209 add_local_forward(Options *options, u_short port, const char *host,
210                   u_short host_port)
211 {
212         Forward *fwd;
213 #ifndef NO_IPPORT_RESERVED_CONCEPT
214         extern uid_t original_real_uid;
215         if (port < IPPORT_RESERVED && original_real_uid != 0)
216                 fatal("Privileged ports can only be forwarded by root.");
217 #endif
218         if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
219                 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
220         fwd = &options->local_forwards[options->num_local_forwards++];
221         fwd->port = port;
222         fwd->host = xstrdup(host);
223         fwd->host_port = host_port;
224 }
225
226 /*
227  * Adds a remote TCP/IP port forward to options.  Never returns if there is
228  * an error.
229  */
230
231 void
232 add_remote_forward(Options *options, u_short port, const char *host,
233                    u_short host_port)
234 {
235         Forward *fwd;
236         if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
237                 fatal("Too many remote forwards (max %d).",
238                     SSH_MAX_FORWARDS_PER_DIRECTION);
239         fwd = &options->remote_forwards[options->num_remote_forwards++];
240         fwd->port = port;
241         fwd->host = xstrdup(host);
242         fwd->host_port = host_port;
243 }
244
245 static void
246 clear_forwardings(Options *options)
247 {
248         int i;
249
250         for (i = 0; i < options->num_local_forwards; i++)
251                 xfree(options->local_forwards[i].host);
252         options->num_local_forwards = 0;
253         for (i = 0; i < options->num_remote_forwards; i++)
254                 xfree(options->remote_forwards[i].host);
255         options->num_remote_forwards = 0;
256 }
257
258 /*
259  * Returns the number of the token pointed to by cp or oBadOption.
260  */
261
262 static OpCodes
263 parse_token(const char *cp, const char *filename, int linenum)
264 {
265         u_int i;
266
267         for (i = 0; keywords[i].name; i++)
268                 if (strcasecmp(cp, keywords[i].name) == 0)
269                         return keywords[i].opcode;
270
271         error("%s: line %d: Bad configuration option: %s",
272             filename, linenum, cp);
273         return oBadOption;
274 }
275
276 /*
277  * Processes a single option line as used in the configuration files. This
278  * only sets those values that have not already been set.
279  */
280 #define WHITESPACE " \t\r\n"
281
282 int
283 process_config_line(Options *options, const char *host,
284                     char *line, const char *filename, int linenum,
285                     int *activep)
286 {
287         char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
288         int opcode, *intptr, value;
289         size_t len;
290         u_short fwd_port, fwd_host_port;
291         char sfwd_host_port[6];
292
293         /* Strip trailing whitespace */
294         for(len = strlen(line) - 1; len > 0; len--) {
295                 if (strchr(WHITESPACE, line[len]) == NULL)
296                         break;
297                 line[len] = '\0';
298         }
299
300         s = line;
301         /* Get the keyword. (Each line is supposed to begin with a keyword). */
302         keyword = strdelim(&s);
303         /* Ignore leading whitespace. */
304         if (*keyword == '\0')
305                 keyword = strdelim(&s);
306         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
307                 return 0;
308
309         opcode = parse_token(keyword, filename, linenum);
310
311         switch (opcode) {
312         case oBadOption:
313                 /* don't panic, but count bad options */
314                 return -1;
315                 /* NOTREACHED */
316         case oConnectTimeout:
317                 intptr = &options->connection_timeout;
318 parse_time:
319                 arg = strdelim(&s);
320                 if (!arg || *arg == '\0')
321                         fatal("%s line %d: missing time value.",
322                             filename, linenum);
323                 if ((value = convtime(arg)) == -1)
324                         fatal("%s line %d: invalid time value.",
325                             filename, linenum);
326                 if (*intptr == -1)
327                         *intptr = value;
328                 break;
329
330         case oForwardAgent:
331                 intptr = &options->forward_agent;
332 parse_flag:
333                 arg = strdelim(&s);
334                 if (!arg || *arg == '\0')
335                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
336                 value = 0;      /* To avoid compiler warning... */
337                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
338                         value = 1;
339                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
340                         value = 0;
341                 else
342                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
343                 if (*activep && *intptr == -1)
344                         *intptr = value;
345                 break;
346
347         case oForwardX11:
348                 intptr = &options->forward_x11;
349                 goto parse_flag;
350
351         case oForwardX11Trusted:
352                 intptr = &options->forward_x11_trusted;
353                 goto parse_flag;
354
355         case oGatewayPorts:
356                 intptr = &options->gateway_ports;
357                 goto parse_flag;
358
359         case oUsePrivilegedPort:
360                 intptr = &options->use_privileged_port;
361                 goto parse_flag;
362
363         case oPasswordAuthentication:
364                 intptr = &options->password_authentication;
365                 goto parse_flag;
366
367         case oKbdInteractiveAuthentication:
368                 intptr = &options->kbd_interactive_authentication;
369                 goto parse_flag;
370
371         case oKbdInteractiveDevices:
372                 charptr = &options->kbd_interactive_devices;
373                 goto parse_string;
374
375         case oPubkeyAuthentication:
376                 intptr = &options->pubkey_authentication;
377                 goto parse_flag;
378
379         case oRSAAuthentication:
380                 intptr = &options->rsa_authentication;
381                 goto parse_flag;
382
383         case oRhostsRSAAuthentication:
384                 intptr = &options->rhosts_rsa_authentication;
385                 goto parse_flag;
386
387         case oHostbasedAuthentication:
388                 intptr = &options->hostbased_authentication;
389                 goto parse_flag;
390
391         case oChallengeResponseAuthentication:
392                 intptr = &options->challenge_response_authentication;
393                 goto parse_flag;
394
395         case oGssAuthentication:
396                 intptr = &options->gss_authentication;
397                 goto parse_flag;
398
399         case oGssDelegateCreds:
400                 intptr = &options->gss_deleg_creds;
401                 goto parse_flag;
402
403         case oBatchMode:
404                 intptr = &options->batch_mode;
405                 goto parse_flag;
406
407         case oCheckHostIP:
408                 intptr = &options->check_host_ip;
409                 goto parse_flag;
410
411         case oVerifyHostKeyDNS:
412                 intptr = &options->verify_host_key_dns;
413                 goto parse_yesnoask;
414
415         case oStrictHostKeyChecking:
416                 intptr = &options->strict_host_key_checking;
417 parse_yesnoask:
418                 arg = strdelim(&s);
419                 if (!arg || *arg == '\0')
420                         fatal("%.200s line %d: Missing yes/no/ask argument.",
421                             filename, linenum);
422                 value = 0;      /* To avoid compiler warning... */
423                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
424                         value = 1;
425                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
426                         value = 0;
427                 else if (strcmp(arg, "ask") == 0)
428                         value = 2;
429                 else
430                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
431                 if (*activep && *intptr == -1)
432                         *intptr = value;
433                 break;
434
435         case oCompression:
436                 intptr = &options->compression;
437                 goto parse_flag;
438
439         case oTCPKeepAlive:
440                 intptr = &options->tcp_keep_alive;
441                 goto parse_flag;
442
443         case oNoHostAuthenticationForLocalhost:
444                 intptr = &options->no_host_authentication_for_localhost;
445                 goto parse_flag;
446
447         case oNumberOfPasswordPrompts:
448                 intptr = &options->number_of_password_prompts;
449                 goto parse_int;
450
451         case oCompressionLevel:
452                 intptr = &options->compression_level;
453                 goto parse_int;
454
455         case oRekeyLimit:
456                 intptr = &options->rekey_limit;
457                 arg = strdelim(&s);
458                 if (!arg || *arg == '\0')
459                         fatal("%.200s line %d: Missing argument.", filename, linenum);
460                 if (arg[0] < '0' || arg[0] > '9')
461                         fatal("%.200s line %d: Bad number.", filename, linenum);
462                 value = strtol(arg, &endofnumber, 10);
463                 if (arg == endofnumber)
464                         fatal("%.200s line %d: Bad number.", filename, linenum);
465                 switch (toupper(*endofnumber)) {
466                 case 'K':
467                         value *= 1<<10;
468                         break;
469                 case 'M':
470                         value *= 1<<20;
471                         break;
472                 case 'G':
473                         value *= 1<<30;
474                         break;
475                 }
476                 if (*activep && *intptr == -1)
477                         *intptr = value;
478                 break;
479
480         case oIdentityFile:
481                 arg = strdelim(&s);
482                 if (!arg || *arg == '\0')
483                         fatal("%.200s line %d: Missing argument.", filename, linenum);
484                 if (*activep) {
485                         intptr = &options->num_identity_files;
486                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
487                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
488                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
489                         charptr =  &options->identity_files[*intptr];
490                         *charptr = xstrdup(arg);
491                         *intptr = *intptr + 1;
492                 }
493                 break;
494
495         case oXAuthLocation:
496                 charptr=&options->xauth_location;
497                 goto parse_string;
498
499         case oUser:
500                 charptr = &options->user;
501 parse_string:
502                 arg = strdelim(&s);
503                 if (!arg || *arg == '\0')
504                         fatal("%.200s line %d: Missing argument.", filename, linenum);
505                 if (*activep && *charptr == NULL)
506                         *charptr = xstrdup(arg);
507                 break;
508
509         case oGlobalKnownHostsFile:
510                 charptr = &options->system_hostfile;
511                 goto parse_string;
512
513         case oUserKnownHostsFile:
514                 charptr = &options->user_hostfile;
515                 goto parse_string;
516
517         case oGlobalKnownHostsFile2:
518                 charptr = &options->system_hostfile2;
519                 goto parse_string;
520
521         case oUserKnownHostsFile2:
522                 charptr = &options->user_hostfile2;
523                 goto parse_string;
524
525         case oHostName:
526                 charptr = &options->hostname;
527                 goto parse_string;
528
529         case oHostKeyAlias:
530                 charptr = &options->host_key_alias;
531                 goto parse_string;
532
533         case oPreferredAuthentications:
534                 charptr = &options->preferred_authentications;
535                 goto parse_string;
536
537         case oBindAddress:
538                 charptr = &options->bind_address;
539                 goto parse_string;
540
541         case oSmartcardDevice:
542                 charptr = &options->smartcard_device;
543                 goto parse_string;
544
545         case oProxyCommand:
546                 if (s == NULL)
547                         fatal("%.200s line %d: Missing argument.", filename, linenum);
548                 charptr = &options->proxy_command;
549                 len = strspn(s, WHITESPACE "=");
550                 if (*activep && *charptr == NULL)
551                         *charptr = xstrdup(s + len);
552                 return 0;
553
554         case oPort:
555                 intptr = &options->port;
556 parse_int:
557                 arg = strdelim(&s);
558                 if (!arg || *arg == '\0')
559                         fatal("%.200s line %d: Missing argument.", filename, linenum);
560                 if (arg[0] < '0' || arg[0] > '9')
561                         fatal("%.200s line %d: Bad number.", filename, linenum);
562
563                 /* Octal, decimal, or hex format? */
564                 value = strtol(arg, &endofnumber, 0);
565                 if (arg == endofnumber)
566                         fatal("%.200s line %d: Bad number.", filename, linenum);
567                 if (*activep && *intptr == -1)
568                         *intptr = value;
569                 break;
570
571         case oConnectionAttempts:
572                 intptr = &options->connection_attempts;
573                 goto parse_int;
574
575         case oCipher:
576                 intptr = &options->cipher;
577                 arg = strdelim(&s);
578                 if (!arg || *arg == '\0')
579                         fatal("%.200s line %d: Missing argument.", filename, linenum);
580                 value = cipher_number(arg);
581                 if (value == -1)
582                         fatal("%.200s line %d: Bad cipher '%s'.",
583                             filename, linenum, arg ? arg : "<NONE>");
584                 if (*activep && *intptr == -1)
585                         *intptr = value;
586                 break;
587
588         case oCiphers:
589                 arg = strdelim(&s);
590                 if (!arg || *arg == '\0')
591                         fatal("%.200s line %d: Missing argument.", filename, linenum);
592                 if (!ciphers_valid(arg))
593                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
594                             filename, linenum, arg ? arg : "<NONE>");
595                 if (*activep && options->ciphers == NULL)
596                         options->ciphers = xstrdup(arg);
597                 break;
598
599         case oMacs:
600                 arg = strdelim(&s);
601                 if (!arg || *arg == '\0')
602                         fatal("%.200s line %d: Missing argument.", filename, linenum);
603                 if (!mac_valid(arg))
604                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
605                             filename, linenum, arg ? arg : "<NONE>");
606                 if (*activep && options->macs == NULL)
607                         options->macs = xstrdup(arg);
608                 break;
609
610         case oHostKeyAlgorithms:
611                 arg = strdelim(&s);
612                 if (!arg || *arg == '\0')
613                         fatal("%.200s line %d: Missing argument.", filename, linenum);
614                 if (!key_names_valid2(arg))
615                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
616                             filename, linenum, arg ? arg : "<NONE>");
617                 if (*activep && options->hostkeyalgorithms == NULL)
618                         options->hostkeyalgorithms = xstrdup(arg);
619                 break;
620
621         case oProtocol:
622                 intptr = &options->protocol;
623                 arg = strdelim(&s);
624                 if (!arg || *arg == '\0')
625                         fatal("%.200s line %d: Missing argument.", filename, linenum);
626                 value = proto_spec(arg);
627                 if (value == SSH_PROTO_UNKNOWN)
628                         fatal("%.200s line %d: Bad protocol spec '%s'.",
629                             filename, linenum, arg ? arg : "<NONE>");
630                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
631                         *intptr = value;
632                 break;
633
634         case oLogLevel:
635                 intptr = (int *) &options->log_level;
636                 arg = strdelim(&s);
637                 value = log_level_number(arg);
638                 if (value == SYSLOG_LEVEL_NOT_SET)
639                         fatal("%.200s line %d: unsupported log level '%s'",
640                             filename, linenum, arg ? arg : "<NONE>");
641                 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
642                         *intptr = (LogLevel) value;
643                 break;
644
645         case oLocalForward:
646         case oRemoteForward:
647                 arg = strdelim(&s);
648                 if (!arg || *arg == '\0')
649                         fatal("%.200s line %d: Missing port argument.",
650                             filename, linenum);
651                 if ((fwd_port = a2port(arg)) == 0)
652                         fatal("%.200s line %d: Bad listen port.",
653                             filename, linenum);
654                 arg = strdelim(&s);
655                 if (!arg || *arg == '\0')
656                         fatal("%.200s line %d: Missing second argument.",
657                             filename, linenum);
658                 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
659                     sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
660                         fatal("%.200s line %d: Bad forwarding specification.",
661                             filename, linenum);
662                 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
663                         fatal("%.200s line %d: Bad forwarding port.",
664                             filename, linenum);
665                 if (*activep) {
666                         if (opcode == oLocalForward)
667                                 add_local_forward(options, fwd_port, buf,
668                                     fwd_host_port);
669                         else if (opcode == oRemoteForward)
670                                 add_remote_forward(options, fwd_port, buf,
671                                     fwd_host_port);
672                 }
673                 break;
674
675         case oDynamicForward:
676                 arg = strdelim(&s);
677                 if (!arg || *arg == '\0')
678                         fatal("%.200s line %d: Missing port argument.",
679                             filename, linenum);
680                 fwd_port = a2port(arg);
681                 if (fwd_port == 0)
682                         fatal("%.200s line %d: Badly formatted port number.",
683                             filename, linenum);
684                 if (*activep)
685                         add_local_forward(options, fwd_port, "socks", 0);
686                 break;
687
688         case oClearAllForwardings:
689                 intptr = &options->clear_forwardings;
690                 goto parse_flag;
691
692         case oHost:
693                 *activep = 0;
694                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
695                         if (match_pattern(host, arg)) {
696                                 debug("Applying options for %.100s", arg);
697                                 *activep = 1;
698                                 break;
699                         }
700                 /* Avoid garbage check below, as strdelim is done. */
701                 return 0;
702
703         case oEscapeChar:
704                 intptr = &options->escape_char;
705                 arg = strdelim(&s);
706                 if (!arg || *arg == '\0')
707                         fatal("%.200s line %d: Missing argument.", filename, linenum);
708                 if (arg[0] == '^' && arg[2] == 0 &&
709                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
710                         value = (u_char) arg[1] & 31;
711                 else if (strlen(arg) == 1)
712                         value = (u_char) arg[0];
713                 else if (strcmp(arg, "none") == 0)
714                         value = SSH_ESCAPECHAR_NONE;
715                 else {
716                         fatal("%.200s line %d: Bad escape character.",
717                             filename, linenum);
718                         /* NOTREACHED */
719                         value = 0;      /* Avoid compiler warning. */
720                 }
721                 if (*activep && *intptr == -1)
722                         *intptr = value;
723                 break;
724
725         case oAddressFamily:
726                 arg = strdelim(&s);
727                 intptr = &options->address_family;
728                 if (strcasecmp(arg, "inet") == 0)
729                         value = AF_INET;
730                 else if (strcasecmp(arg, "inet6") == 0)
731                         value = AF_INET6;
732                 else if (strcasecmp(arg, "any") == 0)
733                         value = AF_UNSPEC;
734                 else
735                         fatal("Unsupported AddressFamily \"%s\"", arg);
736                 if (*activep && *intptr == -1)
737                         *intptr = value;
738                 break;
739
740         case oEnableSSHKeysign:
741                 intptr = &options->enable_ssh_keysign;
742                 goto parse_flag;
743
744         case oIdentitiesOnly:
745                 intptr = &options->identities_only;
746                 goto parse_flag;
747
748         case oServerAliveInterval:
749                 intptr = &options->server_alive_interval;
750                 goto parse_time;
751
752         case oServerAliveCountMax:
753                 intptr = &options->server_alive_count_max;
754                 goto parse_int;
755
756         case oSendEnv:
757                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
758                         if (strchr(arg, '=') != NULL)
759                                 fatal("%s line %d: Invalid environment name.",
760                                     filename, linenum);
761                         if (options->num_send_env >= MAX_SEND_ENV)
762                                 fatal("%s line %d: too many send env.",
763                                     filename, linenum);
764                         options->send_env[options->num_send_env++] =
765                             xstrdup(arg);
766                 }
767                 break;
768
769         case oControlPath:
770                 charptr = &options->control_path;
771                 goto parse_string;
772
773         case oControlMaster:
774                 intptr = &options->control_master;
775                 goto parse_yesnoask;
776
777         case oDeprecated:
778                 debug("%s line %d: Deprecated option \"%s\"",
779                     filename, linenum, keyword);
780                 return 0;
781
782         case oUnsupported:
783                 error("%s line %d: Unsupported option \"%s\"",
784                     filename, linenum, keyword);
785                 return 0;
786
787         default:
788                 fatal("process_config_line: Unimplemented opcode %d", opcode);
789         }
790
791         /* Check that there is no garbage at end of line. */
792         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
793                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
794                      filename, linenum, arg);
795         }
796         return 0;
797 }
798
799
800 /*
801  * Reads the config file and modifies the options accordingly.  Options
802  * should already be initialized before this call.  This never returns if
803  * there is an error.  If the file does not exist, this returns 0.
804  */
805
806 int
807 read_config_file(const char *filename, const char *host, Options *options,
808     int checkperm)
809 {
810         FILE *f;
811         char line[1024];
812         int active, linenum;
813         int bad_options = 0;
814
815         /* Open the file. */
816         if ((f = fopen(filename, "r")) == NULL)
817                 return 0;
818
819         if (checkperm) {
820                 struct stat sb;
821
822                 if (fstat(fileno(f), &sb) == -1)
823                         fatal("fstat %s: %s", filename, strerror(errno));
824                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
825                     (sb.st_mode & 022) != 0))
826                         fatal("Bad owner or permissions on %s", filename);
827         }
828
829         debug("Reading configuration data %.200s", filename);
830
831         /*
832          * Mark that we are now processing the options.  This flag is turned
833          * on/off by Host specifications.
834          */
835         active = 1;
836         linenum = 0;
837         while (fgets(line, sizeof(line), f)) {
838                 /* Update line number counter. */
839                 linenum++;
840                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
841                         bad_options++;
842         }
843         fclose(f);
844         if (bad_options > 0)
845                 fatal("%s: terminating, %d bad configuration options",
846                     filename, bad_options);
847         return 1;
848 }
849
850 /*
851  * Initializes options to special values that indicate that they have not yet
852  * been set.  Read_config_file will only set options with this value. Options
853  * are processed in the following order: command line, user config file,
854  * system config file.  Last, fill_default_options is called.
855  */
856
857 void
858 initialize_options(Options * options)
859 {
860         memset(options, 'X', sizeof(*options));
861         options->forward_agent = -1;
862         options->forward_x11 = -1;
863         options->forward_x11_trusted = -1;
864         options->xauth_location = NULL;
865         options->gateway_ports = -1;
866         options->use_privileged_port = -1;
867         options->rsa_authentication = -1;
868         options->pubkey_authentication = -1;
869         options->challenge_response_authentication = -1;
870         options->gss_authentication = -1;
871         options->gss_deleg_creds = -1;
872         options->password_authentication = -1;
873         options->kbd_interactive_authentication = -1;
874         options->kbd_interactive_devices = NULL;
875         options->rhosts_rsa_authentication = -1;
876         options->hostbased_authentication = -1;
877         options->batch_mode = -1;
878         options->check_host_ip = -1;
879         options->strict_host_key_checking = -1;
880         options->compression = -1;
881         options->tcp_keep_alive = -1;
882         options->compression_level = -1;
883         options->port = -1;
884         options->address_family = -1;
885         options->connection_attempts = -1;
886         options->connection_timeout = -1;
887         options->number_of_password_prompts = -1;
888         options->cipher = -1;
889         options->ciphers = NULL;
890         options->macs = NULL;
891         options->hostkeyalgorithms = NULL;
892         options->protocol = SSH_PROTO_UNKNOWN;
893         options->num_identity_files = 0;
894         options->hostname = NULL;
895         options->host_key_alias = NULL;
896         options->proxy_command = NULL;
897         options->user = NULL;
898         options->escape_char = -1;
899         options->system_hostfile = NULL;
900         options->user_hostfile = NULL;
901         options->system_hostfile2 = NULL;
902         options->user_hostfile2 = NULL;
903         options->num_local_forwards = 0;
904         options->num_remote_forwards = 0;
905         options->clear_forwardings = -1;
906         options->log_level = SYSLOG_LEVEL_NOT_SET;
907         options->preferred_authentications = NULL;
908         options->bind_address = NULL;
909         options->smartcard_device = NULL;
910         options->enable_ssh_keysign = - 1;
911         options->no_host_authentication_for_localhost = - 1;
912         options->identities_only = - 1;
913         options->rekey_limit = - 1;
914         options->verify_host_key_dns = -1;
915         options->server_alive_interval = -1;
916         options->server_alive_count_max = -1;
917         options->num_send_env = 0;
918         options->control_path = NULL;
919         options->control_master = -1;
920 }
921
922 /*
923  * Called after processing other sources of option data, this fills those
924  * options for which no value has been specified with their default values.
925  */
926
927 void
928 fill_default_options(Options * options)
929 {
930         int len;
931
932         if (options->forward_agent == -1)
933                 options->forward_agent = 0;
934         if (options->forward_x11 == -1)
935                 options->forward_x11 = 0;
936         if (options->forward_x11_trusted == -1)
937                 options->forward_x11_trusted = 0;
938         if (options->xauth_location == NULL)
939                 options->xauth_location = _PATH_XAUTH;
940         if (options->gateway_ports == -1)
941                 options->gateway_ports = 0;
942         if (options->use_privileged_port == -1)
943                 options->use_privileged_port = 0;
944         if (options->rsa_authentication == -1)
945                 options->rsa_authentication = 1;
946         if (options->pubkey_authentication == -1)
947                 options->pubkey_authentication = 1;
948         if (options->challenge_response_authentication == -1)
949                 options->challenge_response_authentication = 1;
950         if (options->gss_authentication == -1)
951                 options->gss_authentication = 0;
952         if (options->gss_deleg_creds == -1)
953                 options->gss_deleg_creds = 0;
954         if (options->password_authentication == -1)
955                 options->password_authentication = 1;
956         if (options->kbd_interactive_authentication == -1)
957                 options->kbd_interactive_authentication = 1;
958         if (options->rhosts_rsa_authentication == -1)
959                 options->rhosts_rsa_authentication = 0;
960         if (options->hostbased_authentication == -1)
961                 options->hostbased_authentication = 0;
962         if (options->batch_mode == -1)
963                 options->batch_mode = 0;
964         if (options->check_host_ip == -1)
965                 options->check_host_ip = 1;
966         if (options->strict_host_key_checking == -1)
967                 options->strict_host_key_checking = 2;  /* 2 is default */
968         if (options->compression == -1)
969                 options->compression = 0;
970         if (options->tcp_keep_alive == -1)
971                 options->tcp_keep_alive = 1;
972         if (options->compression_level == -1)
973                 options->compression_level = 6;
974         if (options->port == -1)
975                 options->port = 0;      /* Filled in ssh_connect. */
976         if (options->address_family == -1)
977                 options->address_family = AF_UNSPEC;
978         if (options->connection_attempts == -1)
979                 options->connection_attempts = 1;
980         if (options->number_of_password_prompts == -1)
981                 options->number_of_password_prompts = 3;
982         /* Selected in ssh_login(). */
983         if (options->cipher == -1)
984                 options->cipher = SSH_CIPHER_NOT_SET;
985         /* options->ciphers, default set in myproposals.h */
986         /* options->macs, default set in myproposals.h */
987         /* options->hostkeyalgorithms, default set in myproposals.h */
988         if (options->protocol == SSH_PROTO_UNKNOWN)
989                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
990         if (options->num_identity_files == 0) {
991                 if (options->protocol & SSH_PROTO_1) {
992                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
993                         options->identity_files[options->num_identity_files] =
994                             xmalloc(len);
995                         snprintf(options->identity_files[options->num_identity_files++],
996                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
997                 }
998                 if (options->protocol & SSH_PROTO_2) {
999                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1000                         options->identity_files[options->num_identity_files] =
1001                             xmalloc(len);
1002                         snprintf(options->identity_files[options->num_identity_files++],
1003                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1004
1005                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1006                         options->identity_files[options->num_identity_files] =
1007                             xmalloc(len);
1008                         snprintf(options->identity_files[options->num_identity_files++],
1009                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1010                 }
1011         }
1012         if (options->escape_char == -1)
1013                 options->escape_char = '~';
1014         if (options->system_hostfile == NULL)
1015                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1016         if (options->user_hostfile == NULL)
1017                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1018         if (options->system_hostfile2 == NULL)
1019                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1020         if (options->user_hostfile2 == NULL)
1021                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1022         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1023                 options->log_level = SYSLOG_LEVEL_INFO;
1024         if (options->clear_forwardings == 1)
1025                 clear_forwardings(options);
1026         if (options->no_host_authentication_for_localhost == - 1)
1027                 options->no_host_authentication_for_localhost = 0;
1028         if (options->identities_only == -1)
1029                 options->identities_only = 0;
1030         if (options->enable_ssh_keysign == -1)
1031                 options->enable_ssh_keysign = 0;
1032         if (options->rekey_limit == -1)
1033                 options->rekey_limit = 0;
1034         if (options->verify_host_key_dns == -1)
1035                 options->verify_host_key_dns = 0;
1036         if (options->server_alive_interval == -1)
1037                 options->server_alive_interval = 0;
1038         if (options->server_alive_count_max == -1)
1039                 options->server_alive_count_max = 3;
1040         if (options->control_master == -1)
1041                 options->control_master = 0;
1042         /* options->proxy_command should not be set by default */
1043         /* options->user will be set in the main program if appropriate */
1044         /* options->hostname will be set in the main program if appropriate */
1045         /* options->host_key_alias should not be set by default */
1046         /* options->preferred_authentications will be set in ssh */
1047 }