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