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