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