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