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