]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
1df5ce2d9b9d8d2210fc43972940e45fd8fed626
[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.104 2003/04/01 10:22:21 markus Exp $");
16
17 #include "ssh.h"
18 #include "xmalloc.h"
19 #include "compat.h"
20 #include "cipher.h"
21 #include "pathnames.h"
22 #include "log.h"
23 #include "readconf.h"
24 #include "match.h"
25 #include "misc.h"
26 #include "kex.h"
27 #include "mac.h"
28
29 /* Format of the configuration file:
30
31    # Configuration data is parsed as follows:
32    #  1. command line options
33    #  2. user-specific file
34    #  3. system-wide file
35    # Any configuration value is only changed the first time it is set.
36    # Thus, host-specific definitions should be at the beginning of the
37    # configuration file, and defaults at the end.
38
39    # Host-specific declarations.  These may override anything above.  A single
40    # host may match multiple declarations; these are processed in the order
41    # that they are given in.
42
43    Host *.ngs.fi ngs.fi
44      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         oEnableSSHKeysign,
118         oDeprecated
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", oDeprecated },
154         { "usersh", oDeprecated },
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         { "enablesshkeysign", oEnableSSHKeysign },
190         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
191         { NULL, oBadOption }
192 };
193
194 /*
195  * Adds a local TCP/IP port forward to options.  Never returns if there is an
196  * error.
197  */
198
199 void
200 add_local_forward(Options *options, u_short port, const char *host,
201                   u_short host_port)
202 {
203         Forward *fwd;
204 #ifndef NO_IPPORT_RESERVED_CONCEPT
205         extern uid_t original_real_uid;
206         if (port < IPPORT_RESERVED && original_real_uid != 0)
207                 fatal("Privileged ports can only be forwarded by root.");
208 #endif
209         if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
210                 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
211         fwd = &options->local_forwards[options->num_local_forwards++];
212         fwd->port = port;
213         fwd->host = xstrdup(host);
214         fwd->host_port = host_port;
215 }
216
217 /*
218  * Adds a remote TCP/IP port forward to options.  Never returns if there is
219  * an error.
220  */
221
222 void
223 add_remote_forward(Options *options, u_short port, const char *host,
224                    u_short host_port)
225 {
226         Forward *fwd;
227         if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
228                 fatal("Too many remote forwards (max %d).",
229                     SSH_MAX_FORWARDS_PER_DIRECTION);
230         fwd = &options->remote_forwards[options->num_remote_forwards++];
231         fwd->port = port;
232         fwd->host = xstrdup(host);
233         fwd->host_port = host_port;
234 }
235
236 static void
237 clear_forwardings(Options *options)
238 {
239         int i;
240
241         for (i = 0; i < options->num_local_forwards; i++)
242                 xfree(options->local_forwards[i].host);
243         options->num_local_forwards = 0;
244         for (i = 0; i < options->num_remote_forwards; i++)
245                 xfree(options->remote_forwards[i].host);
246         options->num_remote_forwards = 0;
247 }
248
249 /*
250  * Returns the number of the token pointed to by cp or oBadOption.
251  */
252
253 static OpCodes
254 parse_token(const char *cp, const char *filename, int linenum)
255 {
256         u_int i;
257
258         for (i = 0; keywords[i].name; i++)
259                 if (strcasecmp(cp, keywords[i].name) == 0)
260                         return keywords[i].opcode;
261
262         error("%s: line %d: Bad configuration option: %s",
263             filename, linenum, cp);
264         return oBadOption;
265 }
266
267 /*
268  * Processes a single option line as used in the configuration files. This
269  * only sets those values that have not already been set.
270  */
271 #define WHITESPACE " \t\r\n"
272
273 int
274 process_config_line(Options *options, const char *host,
275                     char *line, const char *filename, int linenum,
276                     int *activep)
277 {
278         char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
279         int opcode, *intptr, value;
280         size_t len;
281         u_short fwd_port, fwd_host_port;
282         char sfwd_host_port[6];
283
284         s = line;
285         /* Get the keyword. (Each line is supposed to begin with a keyword). */
286         keyword = strdelim(&s);
287         /* Ignore leading whitespace. */
288         if (*keyword == '\0')
289                 keyword = strdelim(&s);
290         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
291                 return 0;
292
293         opcode = parse_token(keyword, filename, linenum);
294
295         switch (opcode) {
296         case oBadOption:
297                 /* don't panic, but count bad options */
298                 return -1;
299                 /* NOTREACHED */
300         case oForwardAgent:
301                 intptr = &options->forward_agent;
302 parse_flag:
303                 arg = strdelim(&s);
304                 if (!arg || *arg == '\0')
305                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
306                 value = 0;      /* To avoid compiler warning... */
307                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
308                         value = 1;
309                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
310                         value = 0;
311                 else
312                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
313                 if (*activep && *intptr == -1)
314                         *intptr = value;
315                 break;
316
317         case oForwardX11:
318                 intptr = &options->forward_x11;
319                 goto parse_flag;
320
321         case oGatewayPorts:
322                 intptr = &options->gateway_ports;
323                 goto parse_flag;
324
325         case oUsePrivilegedPort:
326                 intptr = &options->use_privileged_port;
327                 goto parse_flag;
328
329         case oRhostsAuthentication:
330                 intptr = &options->rhosts_authentication;
331                 goto parse_flag;
332
333         case oPasswordAuthentication:
334                 intptr = &options->password_authentication;
335                 goto parse_flag;
336
337         case oKbdInteractiveAuthentication:
338                 intptr = &options->kbd_interactive_authentication;
339                 goto parse_flag;
340
341         case oKbdInteractiveDevices:
342                 charptr = &options->kbd_interactive_devices;
343                 goto parse_string;
344
345         case oPubkeyAuthentication:
346                 intptr = &options->pubkey_authentication;
347                 goto parse_flag;
348
349         case oRSAAuthentication:
350                 intptr = &options->rsa_authentication;
351                 goto parse_flag;
352
353         case oRhostsRSAAuthentication:
354                 intptr = &options->rhosts_rsa_authentication;
355                 goto parse_flag;
356
357         case oHostbasedAuthentication:
358                 intptr = &options->hostbased_authentication;
359                 goto parse_flag;
360
361         case oChallengeResponseAuthentication:
362                 intptr = &options->challenge_response_authentication;
363                 goto parse_flag;
364 #if defined(KRB4) || defined(KRB5)
365         case oKerberosAuthentication:
366                 intptr = &options->kerberos_authentication;
367                 goto parse_flag;
368 #endif
369 #if defined(AFS) || defined(KRB5)
370         case oKerberosTgtPassing:
371                 intptr = &options->kerberos_tgt_passing;
372                 goto parse_flag;
373 #endif
374 #ifdef AFS
375         case oAFSTokenPassing:
376                 intptr = &options->afs_token_passing;
377                 goto parse_flag;
378 #endif
379         case oBatchMode:
380                 intptr = &options->batch_mode;
381                 goto parse_flag;
382
383         case oCheckHostIP:
384                 intptr = &options->check_host_ip;
385                 goto parse_flag;
386
387         case oStrictHostKeyChecking:
388                 intptr = &options->strict_host_key_checking;
389                 arg = strdelim(&s);
390                 if (!arg || *arg == '\0')
391                         fatal("%.200s line %d: Missing yes/no/ask argument.",
392                             filename, linenum);
393                 value = 0;      /* To avoid compiler warning... */
394                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
395                         value = 1;
396                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
397                         value = 0;
398                 else if (strcmp(arg, "ask") == 0)
399                         value = 2;
400                 else
401                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
402                 if (*activep && *intptr == -1)
403                         *intptr = value;
404                 break;
405
406         case oCompression:
407                 intptr = &options->compression;
408                 goto parse_flag;
409
410         case oKeepAlives:
411                 intptr = &options->keepalives;
412                 goto parse_flag;
413
414         case oNoHostAuthenticationForLocalhost:
415                 intptr = &options->no_host_authentication_for_localhost;
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                 len = strspn(s, WHITESPACE "=");
494                 if (*activep && *charptr == NULL)
495                         *charptr = xstrdup(s + len);
496                 return 0;
497
498         case oPort:
499                 intptr = &options->port;
500 parse_int:
501                 arg = strdelim(&s);
502                 if (!arg || *arg == '\0')
503                         fatal("%.200s line %d: Missing argument.", filename, linenum);
504                 if (arg[0] < '0' || arg[0] > '9')
505                         fatal("%.200s line %d: Bad number.", filename, linenum);
506
507                 /* Octal, decimal, or hex format? */
508                 value = strtol(arg, &endofnumber, 0);
509                 if (arg == endofnumber)
510                         fatal("%.200s line %d: Bad number.", filename, linenum);
511                 if (*activep && *intptr == -1)
512                         *intptr = value;
513                 break;
514
515         case oConnectionAttempts:
516                 intptr = &options->connection_attempts;
517                 goto parse_int;
518
519         case oCipher:
520                 intptr = &options->cipher;
521                 arg = strdelim(&s);
522                 if (!arg || *arg == '\0')
523                         fatal("%.200s line %d: Missing argument.", filename, linenum);
524                 value = cipher_number(arg);
525                 if (value == -1)
526                         fatal("%.200s line %d: Bad cipher '%s'.",
527                             filename, linenum, arg ? arg : "<NONE>");
528                 if (*activep && *intptr == -1)
529                         *intptr = value;
530                 break;
531
532         case oCiphers:
533                 arg = strdelim(&s);
534                 if (!arg || *arg == '\0')
535                         fatal("%.200s line %d: Missing argument.", filename, linenum);
536                 if (!ciphers_valid(arg))
537                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
538                             filename, linenum, arg ? arg : "<NONE>");
539                 if (*activep && options->ciphers == NULL)
540                         options->ciphers = xstrdup(arg);
541                 break;
542
543         case oMacs:
544                 arg = strdelim(&s);
545                 if (!arg || *arg == '\0')
546                         fatal("%.200s line %d: Missing argument.", filename, linenum);
547                 if (!mac_valid(arg))
548                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
549                             filename, linenum, arg ? arg : "<NONE>");
550                 if (*activep && options->macs == NULL)
551                         options->macs = xstrdup(arg);
552                 break;
553
554         case oHostKeyAlgorithms:
555                 arg = strdelim(&s);
556                 if (!arg || *arg == '\0')
557                         fatal("%.200s line %d: Missing argument.", filename, linenum);
558                 if (!key_names_valid2(arg))
559                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
560                             filename, linenum, arg ? arg : "<NONE>");
561                 if (*activep && options->hostkeyalgorithms == NULL)
562                         options->hostkeyalgorithms = xstrdup(arg);
563                 break;
564
565         case oProtocol:
566                 intptr = &options->protocol;
567                 arg = strdelim(&s);
568                 if (!arg || *arg == '\0')
569                         fatal("%.200s line %d: Missing argument.", filename, linenum);
570                 value = proto_spec(arg);
571                 if (value == SSH_PROTO_UNKNOWN)
572                         fatal("%.200s line %d: Bad protocol spec '%s'.",
573                             filename, linenum, arg ? arg : "<NONE>");
574                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
575                         *intptr = value;
576                 break;
577
578         case oLogLevel:
579                 intptr = (int *) &options->log_level;
580                 arg = strdelim(&s);
581                 value = log_level_number(arg);
582                 if (value == SYSLOG_LEVEL_NOT_SET)
583                         fatal("%.200s line %d: unsupported log level '%s'",
584                             filename, linenum, arg ? arg : "<NONE>");
585                 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
586                         *intptr = (LogLevel) value;
587                 break;
588
589         case oLocalForward:
590         case oRemoteForward:
591                 arg = strdelim(&s);
592                 if (!arg || *arg == '\0')
593                         fatal("%.200s line %d: Missing port argument.",
594                             filename, linenum);
595                 if ((fwd_port = a2port(arg)) == 0)
596                         fatal("%.200s line %d: Bad listen port.",
597                             filename, linenum);
598                 arg = strdelim(&s);
599                 if (!arg || *arg == '\0')
600                         fatal("%.200s line %d: Missing second argument.",
601                             filename, linenum);
602                 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
603                     sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
604                         fatal("%.200s line %d: Bad forwarding specification.",
605                             filename, linenum);
606                 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
607                         fatal("%.200s line %d: Bad forwarding port.",
608                             filename, linenum);
609                 if (*activep) {
610                         if (opcode == oLocalForward)
611                                 add_local_forward(options, fwd_port, buf,
612                                     fwd_host_port);
613                         else if (opcode == oRemoteForward)
614                                 add_remote_forward(options, fwd_port, buf,
615                                     fwd_host_port);
616                 }
617                 break;
618
619         case oDynamicForward:
620                 arg = strdelim(&s);
621                 if (!arg || *arg == '\0')
622                         fatal("%.200s line %d: Missing port argument.",
623                             filename, linenum);
624                 fwd_port = a2port(arg);
625                 if (fwd_port == 0)
626                         fatal("%.200s line %d: Badly formatted port number.",
627                             filename, linenum);
628                 if (*activep)
629                         add_local_forward(options, fwd_port, "socks4", 0);
630                 break;
631
632         case oClearAllForwardings:
633                 intptr = &options->clear_forwardings;
634                 goto parse_flag;
635
636         case oHost:
637                 *activep = 0;
638                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
639                         if (match_pattern(host, arg)) {
640                                 debug("Applying options for %.100s", arg);
641                                 *activep = 1;
642                                 break;
643                         }
644                 /* Avoid garbage check below, as strdelim is done. */
645                 return 0;
646
647         case oEscapeChar:
648                 intptr = &options->escape_char;
649                 arg = strdelim(&s);
650                 if (!arg || *arg == '\0')
651                         fatal("%.200s line %d: Missing argument.", filename, linenum);
652                 if (arg[0] == '^' && arg[2] == 0 &&
653                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
654                         value = (u_char) arg[1] & 31;
655                 else if (strlen(arg) == 1)
656                         value = (u_char) arg[0];
657                 else if (strcmp(arg, "none") == 0)
658                         value = SSH_ESCAPECHAR_NONE;
659                 else {
660                         fatal("%.200s line %d: Bad escape character.",
661                             filename, linenum);
662                         /* NOTREACHED */
663                         value = 0;      /* Avoid compiler warning. */
664                 }
665                 if (*activep && *intptr == -1)
666                         *intptr = value;
667                 break;
668
669         case oEnableSSHKeysign:
670                 intptr = &options->enable_ssh_keysign;
671                 goto parse_flag;
672
673         case oDeprecated:
674                 debug("%s line %d: Deprecated option \"%s\"",
675                     filename, linenum, keyword);
676                 return 0;
677
678         default:
679                 fatal("process_config_line: Unimplemented opcode %d", opcode);
680         }
681
682         /* Check that there is no garbage at end of line. */
683         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
684                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
685                      filename, linenum, arg);
686         }
687         return 0;
688 }
689
690
691 /*
692  * Reads the config file and modifies the options accordingly.  Options
693  * should already be initialized before this call.  This never returns if
694  * there is an error.  If the file does not exist, this returns 0.
695  */
696
697 int
698 read_config_file(const char *filename, const char *host, Options *options)
699 {
700         FILE *f;
701         char line[1024];
702         int active, linenum;
703         int bad_options = 0;
704
705         /* Open the file. */
706         f = fopen(filename, "r");
707         if (!f)
708                 return 0;
709
710         debug("Reading configuration data %.200s", filename);
711
712         /*
713          * Mark that we are now processing the options.  This flag is turned
714          * on/off by Host specifications.
715          */
716         active = 1;
717         linenum = 0;
718         while (fgets(line, sizeof(line), f)) {
719                 /* Update line number counter. */
720                 linenum++;
721                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
722                         bad_options++;
723         }
724         fclose(f);
725         if (bad_options > 0)
726                 fatal("%s: terminating, %d bad configuration options",
727                     filename, bad_options);
728         return 1;
729 }
730
731 /*
732  * Initializes options to special values that indicate that they have not yet
733  * been set.  Read_config_file will only set options with this value. Options
734  * are processed in the following order: command line, user config file,
735  * system config file.  Last, fill_default_options is called.
736  */
737
738 void
739 initialize_options(Options * options)
740 {
741         memset(options, 'X', sizeof(*options));
742         options->forward_agent = -1;
743         options->forward_x11 = -1;
744         options->xauth_location = NULL;
745         options->gateway_ports = -1;
746         options->use_privileged_port = -1;
747         options->rhosts_authentication = -1;
748         options->rsa_authentication = -1;
749         options->pubkey_authentication = -1;
750         options->challenge_response_authentication = -1;
751 #if defined(KRB4) || defined(KRB5)
752         options->kerberos_authentication = -1;
753 #endif
754 #if defined(AFS) || defined(KRB5)
755         options->kerberos_tgt_passing = -1;
756 #endif
757 #ifdef AFS
758         options->afs_token_passing = -1;
759 #endif
760         options->password_authentication = -1;
761         options->kbd_interactive_authentication = -1;
762         options->kbd_interactive_devices = NULL;
763         options->rhosts_rsa_authentication = -1;
764         options->hostbased_authentication = -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 = SYSLOG_LEVEL_NOT_SET;
793         options->preferred_authentications = NULL;
794         options->bind_address = NULL;
795         options->smartcard_device = NULL;
796         options->enable_ssh_keysign = - 1;
797         options->no_host_authentication_for_localhost = - 1;
798 }
799
800 /*
801  * Called after processing other sources of option data, this fills those
802  * options for which no value has been specified with their default values.
803  */
804
805 void
806 fill_default_options(Options * options)
807 {
808         int len;
809
810         if (options->forward_agent == -1)
811                 options->forward_agent = 0;
812         if (options->forward_x11 == -1)
813                 options->forward_x11 = 0;
814         if (options->xauth_location == NULL)
815                 options->xauth_location = _PATH_XAUTH;
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 = 0;
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 = 0;
846         if (options->hostbased_authentication == -1)
847                 options->hostbased_authentication = 0;
848         if (options->batch_mode == -1)
849                 options->batch_mode = 0;
850         if (options->check_host_ip == -1)
851                 options->check_host_ip = 1;
852         if (options->strict_host_key_checking == -1)
853                 options->strict_host_key_checking = 2;  /* 2 is default */
854         if (options->compression == -1)
855                 options->compression = 0;
856         if (options->keepalives == -1)
857                 options->keepalives = 1;
858         if (options->compression_level == -1)
859                 options->compression_level = 6;
860         if (options->port == -1)
861                 options->port = 0;      /* Filled in ssh_connect. */
862         if (options->connection_attempts == -1)
863                 options->connection_attempts = 1;
864         if (options->number_of_password_prompts == -1)
865                 options->number_of_password_prompts = 3;
866         /* Selected in ssh_login(). */
867         if (options->cipher == -1)
868                 options->cipher = SSH_CIPHER_NOT_SET;
869         /* options->ciphers, default set in myproposals.h */
870         /* options->macs, default set in myproposals.h */
871         /* options->hostkeyalgorithms, default set in myproposals.h */
872         if (options->protocol == SSH_PROTO_UNKNOWN)
873                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
874         if (options->num_identity_files == 0) {
875                 if (options->protocol & SSH_PROTO_1) {
876                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
877                         options->identity_files[options->num_identity_files] =
878                             xmalloc(len);
879                         snprintf(options->identity_files[options->num_identity_files++],
880                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
881                 }
882                 if (options->protocol & SSH_PROTO_2) {
883                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
884                         options->identity_files[options->num_identity_files] =
885                             xmalloc(len);
886                         snprintf(options->identity_files[options->num_identity_files++],
887                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
888
889                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
890                         options->identity_files[options->num_identity_files] =
891                             xmalloc(len);
892                         snprintf(options->identity_files[options->num_identity_files++],
893                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
894                 }
895         }
896         if (options->escape_char == -1)
897                 options->escape_char = '~';
898         if (options->system_hostfile == NULL)
899                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
900         if (options->user_hostfile == NULL)
901                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
902         if (options->system_hostfile2 == NULL)
903                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
904         if (options->user_hostfile2 == NULL)
905                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
906         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
907                 options->log_level = SYSLOG_LEVEL_INFO;
908         if (options->clear_forwardings == 1)
909                 clear_forwardings(options);
910         if (options->no_host_authentication_for_localhost == - 1)
911                 options->no_host_authentication_for_localhost = 0;
912         if (options->enable_ssh_keysign == -1)
913                 options->enable_ssh_keysign = 0;
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.198423 seconds and 3 git commands to generate.