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