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