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