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