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