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