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