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