]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
Import of OpenSSH 3.5p1
[gssapi-openssh.git] / openssh / 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.100 2002/06/19 00:27:55 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      User foo
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      PublicKeyAuthentication no
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      StrictHostKeyChecking yes
83      KeepAlives no
84      IdentityFile ~/.ssh/identity
85      Port 22
86      EscapeChar ~
87
88 */
89
90 /* Keyword tokens. */
91
92 typedef enum {
93         oBadOption,
94         oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
95         oPasswordAuthentication, oRSAAuthentication,
96         oChallengeResponseAuthentication, oXAuthLocation,
97 #if defined(KRB4) || defined(KRB5)
98         oKerberosAuthentication,
99 #endif
100 #if defined(AFS) || defined(KRB5)
101         oKerberosTgtPassing,
102 #endif
103 #ifdef AFS
104         oAFSTokenPassing,
105 #endif
106         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
107         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
108         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
109         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
110         oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
111         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
112         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
113         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
114         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
115         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
116         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
117         oDeprecated
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", oDeprecated },
153         { "usersh", oDeprecated },
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         { "clearallforwardings", oClearAllForwardings },
188         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
189         { NULL, oBadOption }
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 NO_IPPORT_RESERVED_CONCEPT
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 oBatchMode:
376                 intptr = &options->batch_mode;
377                 goto parse_flag;
378
379         case oCheckHostIP:
380                 intptr = &options->check_host_ip;
381                 goto parse_flag;
382
383         case oStrictHostKeyChecking:
384                 intptr = &options->strict_host_key_checking;
385                 arg = strdelim(&s);
386                 if (!arg || *arg == '\0')
387                         fatal("%.200s line %d: Missing yes/no/ask argument.",
388                             filename, linenum);
389                 value = 0;      /* To avoid compiler warning... */
390                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
391                         value = 1;
392                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
393                         value = 0;
394                 else if (strcmp(arg, "ask") == 0)
395                         value = 2;
396                 else
397                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
398                 if (*activep && *intptr == -1)
399                         *intptr = value;
400                 break;
401
402         case oCompression:
403                 intptr = &options->compression;
404                 goto parse_flag;
405
406         case oKeepAlives:
407                 intptr = &options->keepalives;
408                 goto parse_flag;
409
410         case oNoHostAuthenticationForLocalhost:
411                 intptr = &options->no_host_authentication_for_localhost;
412                 goto parse_flag;
413
414         case oNumberOfPasswordPrompts:
415                 intptr = &options->number_of_password_prompts;
416                 goto parse_int;
417
418         case oCompressionLevel:
419                 intptr = &options->compression_level;
420                 goto parse_int;
421
422         case oIdentityFile:
423                 arg = strdelim(&s);
424                 if (!arg || *arg == '\0')
425                         fatal("%.200s line %d: Missing argument.", filename, linenum);
426                 if (*activep) {
427                         intptr = &options->num_identity_files;
428                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
429                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
430                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
431                         charptr =  &options->identity_files[*intptr];
432                         *charptr = xstrdup(arg);
433                         *intptr = *intptr + 1;
434                 }
435                 break;
436
437         case oXAuthLocation:
438                 charptr=&options->xauth_location;
439                 goto parse_string;
440
441         case oUser:
442                 charptr = &options->user;
443 parse_string:
444                 arg = strdelim(&s);
445                 if (!arg || *arg == '\0')
446                         fatal("%.200s line %d: Missing argument.", filename, linenum);
447                 if (*activep && *charptr == NULL)
448                         *charptr = xstrdup(arg);
449                 break;
450
451         case oGlobalKnownHostsFile:
452                 charptr = &options->system_hostfile;
453                 goto parse_string;
454
455         case oUserKnownHostsFile:
456                 charptr = &options->user_hostfile;
457                 goto parse_string;
458
459         case oGlobalKnownHostsFile2:
460                 charptr = &options->system_hostfile2;
461                 goto parse_string;
462
463         case oUserKnownHostsFile2:
464                 charptr = &options->user_hostfile2;
465                 goto parse_string;
466
467         case oHostName:
468                 charptr = &options->hostname;
469                 goto parse_string;
470
471         case oHostKeyAlias:
472                 charptr = &options->host_key_alias;
473                 goto parse_string;
474
475         case oPreferredAuthentications:
476                 charptr = &options->preferred_authentications;
477                 goto parse_string;
478
479         case oBindAddress:
480                 charptr = &options->bind_address;
481                 goto parse_string;
482
483         case oSmartcardDevice:
484                 charptr = &options->smartcard_device;
485                 goto parse_string;
486
487         case oProxyCommand:
488                 charptr = &options->proxy_command;
489                 string = xstrdup("");
490                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
491                         string = xrealloc(string, strlen(string) + strlen(arg) + 2);
492                         strcat(string, " ");
493                         strcat(string, arg);
494                 }
495                 if (*activep && *charptr == NULL)
496                         *charptr = string;
497                 else
498                         xfree(string);
499                 return 0;
500
501         case oPort:
502                 intptr = &options->port;
503 parse_int:
504                 arg = strdelim(&s);
505                 if (!arg || *arg == '\0')
506                         fatal("%.200s line %d: Missing argument.", filename, linenum);
507                 if (arg[0] < '0' || arg[0] > '9')
508                         fatal("%.200s line %d: Bad number.", filename, linenum);
509
510                 /* Octal, decimal, or hex format? */
511                 value = strtol(arg, &endofnumber, 0);
512                 if (arg == endofnumber)
513                         fatal("%.200s line %d: Bad number.", filename, linenum);
514                 if (*activep && *intptr == -1)
515                         *intptr = value;
516                 break;
517
518         case oConnectionAttempts:
519                 intptr = &options->connection_attempts;
520                 goto parse_int;
521
522         case oCipher:
523                 intptr = &options->cipher;
524                 arg = strdelim(&s);
525                 if (!arg || *arg == '\0')
526                         fatal("%.200s line %d: Missing argument.", filename, linenum);
527                 value = cipher_number(arg);
528                 if (value == -1)
529                         fatal("%.200s line %d: Bad cipher '%s'.",
530                             filename, linenum, arg ? arg : "<NONE>");
531                 if (*activep && *intptr == -1)
532                         *intptr = value;
533                 break;
534
535         case oCiphers:
536                 arg = strdelim(&s);
537                 if (!arg || *arg == '\0')
538                         fatal("%.200s line %d: Missing argument.", filename, linenum);
539                 if (!ciphers_valid(arg))
540                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
541                             filename, linenum, arg ? arg : "<NONE>");
542                 if (*activep && options->ciphers == NULL)
543                         options->ciphers = xstrdup(arg);
544                 break;
545
546         case oMacs:
547                 arg = strdelim(&s);
548                 if (!arg || *arg == '\0')
549                         fatal("%.200s line %d: Missing argument.", filename, linenum);
550                 if (!mac_valid(arg))
551                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
552                             filename, linenum, arg ? arg : "<NONE>");
553                 if (*activep && options->macs == NULL)
554                         options->macs = xstrdup(arg);
555                 break;
556
557         case oHostKeyAlgorithms:
558                 arg = strdelim(&s);
559                 if (!arg || *arg == '\0')
560                         fatal("%.200s line %d: Missing argument.", filename, linenum);
561                 if (!key_names_valid2(arg))
562                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
563                             filename, linenum, arg ? arg : "<NONE>");
564                 if (*activep && options->hostkeyalgorithms == NULL)
565                         options->hostkeyalgorithms = xstrdup(arg);
566                 break;
567
568         case oProtocol:
569                 intptr = &options->protocol;
570                 arg = strdelim(&s);
571                 if (!arg || *arg == '\0')
572                         fatal("%.200s line %d: Missing argument.", filename, linenum);
573                 value = proto_spec(arg);
574                 if (value == SSH_PROTO_UNKNOWN)
575                         fatal("%.200s line %d: Bad protocol spec '%s'.",
576                             filename, linenum, arg ? arg : "<NONE>");
577                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
578                         *intptr = value;
579                 break;
580
581         case oLogLevel:
582                 intptr = (int *) &options->log_level;
583                 arg = strdelim(&s);
584                 value = log_level_number(arg);
585                 if (value == SYSLOG_LEVEL_NOT_SET)
586                         fatal("%.200s line %d: unsupported log level '%s'",
587                             filename, linenum, arg ? arg : "<NONE>");
588                 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
589                         *intptr = (LogLevel) value;
590                 break;
591
592         case oLocalForward:
593         case oRemoteForward:
594                 arg = strdelim(&s);
595                 if (!arg || *arg == '\0')
596                         fatal("%.200s line %d: Missing port argument.",
597                             filename, linenum);
598                 if ((fwd_port = a2port(arg)) == 0)
599                         fatal("%.200s line %d: Bad listen port.",
600                             filename, linenum);
601                 arg = strdelim(&s);
602                 if (!arg || *arg == '\0')
603                         fatal("%.200s line %d: Missing second argument.",
604                             filename, linenum);
605                 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
606                     sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
607                         fatal("%.200s line %d: Bad forwarding specification.",
608                             filename, linenum);
609                 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
610                         fatal("%.200s line %d: Bad forwarding port.",
611                             filename, linenum);
612                 if (*activep) {
613                         if (opcode == oLocalForward)
614                                 add_local_forward(options, fwd_port, buf,
615                                     fwd_host_port);
616                         else if (opcode == oRemoteForward)
617                                 add_remote_forward(options, fwd_port, buf,
618                                     fwd_host_port);
619                 }
620                 break;
621
622         case oDynamicForward:
623                 arg = strdelim(&s);
624                 if (!arg || *arg == '\0')
625                         fatal("%.200s line %d: Missing port argument.",
626                             filename, linenum);
627                 fwd_port = a2port(arg);
628                 if (fwd_port == 0)
629                         fatal("%.200s line %d: Badly formatted port number.",
630                             filename, linenum);
631                 if (*activep)
632                         add_local_forward(options, fwd_port, "socks4", 0);
633                 break;
634
635         case oClearAllForwardings:
636                 intptr = &options->clear_forwardings;
637                 goto parse_flag;
638
639         case oHost:
640                 *activep = 0;
641                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
642                         if (match_pattern(host, arg)) {
643                                 debug("Applying options for %.100s", arg);
644                                 *activep = 1;
645                                 break;
646                         }
647                 /* Avoid garbage check below, as strdelim is done. */
648                 return 0;
649
650         case oEscapeChar:
651                 intptr = &options->escape_char;
652                 arg = strdelim(&s);
653                 if (!arg || *arg == '\0')
654                         fatal("%.200s line %d: Missing argument.", filename, linenum);
655                 if (arg[0] == '^' && arg[2] == 0 &&
656                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
657                         value = (u_char) arg[1] & 31;
658                 else if (strlen(arg) == 1)
659                         value = (u_char) arg[0];
660                 else if (strcmp(arg, "none") == 0)
661                         value = SSH_ESCAPECHAR_NONE;
662                 else {
663                         fatal("%.200s line %d: Bad escape character.",
664                             filename, linenum);
665                         /* NOTREACHED */
666                         value = 0;      /* Avoid compiler warning. */
667                 }
668                 if (*activep && *intptr == -1)
669                         *intptr = value;
670                 break;
671
672         case oDeprecated:
673                 debug("%s line %d: Deprecated option \"%s\"",
674                     filename, linenum, keyword);
675                 return 0;
676
677         default:
678                 fatal("process_config_line: Unimplemented opcode %d", opcode);
679         }
680
681         /* Check that there is no garbage at end of line. */
682         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
683                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
684                      filename, linenum, arg);
685         }
686         return 0;
687 }
688
689
690 /*
691  * Reads the config file and modifies the options accordingly.  Options
692  * should already be initialized before this call.  This never returns if
693  * there is an error.  If the file does not exist, this returns 0.
694  */
695
696 int
697 read_config_file(const char *filename, const char *host, Options *options)
698 {
699         FILE *f;
700         char line[1024];
701         int active, linenum;
702         int bad_options = 0;
703
704         /* Open the file. */
705         f = fopen(filename, "r");
706         if (!f)
707                 return 0;
708
709         debug("Reading configuration data %.200s", filename);
710
711         /*
712          * Mark that we are now processing the options.  This flag is turned
713          * on/off by Host specifications.
714          */
715         active = 1;
716         linenum = 0;
717         while (fgets(line, sizeof(line), f)) {
718                 /* Update line number counter. */
719                 linenum++;
720                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
721                         bad_options++;
722         }
723         fclose(f);
724         if (bad_options > 0)
725                 fatal("%s: terminating, %d bad configuration options",
726                     filename, bad_options);
727         return 1;
728 }
729
730 /*
731  * Initializes options to special values that indicate that they have not yet
732  * been set.  Read_config_file will only set options with this value. Options
733  * are processed in the following order: command line, user config file,
734  * system config file.  Last, fill_default_options is called.
735  */
736
737 void
738 initialize_options(Options * options)
739 {
740         memset(options, 'X', sizeof(*options));
741         options->forward_agent = -1;
742         options->forward_x11 = -1;
743         options->xauth_location = NULL;
744         options->gateway_ports = -1;
745         options->use_privileged_port = -1;
746         options->rhosts_authentication = -1;
747         options->rsa_authentication = -1;
748         options->pubkey_authentication = -1;
749         options->challenge_response_authentication = -1;
750 #if defined(KRB4) || defined(KRB5)
751         options->kerberos_authentication = -1;
752 #endif
753 #if defined(AFS) || defined(KRB5)
754         options->kerberos_tgt_passing = -1;
755 #endif
756 #ifdef AFS
757         options->afs_token_passing = -1;
758 #endif
759         options->password_authentication = -1;
760         options->kbd_interactive_authentication = -1;
761         options->kbd_interactive_devices = NULL;
762         options->rhosts_rsa_authentication = -1;
763         options->hostbased_authentication = -1;
764         options->batch_mode = -1;
765         options->check_host_ip = -1;
766         options->strict_host_key_checking = -1;
767         options->compression = -1;
768         options->keepalives = -1;
769         options->compression_level = -1;
770         options->port = -1;
771         options->connection_attempts = -1;
772         options->number_of_password_prompts = -1;
773         options->cipher = -1;
774         options->ciphers = NULL;
775         options->macs = NULL;
776         options->hostkeyalgorithms = NULL;
777         options->protocol = SSH_PROTO_UNKNOWN;
778         options->num_identity_files = 0;
779         options->hostname = NULL;
780         options->host_key_alias = NULL;
781         options->proxy_command = NULL;
782         options->user = NULL;
783         options->escape_char = -1;
784         options->system_hostfile = NULL;
785         options->user_hostfile = NULL;
786         options->system_hostfile2 = NULL;
787         options->user_hostfile2 = NULL;
788         options->num_local_forwards = 0;
789         options->num_remote_forwards = 0;
790         options->clear_forwardings = -1;
791         options->log_level = SYSLOG_LEVEL_NOT_SET;
792         options->preferred_authentications = NULL;
793         options->bind_address = NULL;
794         options->smartcard_device = NULL;
795         options->no_host_authentication_for_localhost = - 1;
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         if (options->xauth_location == NULL)
813                 options->xauth_location = _PATH_XAUTH;
814         if (options->gateway_ports == -1)
815                 options->gateway_ports = 0;
816         if (options->use_privileged_port == -1)
817                 options->use_privileged_port = 0;
818         if (options->rhosts_authentication == -1)
819                 options->rhosts_authentication = 0;
820         if (options->rsa_authentication == -1)
821                 options->rsa_authentication = 1;
822         if (options->pubkey_authentication == -1)
823                 options->pubkey_authentication = 1;
824         if (options->challenge_response_authentication == -1)
825                 options->challenge_response_authentication = 1;
826 #if defined(KRB4) || defined(KRB5)
827         if (options->kerberos_authentication == -1)
828                 options->kerberos_authentication = 1;
829 #endif
830 #if defined(AFS) || defined(KRB5)
831         if (options->kerberos_tgt_passing == -1)
832                 options->kerberos_tgt_passing = 1;
833 #endif
834 #ifdef AFS
835         if (options->afs_token_passing == -1)
836                 options->afs_token_passing = 1;
837 #endif
838         if (options->password_authentication == -1)
839                 options->password_authentication = 1;
840         if (options->kbd_interactive_authentication == -1)
841                 options->kbd_interactive_authentication = 1;
842         if (options->rhosts_rsa_authentication == -1)
843                 options->rhosts_rsa_authentication = 0;
844         if (options->hostbased_authentication == -1)
845                 options->hostbased_authentication = 0;
846         if (options->batch_mode == -1)
847                 options->batch_mode = 0;
848         if (options->check_host_ip == -1)
849                 options->check_host_ip = 1;
850         if (options->strict_host_key_checking == -1)
851                 options->strict_host_key_checking = 2;  /* 2 is default */
852         if (options->compression == -1)
853                 options->compression = 0;
854         if (options->keepalives == -1)
855                 options->keepalives = 1;
856         if (options->compression_level == -1)
857                 options->compression_level = 6;
858         if (options->port == -1)
859                 options->port = 0;      /* Filled in ssh_connect. */
860         if (options->connection_attempts == -1)
861                 options->connection_attempts = 1;
862         if (options->number_of_password_prompts == -1)
863                 options->number_of_password_prompts = 3;
864         /* Selected in ssh_login(). */
865         if (options->cipher == -1)
866                 options->cipher = SSH_CIPHER_NOT_SET;
867         /* options->ciphers, default set in myproposals.h */
868         /* options->macs, default set in myproposals.h */
869         /* options->hostkeyalgorithms, default set in myproposals.h */
870         if (options->protocol == SSH_PROTO_UNKNOWN)
871                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
872         if (options->num_identity_files == 0) {
873                 if (options->protocol & SSH_PROTO_1) {
874                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
875                         options->identity_files[options->num_identity_files] =
876                             xmalloc(len);
877                         snprintf(options->identity_files[options->num_identity_files++],
878                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
879                 }
880                 if (options->protocol & SSH_PROTO_2) {
881                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
882                         options->identity_files[options->num_identity_files] =
883                             xmalloc(len);
884                         snprintf(options->identity_files[options->num_identity_files++],
885                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
886
887                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 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_DSA);
892                 }
893         }
894         if (options->escape_char == -1)
895                 options->escape_char = '~';
896         if (options->system_hostfile == NULL)
897                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
898         if (options->user_hostfile == NULL)
899                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
900         if (options->system_hostfile2 == NULL)
901                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
902         if (options->user_hostfile2 == NULL)
903                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
904         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
905                 options->log_level = SYSLOG_LEVEL_INFO;
906         if (options->clear_forwardings == 1)
907                 clear_forwardings(options);
908         if (options->no_host_authentication_for_localhost == - 1)
909                 options->no_host_authentication_for_localhost = 0;
910         /* options->proxy_command should not be set by default */
911         /* options->user will be set in the main program if appropriate */
912         /* options->hostname will be set in the main program if appropriate */
913         /* options->host_key_alias should not be set by default */
914         /* options->preferred_authentications will be set in ssh */
915 }
This page took 0.111074 seconds and 5 git commands to generate.