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