]> andersk Git - openssh.git/blob - readconf.c
- (bal) Fixed stray code in readconf.c that went in by mistake.
[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.86 2001/08/01 22:03:33 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 #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
264         s = line;
265         /* Get the keyword. (Each line is supposed to begin with a keyword). */
266         keyword = strdelim(&s);
267         /* Ignore leading whitespace. */
268         if (*keyword == '\0')
269                 keyword = strdelim(&s);
270         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
271                 return 0;
272
273         opcode = parse_token(keyword, filename, linenum);
274
275         switch (opcode) {
276         case oBadOption:
277                 /* don't panic, but count bad options */
278                 return -1;
279                 /* NOTREACHED */
280         case oForwardAgent:
281                 intptr = &options->forward_agent;
282 parse_flag:
283                 arg = strdelim(&s);
284                 if (!arg || *arg == '\0')
285                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
286                 value = 0;      /* To avoid compiler warning... */
287                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
288                         value = 1;
289                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
290                         value = 0;
291                 else
292                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
293                 if (*activep && *intptr == -1)
294                         *intptr = value;
295                 break;
296
297         case oForwardX11:
298                 intptr = &options->forward_x11;
299                 goto parse_flag;
300
301         case oGatewayPorts:
302                 intptr = &options->gateway_ports;
303                 goto parse_flag;
304
305         case oUsePrivilegedPort:
306                 intptr = &options->use_privileged_port;
307                 goto parse_flag;
308
309         case oRhostsAuthentication:
310                 intptr = &options->rhosts_authentication;
311                 goto parse_flag;
312
313         case oPasswordAuthentication:
314                 intptr = &options->password_authentication;
315                 goto parse_flag;
316
317         case oKbdInteractiveAuthentication:
318                 intptr = &options->kbd_interactive_authentication;
319                 goto parse_flag;
320
321         case oKbdInteractiveDevices:
322                 charptr = &options->kbd_interactive_devices;
323                 goto parse_string;
324
325         case oPubkeyAuthentication:
326                 intptr = &options->pubkey_authentication;
327                 goto parse_flag;
328
329         case oRSAAuthentication:
330                 intptr = &options->rsa_authentication;
331                 goto parse_flag;
332
333         case oRhostsRSAAuthentication:
334                 intptr = &options->rhosts_rsa_authentication;
335                 goto parse_flag;
336
337         case oHostbasedAuthentication:
338                 intptr = &options->hostbased_authentication;
339                 goto parse_flag;
340
341         case oChallengeResponseAuthentication:
342                 intptr = &options->challenge_response_authentication;
343                 goto parse_flag;
344 #if defined(KRB4) || defined(KRB5)
345         case oKerberosAuthentication:
346                 intptr = &options->kerberos_authentication;
347                 goto parse_flag;
348 #endif
349 #if defined(AFS) || defined(KRB5)
350         case oKerberosTgtPassing:
351                 intptr = &options->kerberos_tgt_passing;
352                 goto parse_flag;
353 #endif
354 #ifdef AFS
355         case oAFSTokenPassing:
356                 intptr = &options->afs_token_passing;
357                 goto parse_flag;
358 #endif
359         case oFallBackToRsh:
360                 intptr = &options->fallback_to_rsh;
361                 goto parse_flag;
362
363         case oUseRsh:
364                 intptr = &options->use_rsh;
365                 goto parse_flag;
366
367         case oBatchMode:
368                 intptr = &options->batch_mode;
369                 goto parse_flag;
370
371         case oCheckHostIP:
372                 intptr = &options->check_host_ip;
373                 goto parse_flag;
374
375         case oStrictHostKeyChecking:
376                 intptr = &options->strict_host_key_checking;
377                 arg = strdelim(&s);
378                 if (!arg || *arg == '\0')
379                         fatal("%.200s line %d: Missing yes/no/ask argument.",
380                               filename, linenum);
381                 value = 0;      /* To avoid compiler warning... */
382                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
383                         value = 1;
384                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
385                         value = 0;
386                 else if (strcmp(arg, "ask") == 0)
387                         value = 2;
388                 else
389                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
390                 if (*activep && *intptr == -1)
391                         *intptr = value;
392                 break;
393
394         case oCompression:
395                 intptr = &options->compression;
396                 goto parse_flag;
397
398         case oKeepAlives:
399                 intptr = &options->keepalives;
400                 goto parse_flag;
401
402         case oNumberOfPasswordPrompts:
403                 intptr = &options->number_of_password_prompts;
404                 goto parse_int;
405
406         case oCompressionLevel:
407                 intptr = &options->compression_level;
408                 goto parse_int;
409
410         case oIdentityFile:
411                 arg = strdelim(&s);
412                 if (!arg || *arg == '\0')
413                         fatal("%.200s line %d: Missing argument.", filename, linenum);
414                 if (*activep) {
415                         intptr = &options->num_identity_files;
416                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
417                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
418                                       filename, linenum, SSH_MAX_IDENTITY_FILES);
419                         charptr =  &options->identity_files[*intptr];
420                         *charptr = xstrdup(arg);
421                         *intptr = *intptr + 1;
422                 }
423                 break;
424
425         case oXAuthLocation:
426                 charptr=&options->xauth_location;
427                 goto parse_string;
428
429         case oUser:
430                 charptr = &options->user;
431 parse_string:
432                 arg = strdelim(&s);
433                 if (!arg || *arg == '\0')
434                         fatal("%.200s line %d: Missing argument.", filename, linenum);
435                 if (*activep && *charptr == NULL)
436                         *charptr = xstrdup(arg);
437                 break;
438
439         case oGlobalKnownHostsFile:
440                 charptr = &options->system_hostfile;
441                 goto parse_string;
442
443         case oUserKnownHostsFile:
444                 charptr = &options->user_hostfile;
445                 goto parse_string;
446
447         case oGlobalKnownHostsFile2:
448                 charptr = &options->system_hostfile2;
449                 goto parse_string;
450
451         case oUserKnownHostsFile2:
452                 charptr = &options->user_hostfile2;
453                 goto parse_string;
454
455         case oHostName:
456                 charptr = &options->hostname;
457                 goto parse_string;
458
459         case oHostKeyAlias:
460                 charptr = &options->host_key_alias;
461                 goto parse_string;
462
463         case oPreferredAuthentications:
464                 charptr = &options->preferred_authentications;
465                 goto parse_string;
466
467         case oBindAddress:
468                 charptr = &options->bind_address;
469                 goto parse_string;
470
471         case oSmartcardDevice:
472                 charptr = &options->smartcard_device;
473                 goto parse_string;
474
475         case oProxyCommand:
476                 charptr = &options->proxy_command;
477                 string = xstrdup("");
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 = NULL;
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.505984 seconds and 5 git commands to generate.