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