]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
add support for GssapiKeyExchange option on the client side
[gssapi-openssh.git] / openssh / readconf.c
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * Functions for reading the configuration files.
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13
14 #include "includes.h"
15 RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
16
17 #include "ssh.h"
18 #include "xmalloc.h"
19 #include "compat.h"
20 #include "cipher.h"
21 #include "pathnames.h"
22 #include "log.h"
23 #include "readconf.h"
24 #include "match.h"
25 #include "misc.h"
26 #include "kex.h"
27 #include "mac.h"
28
29 /* Format of the configuration file:
30
31    # Configuration data is parsed as follows:
32    #  1. command line options
33    #  2. user-specific file
34    #  3. system-wide file
35    # Any configuration value is only changed the first time it is set.
36    # Thus, host-specific definitions should be at the beginning of the
37    # configuration file, and defaults at the end.
38
39    # Host-specific declarations.  These may override anything above.  A single
40    # host may match multiple declarations; these are processed in the order
41    # that they are given in.
42
43    Host *.ngs.fi ngs.fi
44      User foo
45
46    Host fake.com
47      HostName another.host.name.real.org
48      User blaah
49      Port 34289
50      ForwardX11 no
51      ForwardAgent no
52
53    Host books.com
54      RemoteForward 9999 shadows.cs.hut.fi:9999
55      Cipher 3des
56
57    Host fascist.blob.com
58      Port 23123
59      User tylonen
60      RhostsAuthentication no
61      PasswordAuthentication no
62
63    Host puukko.hut.fi
64      User t35124p
65      ProxyCommand ssh-proxy %h %p
66
67    Host *.fr
68      PublicKeyAuthentication no
69
70    Host *.su
71      Cipher none
72      PasswordAuthentication no
73
74    # Defaults for various options
75    Host *
76      ForwardAgent no
77      ForwardX11 no
78      RhostsAuthentication yes
79      PasswordAuthentication yes
80      RSAAuthentication yes
81      RhostsRSAAuthentication yes
82      StrictHostKeyChecking yes
83      KeepAlives no
84      IdentityFile ~/.ssh/identity
85      Port 22
86      EscapeChar ~
87
88 */
89
90 /* Keyword tokens. */
91
92 typedef enum {
93         oBadOption,
94         oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
95         oPasswordAuthentication, oRSAAuthentication,
96         oChallengeResponseAuthentication, oXAuthLocation,
97 #if defined(KRB4) || defined(KRB5)
98         oKerberosAuthentication,
99 #endif
100 #ifdef GSSAPI
101         oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
102 #ifdef GSI
103         oGssGlobusDelegateLimitedCreds,
104 #endif /* GSI */
105 #endif /* GSSAPI */
106 #if defined(AFS) || defined(KRB5)
107         oKerberosTgtPassing,
108 #endif
109 #ifdef AFS
110         oAFSTokenPassing,
111 #endif
112         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
113         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
114         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
115         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
116         oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
117         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
118         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
119         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
120         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
121         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
122         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
123         oDeprecated
124 } OpCodes;
125
126 /* Textual representations of the tokens. */
127
128 static struct {
129         const char *name;
130         OpCodes opcode;
131 } keywords[] = {
132         { "forwardagent", oForwardAgent },
133         { "forwardx11", oForwardX11 },
134         { "xauthlocation", oXAuthLocation },
135         { "gatewayports", oGatewayPorts },
136         { "useprivilegedport", oUsePrivilegedPort },
137         { "rhostsauthentication", oRhostsAuthentication },
138         { "passwordauthentication", oPasswordAuthentication },
139         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
140         { "kbdinteractivedevices", oKbdInteractiveDevices },
141         { "rsaauthentication", oRSAAuthentication },
142         { "pubkeyauthentication", oPubkeyAuthentication },
143         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
144         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
145         { "hostbasedauthentication", oHostbasedAuthentication },
146         { "challengeresponseauthentication", oChallengeResponseAuthentication },
147         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
148         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
149 #if defined(KRB4) || defined(KRB5)
150         { "kerberosauthentication", oKerberosAuthentication },
151 #endif
152 #ifdef GSSAPI
153         { "gssapiauthentication", oGssAuthentication },
154         { "gssapikeyexchange", oGssKeyEx },
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", oDeprecated },
169         { "usersh", oDeprecated },
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, oBadOption }
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 oGssKeyEx:
387                 intptr = &options->gss_keyex;
388                 goto parse_flag;
389
390         case oGssDelegateCreds:
391                 intptr = &options->gss_deleg_creds;
392                 goto parse_flag;
393  
394 #ifdef GSI
395         case oGssGlobusDelegateLimitedCreds:
396                 intptr = &options->gss_globus_deleg_limited_proxy;
397                 goto parse_flag;
398 #endif /* GSI */
399
400 #endif /* GSSAPI */
401
402 #if defined(AFS) || defined(KRB5)
403         case oKerberosTgtPassing:
404                 intptr = &options->kerberos_tgt_passing;
405                 goto parse_flag;
406 #endif
407 #ifdef AFS
408         case oAFSTokenPassing:
409                 intptr = &options->afs_token_passing;
410                 goto parse_flag;
411 #endif
412         case oBatchMode:
413                 intptr = &options->batch_mode;
414                 goto parse_flag;
415
416         case oCheckHostIP:
417                 intptr = &options->check_host_ip;
418                 goto parse_flag;
419
420         case oStrictHostKeyChecking:
421                 intptr = &options->strict_host_key_checking;
422                 arg = strdelim(&s);
423                 if (!arg || *arg == '\0')
424                         fatal("%.200s line %d: Missing yes/no/ask argument.",
425                             filename, linenum);
426                 value = 0;      /* To avoid compiler warning... */
427                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
428                         value = 1;
429                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
430                         value = 0;
431                 else if (strcmp(arg, "ask") == 0)
432                         value = 2;
433                 else
434                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
435                 if (*activep && *intptr == -1)
436                         *intptr = value;
437                 break;
438
439         case oCompression:
440                 intptr = &options->compression;
441                 goto parse_flag;
442
443         case oKeepAlives:
444                 intptr = &options->keepalives;
445                 goto parse_flag;
446
447         case oNoHostAuthenticationForLocalhost:
448                 intptr = &options->no_host_authentication_for_localhost;
449                 goto parse_flag;
450
451         case oNumberOfPasswordPrompts:
452                 intptr = &options->number_of_password_prompts;
453                 goto parse_int;
454
455         case oCompressionLevel:
456                 intptr = &options->compression_level;
457                 goto parse_int;
458
459         case oIdentityFile:
460                 arg = strdelim(&s);
461                 if (!arg || *arg == '\0')
462                         fatal("%.200s line %d: Missing argument.", filename, linenum);
463                 if (*activep) {
464                         intptr = &options->num_identity_files;
465                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
466                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
467                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
468                         charptr =  &options->identity_files[*intptr];
469                         *charptr = xstrdup(arg);
470                         *intptr = *intptr + 1;
471                 }
472                 break;
473
474         case oXAuthLocation:
475                 charptr=&options->xauth_location;
476                 goto parse_string;
477
478         case oUser:
479                 charptr = &options->user;
480 parse_string:
481                 arg = strdelim(&s);
482                 if (!arg || *arg == '\0')
483                         fatal("%.200s line %d: Missing argument.", filename, linenum);
484                 if (*activep && *charptr == NULL)
485                         *charptr = xstrdup(arg);
486                 break;
487
488         case oGlobalKnownHostsFile:
489                 charptr = &options->system_hostfile;
490                 goto parse_string;
491
492         case oUserKnownHostsFile:
493                 charptr = &options->user_hostfile;
494                 goto parse_string;
495
496         case oGlobalKnownHostsFile2:
497                 charptr = &options->system_hostfile2;
498                 goto parse_string;
499
500         case oUserKnownHostsFile2:
501                 charptr = &options->user_hostfile2;
502                 goto parse_string;
503
504         case oHostName:
505                 charptr = &options->hostname;
506                 goto parse_string;
507
508         case oHostKeyAlias:
509                 charptr = &options->host_key_alias;
510                 goto parse_string;
511
512         case oPreferredAuthentications:
513                 charptr = &options->preferred_authentications;
514                 goto parse_string;
515
516         case oBindAddress:
517                 charptr = &options->bind_address;
518                 goto parse_string;
519
520         case oSmartcardDevice:
521                 charptr = &options->smartcard_device;
522                 goto parse_string;
523
524         case oProxyCommand:
525                 charptr = &options->proxy_command;
526                 string = xstrdup("");
527                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
528                         string = xrealloc(string, strlen(string) + strlen(arg) + 2);
529                         strcat(string, " ");
530                         strcat(string, arg);
531                 }
532                 if (*activep && *charptr == NULL)
533                         *charptr = string;
534                 else
535                         xfree(string);
536                 return 0;
537
538         case oPort:
539                 intptr = &options->port;
540 parse_int:
541                 arg = strdelim(&s);
542                 if (!arg || *arg == '\0')
543                         fatal("%.200s line %d: Missing argument.", filename, linenum);
544                 if (arg[0] < '0' || arg[0] > '9')
545                         fatal("%.200s line %d: Bad number.", filename, linenum);
546
547                 /* Octal, decimal, or hex format? */
548                 value = strtol(arg, &endofnumber, 0);
549                 if (arg == endofnumber)
550                         fatal("%.200s line %d: Bad number.", filename, linenum);
551                 if (*activep && *intptr == -1)
552                         *intptr = value;
553                 break;
554
555         case oConnectionAttempts:
556                 intptr = &options->connection_attempts;
557                 goto parse_int;
558
559         case oCipher:
560                 intptr = &options->cipher;
561                 arg = strdelim(&s);
562                 if (!arg || *arg == '\0')
563                         fatal("%.200s line %d: Missing argument.", filename, linenum);
564                 value = cipher_number(arg);
565                 if (value == -1)
566                         fatal("%.200s line %d: Bad cipher '%s'.",
567                             filename, linenum, arg ? arg : "<NONE>");
568                 if (*activep && *intptr == -1)
569                         *intptr = value;
570                 break;
571
572         case oCiphers:
573                 arg = strdelim(&s);
574                 if (!arg || *arg == '\0')
575                         fatal("%.200s line %d: Missing argument.", filename, linenum);
576                 if (!ciphers_valid(arg))
577                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
578                             filename, linenum, arg ? arg : "<NONE>");
579                 if (*activep && options->ciphers == NULL)
580                         options->ciphers = xstrdup(arg);
581                 break;
582
583         case oMacs:
584                 arg = strdelim(&s);
585                 if (!arg || *arg == '\0')
586                         fatal("%.200s line %d: Missing argument.", filename, linenum);
587                 if (!mac_valid(arg))
588                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
589                             filename, linenum, arg ? arg : "<NONE>");
590                 if (*activep && options->macs == NULL)
591                         options->macs = xstrdup(arg);
592                 break;
593
594         case oHostKeyAlgorithms:
595                 arg = strdelim(&s);
596                 if (!arg || *arg == '\0')
597                         fatal("%.200s line %d: Missing argument.", filename, linenum);
598                 if (!key_names_valid2(arg))
599                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
600                             filename, linenum, arg ? arg : "<NONE>");
601                 if (*activep && options->hostkeyalgorithms == NULL)
602                         options->hostkeyalgorithms = xstrdup(arg);
603                 break;
604
605         case oProtocol:
606                 intptr = &options->protocol;
607                 arg = strdelim(&s);
608                 if (!arg || *arg == '\0')
609                         fatal("%.200s line %d: Missing argument.", filename, linenum);
610                 value = proto_spec(arg);
611                 if (value == SSH_PROTO_UNKNOWN)
612                         fatal("%.200s line %d: Bad protocol spec '%s'.",
613                             filename, linenum, arg ? arg : "<NONE>");
614                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
615                         *intptr = value;
616                 break;
617
618         case oLogLevel:
619                 intptr = (int *) &options->log_level;
620                 arg = strdelim(&s);
621                 value = log_level_number(arg);
622                 if (value == SYSLOG_LEVEL_NOT_SET)
623                         fatal("%.200s line %d: unsupported log level '%s'",
624                             filename, linenum, arg ? arg : "<NONE>");
625                 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
626                         *intptr = (LogLevel) value;
627                 break;
628
629         case oLocalForward:
630         case oRemoteForward:
631                 arg = strdelim(&s);
632                 if (!arg || *arg == '\0')
633                         fatal("%.200s line %d: Missing port argument.",
634                             filename, linenum);
635                 if ((fwd_port = a2port(arg)) == 0)
636                         fatal("%.200s line %d: Bad listen port.",
637                             filename, linenum);
638                 arg = strdelim(&s);
639                 if (!arg || *arg == '\0')
640                         fatal("%.200s line %d: Missing second argument.",
641                             filename, linenum);
642                 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
643                     sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
644                         fatal("%.200s line %d: Bad forwarding specification.",
645                             filename, linenum);
646                 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
647                         fatal("%.200s line %d: Bad forwarding port.",
648                             filename, linenum);
649                 if (*activep) {
650                         if (opcode == oLocalForward)
651                                 add_local_forward(options, fwd_port, buf,
652                                     fwd_host_port);
653                         else if (opcode == oRemoteForward)
654                                 add_remote_forward(options, fwd_port, buf,
655                                     fwd_host_port);
656                 }
657                 break;
658
659         case oDynamicForward:
660                 arg = strdelim(&s);
661                 if (!arg || *arg == '\0')
662                         fatal("%.200s line %d: Missing port argument.",
663                             filename, linenum);
664                 fwd_port = a2port(arg);
665                 if (fwd_port == 0)
666                         fatal("%.200s line %d: Badly formatted port number.",
667                             filename, linenum);
668                 if (*activep)
669                         add_local_forward(options, fwd_port, "socks4", 0);
670                 break;
671
672         case oClearAllForwardings:
673                 intptr = &options->clear_forwardings;
674                 goto parse_flag;
675
676         case oHost:
677                 *activep = 0;
678                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
679                         if (match_pattern(host, arg)) {
680                                 debug("Applying options for %.100s", arg);
681                                 *activep = 1;
682                                 break;
683                         }
684                 /* Avoid garbage check below, as strdelim is done. */
685                 return 0;
686
687         case oEscapeChar:
688                 intptr = &options->escape_char;
689                 arg = strdelim(&s);
690                 if (!arg || *arg == '\0')
691                         fatal("%.200s line %d: Missing argument.", filename, linenum);
692                 if (arg[0] == '^' && arg[2] == 0 &&
693                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
694                         value = (u_char) arg[1] & 31;
695                 else if (strlen(arg) == 1)
696                         value = (u_char) arg[0];
697                 else if (strcmp(arg, "none") == 0)
698                         value = SSH_ESCAPECHAR_NONE;
699                 else {
700                         fatal("%.200s line %d: Bad escape character.",
701                             filename, linenum);
702                         /* NOTREACHED */
703                         value = 0;      /* Avoid compiler warning. */
704                 }
705                 if (*activep && *intptr == -1)
706                         *intptr = value;
707                 break;
708
709         case oDeprecated:
710                 debug("%s line %d: Deprecated option \"%s\"",
711                     filename, linenum, keyword);
712                 return 0;
713
714         default:
715                 fatal("process_config_line: Unimplemented opcode %d", opcode);
716         }
717
718         /* Check that there is no garbage at end of line. */
719         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
720                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
721                      filename, linenum, arg);
722         }
723         return 0;
724 }
725
726
727 /*
728  * Reads the config file and modifies the options accordingly.  Options
729  * should already be initialized before this call.  This never returns if
730  * there is an error.  If the file does not exist, this returns 0.
731  */
732
733 int
734 read_config_file(const char *filename, const char *host, Options *options)
735 {
736         FILE *f;
737         char line[1024];
738         int active, linenum;
739         int bad_options = 0;
740
741         /* Open the file. */
742         f = fopen(filename, "r");
743         if (!f)
744                 return 0;
745
746         debug("Reading configuration data %.200s", filename);
747
748         /*
749          * Mark that we are now processing the options.  This flag is turned
750          * on/off by Host specifications.
751          */
752         active = 1;
753         linenum = 0;
754         while (fgets(line, sizeof(line), f)) {
755                 /* Update line number counter. */
756                 linenum++;
757                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
758                         bad_options++;
759         }
760         fclose(f);
761         if (bad_options > 0)
762                 fatal("%s: terminating, %d bad configuration options",
763                     filename, bad_options);
764         return 1;
765 }
766
767 /*
768  * Initializes options to special values that indicate that they have not yet
769  * been set.  Read_config_file will only set options with this value. Options
770  * are processed in the following order: command line, user config file,
771  * system config file.  Last, fill_default_options is called.
772  */
773
774 void
775 initialize_options(Options * options)
776 {
777         memset(options, 'X', sizeof(*options));
778         options->forward_agent = -1;
779         options->forward_x11 = -1;
780         options->xauth_location = NULL;
781         options->gateway_ports = -1;
782         options->use_privileged_port = -1;
783         options->rhosts_authentication = -1;
784         options->rsa_authentication = -1;
785         options->pubkey_authentication = -1;
786         options->challenge_response_authentication = -1;
787 #ifdef GSSAPI
788         options->gss_authentication = -1;
789         options->gss_keyex = -1;
790         options->gss_deleg_creds = -1;
791 #ifdef GSI
792         options->gss_globus_deleg_limited_proxy = -1;
793 #endif /* GSI */
794 #endif /* GSSAPI */
795
796 #if defined(KRB4) || defined(KRB5)
797         options->kerberos_authentication = -1;
798 #endif
799 #if defined(AFS) || defined(KRB5)
800         options->kerberos_tgt_passing = -1;
801 #endif
802 #ifdef AFS
803         options->afs_token_passing = -1;
804 #endif
805         options->password_authentication = -1;
806         options->kbd_interactive_authentication = -1;
807         options->kbd_interactive_devices = NULL;
808         options->rhosts_rsa_authentication = -1;
809         options->hostbased_authentication = -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 = SYSLOG_LEVEL_NOT_SET;
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         if (options->xauth_location == NULL)
859                 options->xauth_location = _PATH_XAUTH;
860         if (options->gateway_ports == -1)
861                 options->gateway_ports = 0;
862         if (options->use_privileged_port == -1)
863                 options->use_privileged_port = 0;
864         if (options->rhosts_authentication == -1)
865                 options->rhosts_authentication = 0;
866         if (options->rsa_authentication == -1)
867                 options->rsa_authentication = 1;
868         if (options->pubkey_authentication == -1)
869                 options->pubkey_authentication = 1;
870         if (options->challenge_response_authentication == -1)
871                 options->challenge_response_authentication = 1;
872 #ifdef GSSAPI
873         if (options->gss_authentication == -1)
874                 options->gss_authentication = 1;
875         if (options->gss_keyex == -1)
876                 options->gss_keyex = 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 = 0;
902         if (options->hostbased_authentication == -1)
903                 options->hostbased_authentication = 0;
904         if (options->batch_mode == -1)
905                 options->batch_mode = 0;
906         if (options->check_host_ip == -1)
907                 options->check_host_ip = 1;
908         if (options->strict_host_key_checking == -1)
909                 options->strict_host_key_checking = 2;  /* 2 is default */
910         if (options->compression == -1)
911                 options->compression = 0;
912         if (options->keepalives == -1)
913                 options->keepalives = 1;
914         if (options->compression_level == -1)
915                 options->compression_level = 6;
916         if (options->port == -1)
917                 options->port = 0;      /* Filled in ssh_connect. */
918         if (options->connection_attempts == -1)
919                 options->connection_attempts = 1;
920         if (options->number_of_password_prompts == -1)
921                 options->number_of_password_prompts = 3;
922         /* Selected in ssh_login(). */
923         if (options->cipher == -1)
924                 options->cipher = SSH_CIPHER_NOT_SET;
925         /* options->ciphers, default set in myproposals.h */
926         /* options->macs, default set in myproposals.h */
927         /* options->hostkeyalgorithms, default set in myproposals.h */
928         if (options->protocol == SSH_PROTO_UNKNOWN)
929                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
930         if (options->num_identity_files == 0) {
931                 if (options->protocol & SSH_PROTO_1) {
932                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
933                         options->identity_files[options->num_identity_files] =
934                             xmalloc(len);
935                         snprintf(options->identity_files[options->num_identity_files++],
936                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
937                 }
938                 if (options->protocol & SSH_PROTO_2) {
939                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
940                         options->identity_files[options->num_identity_files] =
941                             xmalloc(len);
942                         snprintf(options->identity_files[options->num_identity_files++],
943                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
944
945                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
946                         options->identity_files[options->num_identity_files] =
947                             xmalloc(len);
948                         snprintf(options->identity_files[options->num_identity_files++],
949                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
950                 }
951         }
952         if (options->escape_char == -1)
953                 options->escape_char = '~';
954         if (options->system_hostfile == NULL)
955                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
956         if (options->user_hostfile == NULL)
957                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
958         if (options->system_hostfile2 == NULL)
959                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
960         if (options->user_hostfile2 == NULL)
961                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
962         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
963                 options->log_level = SYSLOG_LEVEL_INFO;
964         if (options->clear_forwardings == 1)
965                 clear_forwardings(options);
966         if (options->no_host_authentication_for_localhost == - 1)
967                 options->no_host_authentication_for_localhost = 0;
968         /* options->proxy_command should not be set by default */
969         /* options->user will be set in the main program if appropriate */
970         /* options->hostname will be set in the main program if appropriate */
971         /* options->host_key_alias should not be set by default */
972         /* options->preferred_authentications will be set in ssh */
973 }
This page took 0.26558 seconds and 5 git commands to generate.