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