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