]> andersk Git - openssh.git/blob - readconf.c
- dugsong@cvs.openbsd.org 2001/06/26 16:15:25
[openssh.git] / 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.82 2001/06/26 16:15:23 dugsong 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      FallBackToRsh no
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      RhostsAuthentication no
61      PasswordAuthentication no
62
63    Host puukko.hut.fi
64      User t35124p
65      ProxyCommand ssh-proxy %h %p
66
67    Host *.fr
68      UseRsh yes
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      RhostsAuthentication yes
79      PasswordAuthentication yes
80      RSAAuthentication yes
81      RhostsRSAAuthentication yes
82      FallBackToRsh no
83      UseRsh no
84      StrictHostKeyChecking yes
85      KeepAlives no
86      IdentityFile ~/.ssh/identity
87      Port 22
88      EscapeChar ~
89
90 */
91
92 /* Keyword tokens. */
93
94 typedef enum {
95         oBadOption,
96         oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97         oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98         oChallengeResponseAuthentication, oXAuthLocation,
99 #if defined(KRB4) || defined(KRB5)
100         oKerberosAuthentication,
101 #endif
102 #if defined(AFS) || defined(KRB5)
103         oKerberosTgtPassing,
104 #endif
105 #ifdef AFS
106         oAFSTokenPassing,
107 #endif
108         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
109         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
110         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
111         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
112         oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
113         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
114         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
115         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
116         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
117         oHostKeyAlgorithms, oBindAddress
118 } OpCodes;
119
120 /* Textual representations of the tokens. */
121
122 static struct {
123         const char *name;
124         OpCodes opcode;
125 } keywords[] = {
126         { "forwardagent", oForwardAgent },
127         { "forwardx11", oForwardX11 },
128         { "xauthlocation", oXAuthLocation },
129         { "gatewayports", oGatewayPorts },
130         { "useprivilegedport", oUsePrivilegedPort },
131         { "rhostsauthentication", oRhostsAuthentication },
132         { "passwordauthentication", oPasswordAuthentication },
133         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
134         { "kbdinteractivedevices", oKbdInteractiveDevices },
135         { "rsaauthentication", oRSAAuthentication },
136         { "pubkeyauthentication", oPubkeyAuthentication },
137         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
138         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
139         { "hostbasedauthentication", oHostbasedAuthentication },
140         { "challengeresponseauthentication", oChallengeResponseAuthentication },
141         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
142         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
143 #if defined(KRB4) || defined(KRB5)
144         { "kerberosauthentication", oKerberosAuthentication },
145 #endif
146 #if defined(AFS) || defined(KRB5)
147         { "kerberostgtpassing", oKerberosTgtPassing },
148 #endif
149 #ifdef AFS
150         { "afstokenpassing", oAFSTokenPassing },
151 #endif
152         { "fallbacktorsh", oFallBackToRsh },
153         { "usersh", oUseRsh },
154         { "identityfile", oIdentityFile },
155         { "identityfile2", oIdentityFile },                     /* alias */
156         { "hostname", oHostName },
157         { "hostkeyalias", oHostKeyAlias },
158         { "proxycommand", oProxyCommand },
159         { "port", oPort },
160         { "cipher", oCipher },
161         { "ciphers", oCiphers },
162         { "macs", oMacs },
163         { "protocol", oProtocol },
164         { "remoteforward", oRemoteForward },
165         { "localforward", oLocalForward },
166         { "user", oUser },
167         { "host", oHost },
168         { "escapechar", oEscapeChar },
169         { "globalknownhostsfile", oGlobalKnownHostsFile },
170         { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
171         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
172         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
173         { "connectionattempts", oConnectionAttempts },
174         { "batchmode", oBatchMode },
175         { "checkhostip", oCheckHostIP },
176         { "stricthostkeychecking", oStrictHostKeyChecking },
177         { "compression", oCompression },
178         { "compressionlevel", oCompressionLevel },
179         { "keepalive", oKeepAlives },
180         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
181         { "loglevel", oLogLevel },
182         { "dynamicforward", oDynamicForward },
183         { "preferredauthentications", oPreferredAuthentications },
184         { "hostkeyalgorithms", oHostKeyAlgorithms },
185         { "bindaddress", oBindAddress },
186         { NULL, 0 }
187 };
188
189 /*
190  * Adds a local TCP/IP port forward to options.  Never returns if there is an
191  * error.
192  */
193
194 void
195 add_local_forward(Options *options, u_short port, const char *host,
196                   u_short host_port)
197 {
198         Forward *fwd;
199 #ifndef HAVE_CYGWIN
200         extern uid_t original_real_uid;
201         if (port < IPPORT_RESERVED && original_real_uid != 0)
202                 fatal("Privileged ports can only be forwarded by root.");
203 #endif
204         if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
205                 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
206         fwd = &options->local_forwards[options->num_local_forwards++];
207         fwd->port = port;
208         fwd->host = xstrdup(host);
209         fwd->host_port = host_port;
210 }
211
212 /*
213  * Adds a remote TCP/IP port forward to options.  Never returns if there is
214  * an error.
215  */
216
217 void
218 add_remote_forward(Options *options, u_short port, const char *host,
219                    u_short host_port)
220 {
221         Forward *fwd;
222         if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
223                 fatal("Too many remote forwards (max %d).",
224                       SSH_MAX_FORWARDS_PER_DIRECTION);
225         fwd = &options->remote_forwards[options->num_remote_forwards++];
226         fwd->port = port;
227         fwd->host = xstrdup(host);
228         fwd->host_port = host_port;
229 }
230
231 /*
232  * Returns the number of the token pointed to by cp or oBadOption.
233  */
234
235 static OpCodes
236 parse_token(const char *cp, const char *filename, int linenum)
237 {
238         u_int i;
239
240         for (i = 0; keywords[i].name; i++)
241                 if (strcasecmp(cp, keywords[i].name) == 0)
242                         return keywords[i].opcode;
243
244         error("%s: line %d: Bad configuration option: %s",
245             filename, linenum, cp);
246         return oBadOption;
247 }
248
249 /*
250  * Processes a single option line as used in the configuration files. This
251  * only sets those values that have not already been set.
252  */
253
254 int
255 process_config_line(Options *options, const char *host,
256                     char *line, const char *filename, int linenum,
257                     int *activep)
258 {
259         char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
260         int opcode, *intptr, value;
261         u_short fwd_port, fwd_host_port;
262
263         s = line;
264         /* Get the keyword. (Each line is supposed to begin with a keyword). */
265         keyword = strdelim(&s);
266         /* Ignore leading whitespace. */
267         if (*keyword == '\0')
268                 keyword = strdelim(&s);
269         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
270                 return 0;
271
272         opcode = parse_token(keyword, filename, linenum);
273
274         switch (opcode) {
275         case oBadOption:
276                 /* don't panic, but count bad options */
277                 return -1;
278                 /* NOTREACHED */
279         case oForwardAgent:
280                 intptr = &options->forward_agent;
281 parse_flag:
282                 arg = strdelim(&s);
283                 if (!arg || *arg == '\0')
284                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
285                 value = 0;      /* To avoid compiler warning... */
286                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
287                         value = 1;
288                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
289                         value = 0;
290                 else
291                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
292                 if (*activep && *intptr == -1)
293                         *intptr = value;
294                 break;
295
296         case oForwardX11:
297                 intptr = &options->forward_x11;
298                 goto parse_flag;
299
300         case oGatewayPorts:
301                 intptr = &options->gateway_ports;
302                 goto parse_flag;
303
304         case oUsePrivilegedPort:
305                 intptr = &options->use_privileged_port;
306                 goto parse_flag;
307
308         case oRhostsAuthentication:
309                 intptr = &options->rhosts_authentication;
310                 goto parse_flag;
311
312         case oPasswordAuthentication:
313                 intptr = &options->password_authentication;
314                 goto parse_flag;
315
316         case oKbdInteractiveAuthentication:
317                 intptr = &options->kbd_interactive_authentication;
318                 goto parse_flag;
319
320         case oKbdInteractiveDevices:
321                 charptr = &options->kbd_interactive_devices;
322                 goto parse_string;
323
324         case oPubkeyAuthentication:
325                 intptr = &options->pubkey_authentication;
326                 goto parse_flag;
327
328         case oRSAAuthentication:
329                 intptr = &options->rsa_authentication;
330                 goto parse_flag;
331
332         case oRhostsRSAAuthentication:
333                 intptr = &options->rhosts_rsa_authentication;
334                 goto parse_flag;
335
336         case oHostbasedAuthentication:
337                 intptr = &options->hostbased_authentication;
338                 goto parse_flag;
339
340         case oChallengeResponseAuthentication:
341                 intptr = &options->challenge_response_authentication;
342                 goto parse_flag;
343 #if defined(KRB4) || defined(KRB5)
344         case oKerberosAuthentication:
345                 intptr = &options->kerberos_authentication;
346                 goto parse_flag;
347 #endif
348 #if defined(AFS) || defined(KRB5)
349         case oKerberosTgtPassing:
350                 intptr = &options->kerberos_tgt_passing;
351                 goto parse_flag;
352 #endif
353 #ifdef AFS
354         case oAFSTokenPassing:
355                 intptr = &options->afs_token_passing;
356                 goto parse_flag;
357 #endif
358         case oFallBackToRsh:
359                 intptr = &options->fallback_to_rsh;
360                 goto parse_flag;
361
362         case oUseRsh:
363                 intptr = &options->use_rsh;
364                 goto parse_flag;
365
366         case oBatchMode:
367                 intptr = &options->batch_mode;
368                 goto parse_flag;
369
370         case oCheckHostIP:
371                 intptr = &options->check_host_ip;
372                 goto parse_flag;
373
374         case oStrictHostKeyChecking:
375                 intptr = &options->strict_host_key_checking;
376                 arg = strdelim(&s);
377                 if (!arg || *arg == '\0')
378                         fatal("%.200s line %d: Missing yes/no/ask argument.",
379                               filename, linenum);
380                 value = 0;      /* To avoid compiler warning... */
381                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
382                         value = 1;
383                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
384                         value = 0;
385                 else if (strcmp(arg, "ask") == 0)
386                         value = 2;
387                 else
388                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
389                 if (*activep && *intptr == -1)
390                         *intptr = value;
391                 break;
392
393         case oCompression:
394                 intptr = &options->compression;
395                 goto parse_flag;
396
397         case oKeepAlives:
398                 intptr = &options->keepalives;
399                 goto parse_flag;
400
401         case oNumberOfPasswordPrompts:
402                 intptr = &options->number_of_password_prompts;
403                 goto parse_int;
404
405         case oCompressionLevel:
406                 intptr = &options->compression_level;
407                 goto parse_int;
408
409         case oIdentityFile:
410                 arg = strdelim(&s);
411                 if (!arg || *arg == '\0')
412                         fatal("%.200s line %d: Missing argument.", filename, linenum);
413                 if (*activep) {
414                         intptr = &options->num_identity_files;
415                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
416                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
417                                       filename, linenum, SSH_MAX_IDENTITY_FILES);
418                         charptr =  &options->identity_files[*intptr];
419                         *charptr = xstrdup(arg);
420                         *intptr = *intptr + 1;
421                 }
422                 break;
423
424         case oXAuthLocation:
425                 charptr=&options->xauth_location;
426                 goto parse_string;
427
428         case oUser:
429                 charptr = &options->user;
430 parse_string:
431                 arg = strdelim(&s);
432                 if (!arg || *arg == '\0')
433                         fatal("%.200s line %d: Missing argument.", filename, linenum);
434                 if (*activep && *charptr == NULL)
435                         *charptr = xstrdup(arg);
436                 break;
437
438         case oGlobalKnownHostsFile:
439                 charptr = &options->system_hostfile;
440                 goto parse_string;
441
442         case oUserKnownHostsFile:
443                 charptr = &options->user_hostfile;
444                 goto parse_string;
445
446         case oGlobalKnownHostsFile2:
447                 charptr = &options->system_hostfile2;
448                 goto parse_string;
449
450         case oUserKnownHostsFile2:
451                 charptr = &options->user_hostfile2;
452                 goto parse_string;
453
454         case oHostName:
455                 charptr = &options->hostname;
456                 goto parse_string;
457
458         case oHostKeyAlias:
459                 charptr = &options->host_key_alias;
460                 goto parse_string;
461
462         case oPreferredAuthentications:
463                 charptr = &options->preferred_authentications;
464                 goto parse_string;
465
466         case oBindAddress:
467                 charptr = &options->bind_address;
468                 goto parse_string;
469
470         case oProxyCommand:
471                 charptr = &options->proxy_command;
472                 string = xstrdup("");
473                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
474                         string = xrealloc(string, strlen(string) + strlen(arg) + 2);
475                         strcat(string, " ");
476                         strcat(string, arg);
477                 }
478                 if (*activep && *charptr == NULL)
479                         *charptr = string;
480                 else
481                         xfree(string);
482                 return 0;
483
484         case oPort:
485                 intptr = &options->port;
486 parse_int:
487                 arg = strdelim(&s);
488                 if (!arg || *arg == '\0')
489                         fatal("%.200s line %d: Missing argument.", filename, linenum);
490                 if (arg[0] < '0' || arg[0] > '9')
491                         fatal("%.200s line %d: Bad number.", filename, linenum);
492
493                 /* Octal, decimal, or hex format? */
494                 value = strtol(arg, &endofnumber, 0);
495                 if (arg == endofnumber)
496                         fatal("%.200s line %d: Bad number.", filename, linenum);
497                 if (*activep && *intptr == -1)
498                         *intptr = value;
499                 break;
500
501         case oConnectionAttempts:
502                 intptr = &options->connection_attempts;
503                 goto parse_int;
504
505         case oCipher:
506                 intptr = &options->cipher;
507                 arg = strdelim(&s);
508                 if (!arg || *arg == '\0')
509                         fatal("%.200s line %d: Missing argument.", filename, linenum);
510                 value = cipher_number(arg);
511                 if (value == -1)
512                         fatal("%.200s line %d: Bad cipher '%s'.",
513                               filename, linenum, arg ? arg : "<NONE>");
514                 if (*activep && *intptr == -1)
515                         *intptr = value;
516                 break;
517
518         case oCiphers:
519                 arg = strdelim(&s);
520                 if (!arg || *arg == '\0')
521                         fatal("%.200s line %d: Missing argument.", filename, linenum);
522                 if (!ciphers_valid(arg))
523                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
524                               filename, linenum, arg ? arg : "<NONE>");
525                 if (*activep && options->ciphers == NULL)
526                         options->ciphers = xstrdup(arg);
527                 break;
528
529         case oMacs:
530                 arg = strdelim(&s);
531                 if (!arg || *arg == '\0')
532                         fatal("%.200s line %d: Missing argument.", filename, linenum);
533                 if (!mac_valid(arg))
534                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
535                               filename, linenum, arg ? arg : "<NONE>");
536                 if (*activep && options->macs == NULL)
537                         options->macs = xstrdup(arg);
538                 break;
539
540         case oHostKeyAlgorithms:
541                 arg = strdelim(&s);
542                 if (!arg || *arg == '\0')
543                         fatal("%.200s line %d: Missing argument.", filename, linenum);
544                 if (!key_names_valid2(arg))
545                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
546                               filename, linenum, arg ? arg : "<NONE>");
547                 if (*activep && options->hostkeyalgorithms == NULL)
548                         options->hostkeyalgorithms = xstrdup(arg);
549                 break;
550
551         case oProtocol:
552                 intptr = &options->protocol;
553                 arg = strdelim(&s);
554                 if (!arg || *arg == '\0')
555                         fatal("%.200s line %d: Missing argument.", filename, linenum);
556                 value = proto_spec(arg);
557                 if (value == SSH_PROTO_UNKNOWN)
558                         fatal("%.200s line %d: Bad protocol spec '%s'.",
559                               filename, linenum, arg ? arg : "<NONE>");
560                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
561                         *intptr = value;
562                 break;
563
564         case oLogLevel:
565                 intptr = (int *) &options->log_level;
566                 arg = strdelim(&s);
567                 value = log_level_number(arg);
568                 if (value == (LogLevel) - 1)
569                         fatal("%.200s line %d: unsupported log level '%s'",
570                               filename, linenum, arg ? arg : "<NONE>");
571                 if (*activep && (LogLevel) * intptr == -1)
572                         *intptr = (LogLevel) value;
573                 break;
574
575         case oRemoteForward:
576                 arg = strdelim(&s);
577                 if (!arg || *arg == '\0')
578                         fatal("%.200s line %d: Missing argument.", filename, linenum);
579                 fwd_port = a2port(arg);
580                 if (fwd_port == 0)
581                         fatal("%.200s line %d: Badly formatted port number.",
582                               filename, linenum);
583                 arg = strdelim(&s);
584                 if (!arg || *arg == '\0')
585                         fatal("%.200s line %d: Missing second argument.",
586                               filename, linenum);
587                 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
588                         fatal("%.200s line %d: Badly formatted host:port.",
589                               filename, linenum);
590                 if (*activep)
591                         add_remote_forward(options, fwd_port, buf, fwd_host_port);
592                 break;
593
594         case oLocalForward:
595                 arg = strdelim(&s);
596                 if (!arg || *arg == '\0')
597                         fatal("%.200s line %d: Missing argument.", filename, linenum);
598                 fwd_port = a2port(arg);
599                 if (fwd_port == 0)
600                         fatal("%.200s line %d: Badly formatted port number.",
601                               filename, linenum);
602                 arg = strdelim(&s);
603                 if (!arg || *arg == '\0')
604                         fatal("%.200s line %d: Missing second argument.",
605                               filename, linenum);
606                 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
607                         fatal("%.200s line %d: Badly formatted host:port.",
608                               filename, linenum);
609                 if (*activep)
610                         add_local_forward(options, fwd_port, buf, fwd_host_port);
611                 break;
612
613         case oDynamicForward:
614                 arg = strdelim(&s);
615                 if (!arg || *arg == '\0')
616                         fatal("%.200s line %d: Missing port argument.",
617                             filename, linenum);
618                 fwd_port = a2port(arg);
619                 if (fwd_port == 0)
620                         fatal("%.200s line %d: Badly formatted port number.",
621                             filename, linenum);
622                 add_local_forward(options, fwd_port, "socks4", 0);
623                 break;
624
625         case oHost:
626                 *activep = 0;
627                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
628                         if (match_pattern(host, arg)) {
629                                 debug("Applying options for %.100s", arg);
630                                 *activep = 1;
631                                 break;
632                         }
633                 /* Avoid garbage check below, as strdelim is done. */
634                 return 0;
635
636         case oEscapeChar:
637                 intptr = &options->escape_char;
638                 arg = strdelim(&s);
639                 if (!arg || *arg == '\0')
640                         fatal("%.200s line %d: Missing argument.", filename, linenum);
641                 if (arg[0] == '^' && arg[2] == 0 &&
642                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
643                         value = (u_char) arg[1] & 31;
644                 else if (strlen(arg) == 1)
645                         value = (u_char) arg[0];
646                 else if (strcmp(arg, "none") == 0)
647                         value = SSH_ESCAPECHAR_NONE;
648                 else {
649                         fatal("%.200s line %d: Bad escape character.",
650                               filename, linenum);
651                         /* NOTREACHED */
652                         value = 0;      /* Avoid compiler warning. */
653                 }
654                 if (*activep && *intptr == -1)
655                         *intptr = value;
656                 break;
657
658         default:
659                 fatal("process_config_line: Unimplemented opcode %d", opcode);
660         }
661
662         /* Check that there is no garbage at end of line. */
663         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
664                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
665                       filename, linenum, arg);
666         }
667         return 0;
668 }
669
670
671 /*
672  * Reads the config file and modifies the options accordingly.  Options
673  * should already be initialized before this call.  This never returns if
674  * there is an error.  If the file does not exist, this returns immediately.
675  */
676
677 void
678 read_config_file(const char *filename, const char *host, Options *options)
679 {
680         FILE *f;
681         char line[1024];
682         int active, linenum;
683         int bad_options = 0;
684
685         /* Open the file. */
686         f = fopen(filename, "r");
687         if (!f)
688                 return;
689
690         debug("Reading configuration data %.200s", filename);
691
692         /*
693          * Mark that we are now processing the options.  This flag is turned
694          * on/off by Host specifications.
695          */
696         active = 1;
697         linenum = 0;
698         while (fgets(line, sizeof(line), f)) {
699                 /* Update line number counter. */
700                 linenum++;
701                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
702                         bad_options++;
703         }
704         fclose(f);
705         if (bad_options > 0)
706                 fatal("%s: terminating, %d bad configuration options",
707                       filename, bad_options);
708 }
709
710 /*
711  * Initializes options to special values that indicate that they have not yet
712  * been set.  Read_config_file will only set options with this value. Options
713  * are processed in the following order: command line, user config file,
714  * system config file.  Last, fill_default_options is called.
715  */
716
717 void
718 initialize_options(Options * options)
719 {
720         memset(options, 'X', sizeof(*options));
721         options->forward_agent = -1;
722         options->forward_x11 = -1;
723         options->xauth_location = NULL;
724         options->gateway_ports = -1;
725         options->use_privileged_port = -1;
726         options->rhosts_authentication = -1;
727         options->rsa_authentication = -1;
728         options->pubkey_authentication = -1;
729         options->challenge_response_authentication = -1;
730 #if defined(KRB4) || defined(KRB5)
731         options->kerberos_authentication = -1;
732 #endif
733 #if defined(AFS) || defined(KRB5)
734         options->kerberos_tgt_passing = -1;
735 #endif
736 #ifdef AFS
737         options->afs_token_passing = -1;
738 #endif
739         options->password_authentication = -1;
740         options->kbd_interactive_authentication = -1;
741         options->kbd_interactive_devices = NULL;
742         options->rhosts_rsa_authentication = -1;
743         options->hostbased_authentication = -1;
744         options->fallback_to_rsh = -1;
745         options->use_rsh = -1;
746         options->batch_mode = -1;
747         options->check_host_ip = -1;
748         options->strict_host_key_checking = -1;
749         options->compression = -1;
750         options->keepalives = -1;
751         options->compression_level = -1;
752         options->port = -1;
753         options->connection_attempts = -1;
754         options->number_of_password_prompts = -1;
755         options->cipher = -1;
756         options->ciphers = NULL;
757         options->macs = NULL;
758         options->hostkeyalgorithms = NULL;
759         options->protocol = SSH_PROTO_UNKNOWN;
760         options->num_identity_files = 0;
761         options->hostname = NULL;
762         options->host_key_alias = NULL;
763         options->proxy_command = NULL;
764         options->user = NULL;
765         options->escape_char = -1;
766         options->system_hostfile = NULL;
767         options->user_hostfile = NULL;
768         options->system_hostfile2 = NULL;
769         options->user_hostfile2 = NULL;
770         options->num_local_forwards = 0;
771         options->num_remote_forwards = 0;
772         options->log_level = (LogLevel) - 1;
773         options->preferred_authentications = NULL;
774         options->bind_address = NULL;
775 }
776
777 /*
778  * Called after processing other sources of option data, this fills those
779  * options for which no value has been specified with their default values.
780  */
781
782 void
783 fill_default_options(Options * options)
784 {
785         int len;
786
787         if (options->forward_agent == -1)
788                 options->forward_agent = 0;
789         if (options->forward_x11 == -1)
790                 options->forward_x11 = 0;
791 #ifdef _PATH_XAUTH
792         if (options->xauth_location == NULL)
793                 options->xauth_location = _PATH_XAUTH;
794 #endif
795         if (options->gateway_ports == -1)
796                 options->gateway_ports = 0;
797         if (options->use_privileged_port == -1)
798                 options->use_privileged_port = 0;
799         if (options->rhosts_authentication == -1)
800                 options->rhosts_authentication = 1;
801         if (options->rsa_authentication == -1)
802                 options->rsa_authentication = 1;
803         if (options->pubkey_authentication == -1)
804                 options->pubkey_authentication = 1;
805         if (options->challenge_response_authentication == -1)
806                 options->challenge_response_authentication = 0;
807 #if defined(KRB4) || defined(KRB5)
808         if (options->kerberos_authentication == -1)
809                 options->kerberos_authentication = 1;
810 #endif
811 #if defined(AFS) || defined(KRB5)
812         if (options->kerberos_tgt_passing == -1)
813                 options->kerberos_tgt_passing = 1;
814 #endif
815 #ifdef AFS
816         if (options->afs_token_passing == -1)
817                 options->afs_token_passing = 1;
818 #endif
819         if (options->password_authentication == -1)
820                 options->password_authentication = 1;
821         if (options->kbd_interactive_authentication == -1)
822                 options->kbd_interactive_authentication = 1;
823         if (options->rhosts_rsa_authentication == -1)
824                 options->rhosts_rsa_authentication = 1;
825         if (options->hostbased_authentication == -1)
826                 options->hostbased_authentication = 0;
827         if (options->fallback_to_rsh == -1)
828                 options->fallback_to_rsh = 0;
829         if (options->use_rsh == -1)
830                 options->use_rsh = 0;
831         if (options->batch_mode == -1)
832                 options->batch_mode = 0;
833         if (options->check_host_ip == -1)
834                 options->check_host_ip = 1;
835         if (options->strict_host_key_checking == -1)
836                 options->strict_host_key_checking = 2;  /* 2 is default */
837         if (options->compression == -1)
838                 options->compression = 0;
839         if (options->keepalives == -1)
840                 options->keepalives = 1;
841         if (options->compression_level == -1)
842                 options->compression_level = 6;
843         if (options->port == -1)
844                 options->port = 0;      /* Filled in ssh_connect. */
845         if (options->connection_attempts == -1)
846                 options->connection_attempts = 4;
847         if (options->number_of_password_prompts == -1)
848                 options->number_of_password_prompts = 3;
849         /* Selected in ssh_login(). */
850         if (options->cipher == -1)
851                 options->cipher = SSH_CIPHER_NOT_SET;
852         /* options->ciphers, default set in myproposals.h */
853         /* options->macs, default set in myproposals.h */
854         /* options->hostkeyalgorithms, default set in myproposals.h */
855         if (options->protocol == SSH_PROTO_UNKNOWN)
856                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
857         if (options->num_identity_files == 0) {
858                 if (options->protocol & SSH_PROTO_1) {
859                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
860                         options->identity_files[options->num_identity_files] =
861                             xmalloc(len);
862                         snprintf(options->identity_files[options->num_identity_files++],
863                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
864                 }
865                 if (options->protocol & SSH_PROTO_2) {
866                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
867                         options->identity_files[options->num_identity_files] =
868                             xmalloc(len);
869                         snprintf(options->identity_files[options->num_identity_files++],
870                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
871
872                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
873                         options->identity_files[options->num_identity_files] =
874                             xmalloc(len);
875                         snprintf(options->identity_files[options->num_identity_files++],
876                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
877                 }
878         }
879         if (options->escape_char == -1)
880                 options->escape_char = '~';
881         if (options->system_hostfile == NULL)
882                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
883         if (options->user_hostfile == NULL)
884                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
885         if (options->system_hostfile2 == NULL)
886                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
887         if (options->user_hostfile2 == NULL)
888                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
889         if (options->log_level == (LogLevel) - 1)
890                 options->log_level = SYSLOG_LEVEL_INFO;
891         /* options->proxy_command should not be set by default */
892         /* options->user will be set in the main program if appropriate */
893         /* options->hostname will be set in the main program if appropriate */
894         /* options->host_key_alias should not be set by default */
895         /* options->preferred_authentications will be set in ssh */
896 }
This page took 0.358576 seconds and 5 git commands to generate.