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