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