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