]> andersk Git - openssh.git/blob - readconf.c
- jakob@cvs.openbsd.org 2001/07/31 09:28:44
[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.85 2001/07/31 09:28:44 jakob 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 = NULL, **charptr, *endofnumber, *keyword, 
261             *arg;
262         int opcode, *intptr, value;
263         u_short fwd_port, fwd_host_port;
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                 intptr = &options->smartcard_device;
474                 goto parse_int;
475
476         case oProxyCommand:
477                 charptr = &options->proxy_command;
478                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
479                         string = xrealloc(string, strlen(string) + strlen(arg) + 2);
480                         strcat(string, " ");
481                         strcat(string, arg);
482                 }
483                 if (*activep && *charptr == NULL)
484                         *charptr = string;
485                 else
486                         xfree(string);
487                 return 0;
488
489         case oPort:
490                 intptr = &options->port;
491 parse_int:
492                 arg = strdelim(&s);
493                 if (!arg || *arg == '\0')
494                         fatal("%.200s line %d: Missing argument.", filename, linenum);
495                 if (arg[0] < '0' || arg[0] > '9')
496                         fatal("%.200s line %d: Bad number.", filename, linenum);
497
498                 /* Octal, decimal, or hex format? */
499                 value = strtol(arg, &endofnumber, 0);
500                 if (arg == endofnumber)
501                         fatal("%.200s line %d: Bad number.", filename, linenum);
502                 if (*activep && *intptr == -1)
503                         *intptr = value;
504                 break;
505
506         case oConnectionAttempts:
507                 intptr = &options->connection_attempts;
508                 goto parse_int;
509
510         case oCipher:
511                 intptr = &options->cipher;
512                 arg = strdelim(&s);
513                 if (!arg || *arg == '\0')
514                         fatal("%.200s line %d: Missing argument.", filename, linenum);
515                 value = cipher_number(arg);
516                 if (value == -1)
517                         fatal("%.200s line %d: Bad cipher '%s'.",
518                               filename, linenum, arg ? arg : "<NONE>");
519                 if (*activep && *intptr == -1)
520                         *intptr = value;
521                 break;
522
523         case oCiphers:
524                 arg = strdelim(&s);
525                 if (!arg || *arg == '\0')
526                         fatal("%.200s line %d: Missing argument.", filename, linenum);
527                 if (!ciphers_valid(arg))
528                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
529                               filename, linenum, arg ? arg : "<NONE>");
530                 if (*activep && options->ciphers == NULL)
531                         options->ciphers = xstrdup(arg);
532                 break;
533
534         case oMacs:
535                 arg = strdelim(&s);
536                 if (!arg || *arg == '\0')
537                         fatal("%.200s line %d: Missing argument.", filename, linenum);
538                 if (!mac_valid(arg))
539                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
540                               filename, linenum, arg ? arg : "<NONE>");
541                 if (*activep && options->macs == NULL)
542                         options->macs = xstrdup(arg);
543                 break;
544
545         case oHostKeyAlgorithms:
546                 arg = strdelim(&s);
547                 if (!arg || *arg == '\0')
548                         fatal("%.200s line %d: Missing argument.", filename, linenum);
549                 if (!key_names_valid2(arg))
550                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
551                               filename, linenum, arg ? arg : "<NONE>");
552                 if (*activep && options->hostkeyalgorithms == NULL)
553                         options->hostkeyalgorithms = xstrdup(arg);
554                 break;
555
556         case oProtocol:
557                 intptr = &options->protocol;
558                 arg = strdelim(&s);
559                 if (!arg || *arg == '\0')
560                         fatal("%.200s line %d: Missing argument.", filename, linenum);
561                 value = proto_spec(arg);
562                 if (value == SSH_PROTO_UNKNOWN)
563                         fatal("%.200s line %d: Bad protocol spec '%s'.",
564                               filename, linenum, arg ? arg : "<NONE>");
565                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
566                         *intptr = value;
567                 break;
568
569         case oLogLevel:
570                 intptr = (int *) &options->log_level;
571                 arg = strdelim(&s);
572                 value = log_level_number(arg);
573                 if (value == (LogLevel) - 1)
574                         fatal("%.200s line %d: unsupported log level '%s'",
575                               filename, linenum, arg ? arg : "<NONE>");
576                 if (*activep && (LogLevel) * intptr == -1)
577                         *intptr = (LogLevel) value;
578                 break;
579
580         case oRemoteForward:
581                 arg = strdelim(&s);
582                 if (!arg || *arg == '\0')
583                         fatal("%.200s line %d: Missing argument.", filename, linenum);
584                 fwd_port = a2port(arg);
585                 if (fwd_port == 0)
586                         fatal("%.200s line %d: Badly formatted port number.",
587                               filename, linenum);
588                 arg = strdelim(&s);
589                 if (!arg || *arg == '\0')
590                         fatal("%.200s line %d: Missing second argument.",
591                               filename, linenum);
592                 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
593                         fatal("%.200s line %d: Badly formatted host:port.",
594                               filename, linenum);
595                 if (*activep)
596                         add_remote_forward(options, fwd_port, buf, fwd_host_port);
597                 break;
598
599         case oLocalForward:
600                 arg = strdelim(&s);
601                 if (!arg || *arg == '\0')
602                         fatal("%.200s line %d: Missing argument.", filename, linenum);
603                 fwd_port = a2port(arg);
604                 if (fwd_port == 0)
605                         fatal("%.200s line %d: Badly formatted port number.",
606                               filename, linenum);
607                 arg = strdelim(&s);
608                 if (!arg || *arg == '\0')
609                         fatal("%.200s line %d: Missing second argument.",
610                               filename, linenum);
611                 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
612                         fatal("%.200s line %d: Badly formatted host:port.",
613                               filename, linenum);
614                 if (*activep)
615                         add_local_forward(options, fwd_port, buf, fwd_host_port);
616                 break;
617
618         case oDynamicForward:
619                 arg = strdelim(&s);
620                 if (!arg || *arg == '\0')
621                         fatal("%.200s line %d: Missing port argument.",
622                             filename, linenum);
623                 fwd_port = a2port(arg);
624                 if (fwd_port == 0)
625                         fatal("%.200s line %d: Badly formatted port number.",
626                             filename, linenum);
627                 add_local_forward(options, fwd_port, "socks4", 0);
628                 break;
629
630         case oHost:
631                 *activep = 0;
632                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
633                         if (match_pattern(host, arg)) {
634                                 debug("Applying options for %.100s", arg);
635                                 *activep = 1;
636                                 break;
637                         }
638                 /* Avoid garbage check below, as strdelim is done. */
639                 return 0;
640
641         case oEscapeChar:
642                 intptr = &options->escape_char;
643                 arg = strdelim(&s);
644                 if (!arg || *arg == '\0')
645                         fatal("%.200s line %d: Missing argument.", filename, linenum);
646                 if (arg[0] == '^' && arg[2] == 0 &&
647                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
648                         value = (u_char) arg[1] & 31;
649                 else if (strlen(arg) == 1)
650                         value = (u_char) arg[0];
651                 else if (strcmp(arg, "none") == 0)
652                         value = SSH_ESCAPECHAR_NONE;
653                 else {
654                         fatal("%.200s line %d: Bad escape character.",
655                               filename, linenum);
656                         /* NOTREACHED */
657                         value = 0;      /* Avoid compiler warning. */
658                 }
659                 if (*activep && *intptr == -1)
660                         *intptr = value;
661                 break;
662
663         default:
664                 fatal("process_config_line: Unimplemented opcode %d", opcode);
665         }
666
667         /* Check that there is no garbage at end of line. */
668         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
669                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
670                       filename, linenum, arg);
671         }
672         return 0;
673 }
674
675
676 /*
677  * Reads the config file and modifies the options accordingly.  Options
678  * should already be initialized before this call.  This never returns if
679  * there is an error.  If the file does not exist, this returns immediately.
680  */
681
682 void
683 read_config_file(const char *filename, const char *host, Options *options)
684 {
685         FILE *f;
686         char line[1024];
687         int active, linenum;
688         int bad_options = 0;
689
690         /* Open the file. */
691         f = fopen(filename, "r");
692         if (!f)
693                 return;
694
695         debug("Reading configuration data %.200s", filename);
696
697         /*
698          * Mark that we are now processing the options.  This flag is turned
699          * on/off by Host specifications.
700          */
701         active = 1;
702         linenum = 0;
703         while (fgets(line, sizeof(line), f)) {
704                 /* Update line number counter. */
705                 linenum++;
706                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
707                         bad_options++;
708         }
709         fclose(f);
710         if (bad_options > 0)
711                 fatal("%s: terminating, %d bad configuration options",
712                       filename, bad_options);
713 }
714
715 /*
716  * Initializes options to special values that indicate that they have not yet
717  * been set.  Read_config_file will only set options with this value. Options
718  * are processed in the following order: command line, user config file,
719  * system config file.  Last, fill_default_options is called.
720  */
721
722 void
723 initialize_options(Options * options)
724 {
725         memset(options, 'X', sizeof(*options));
726         options->forward_agent = -1;
727         options->forward_x11 = -1;
728         options->xauth_location = NULL;
729         options->gateway_ports = -1;
730         options->use_privileged_port = -1;
731         options->rhosts_authentication = -1;
732         options->rsa_authentication = -1;
733         options->pubkey_authentication = -1;
734         options->challenge_response_authentication = -1;
735 #if defined(KRB4) || defined(KRB5)
736         options->kerberos_authentication = -1;
737 #endif
738 #if defined(AFS) || defined(KRB5)
739         options->kerberos_tgt_passing = -1;
740 #endif
741 #ifdef AFS
742         options->afs_token_passing = -1;
743 #endif
744         options->password_authentication = -1;
745         options->kbd_interactive_authentication = -1;
746         options->kbd_interactive_devices = NULL;
747         options->rhosts_rsa_authentication = -1;
748         options->hostbased_authentication = -1;
749         options->fallback_to_rsh = -1;
750         options->use_rsh = -1;
751         options->batch_mode = -1;
752         options->check_host_ip = -1;
753         options->strict_host_key_checking = -1;
754         options->compression = -1;
755         options->keepalives = -1;
756         options->compression_level = -1;
757         options->port = -1;
758         options->connection_attempts = -1;
759         options->number_of_password_prompts = -1;
760         options->cipher = -1;
761         options->ciphers = NULL;
762         options->macs = NULL;
763         options->hostkeyalgorithms = NULL;
764         options->protocol = SSH_PROTO_UNKNOWN;
765         options->num_identity_files = 0;
766         options->hostname = NULL;
767         options->host_key_alias = NULL;
768         options->proxy_command = NULL;
769         options->user = NULL;
770         options->escape_char = -1;
771         options->system_hostfile = NULL;
772         options->user_hostfile = NULL;
773         options->system_hostfile2 = NULL;
774         options->user_hostfile2 = NULL;
775         options->num_local_forwards = 0;
776         options->num_remote_forwards = 0;
777         options->log_level = (LogLevel) - 1;
778         options->preferred_authentications = NULL;
779         options->bind_address = NULL;
780         options->smartcard_device = -1;
781 }
782
783 /*
784  * Called after processing other sources of option data, this fills those
785  * options for which no value has been specified with their default values.
786  */
787
788 void
789 fill_default_options(Options * options)
790 {
791         int len;
792
793         if (options->forward_agent == -1)
794                 options->forward_agent = 0;
795         if (options->forward_x11 == -1)
796                 options->forward_x11 = 0;
797 #ifdef _PATH_XAUTH
798         if (options->xauth_location == NULL)
799                 options->xauth_location = _PATH_XAUTH;
800 #endif
801         if (options->gateway_ports == -1)
802                 options->gateway_ports = 0;
803         if (options->use_privileged_port == -1)
804                 options->use_privileged_port = 0;
805         if (options->rhosts_authentication == -1)
806                 options->rhosts_authentication = 1;
807         if (options->rsa_authentication == -1)
808                 options->rsa_authentication = 1;
809         if (options->pubkey_authentication == -1)
810                 options->pubkey_authentication = 1;
811         if (options->challenge_response_authentication == -1)
812                 options->challenge_response_authentication = 1;
813 #if defined(KRB4) || defined(KRB5)
814         if (options->kerberos_authentication == -1)
815                 options->kerberos_authentication = 1;
816 #endif
817 #if defined(AFS) || defined(KRB5)
818         if (options->kerberos_tgt_passing == -1)
819                 options->kerberos_tgt_passing = 1;
820 #endif
821 #ifdef AFS
822         if (options->afs_token_passing == -1)
823                 options->afs_token_passing = 1;
824 #endif
825         if (options->password_authentication == -1)
826                 options->password_authentication = 1;
827         if (options->kbd_interactive_authentication == -1)
828                 options->kbd_interactive_authentication = 1;
829         if (options->rhosts_rsa_authentication == -1)
830                 options->rhosts_rsa_authentication = 1;
831         if (options->hostbased_authentication == -1)
832                 options->hostbased_authentication = 0;
833         if (options->fallback_to_rsh == -1)
834                 options->fallback_to_rsh = 0;
835         if (options->use_rsh == -1)
836                 options->use_rsh = 0;
837         if (options->batch_mode == -1)
838                 options->batch_mode = 0;
839         if (options->check_host_ip == -1)
840                 options->check_host_ip = 1;
841         if (options->strict_host_key_checking == -1)
842                 options->strict_host_key_checking = 2;  /* 2 is default */
843         if (options->compression == -1)
844                 options->compression = 0;
845         if (options->keepalives == -1)
846                 options->keepalives = 1;
847         if (options->compression_level == -1)
848                 options->compression_level = 6;
849         if (options->port == -1)
850                 options->port = 0;      /* Filled in ssh_connect. */
851         if (options->connection_attempts == -1)
852                 options->connection_attempts = 1;
853         if (options->number_of_password_prompts == -1)
854                 options->number_of_password_prompts = 3;
855         /* Selected in ssh_login(). */
856         if (options->cipher == -1)
857                 options->cipher = SSH_CIPHER_NOT_SET;
858         /* options->ciphers, default set in myproposals.h */
859         /* options->macs, default set in myproposals.h */
860         /* options->hostkeyalgorithms, default set in myproposals.h */
861         if (options->protocol == SSH_PROTO_UNKNOWN)
862                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
863         if (options->num_identity_files == 0) {
864                 if (options->protocol & SSH_PROTO_1) {
865                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
866                         options->identity_files[options->num_identity_files] =
867                             xmalloc(len);
868                         snprintf(options->identity_files[options->num_identity_files++],
869                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
870                 }
871                 if (options->protocol & SSH_PROTO_2) {
872                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
873                         options->identity_files[options->num_identity_files] =
874                             xmalloc(len);
875                         snprintf(options->identity_files[options->num_identity_files++],
876                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
877
878                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
879                         options->identity_files[options->num_identity_files] =
880                             xmalloc(len);
881                         snprintf(options->identity_files[options->num_identity_files++],
882                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
883                 }
884         }
885         if (options->escape_char == -1)
886                 options->escape_char = '~';
887         if (options->system_hostfile == NULL)
888                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
889         if (options->user_hostfile == NULL)
890                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
891         if (options->system_hostfile2 == NULL)
892                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
893         if (options->user_hostfile2 == NULL)
894                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
895         if (options->log_level == (LogLevel) - 1)
896                 options->log_level = SYSLOG_LEVEL_INFO;
897         /* options->proxy_command should not be set by default */
898         /* options->user will be set in the main program if appropriate */
899         /* options->hostname will be set in the main program if appropriate */
900         /* options->host_key_alias should not be set by default */
901         /* options->preferred_authentications will be set in ssh */
902 }
This page took 0.210284 seconds and 5 git commands to generate.