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