]> andersk Git - openssh.git/blame - readconf.c
- (djm) Big OpenBSD sync:
[openssh.git] / readconf.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5260325f 5 * Functions for reading the configuration files.
6ae2364d 6 *
bcbf86ec 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".
5260325f 12 */
8efc0c15 13
14#include "includes.h"
94ec8c6b 15RCSID("$OpenBSD: readconf.c,v 1.49 2000/10/11 20:27:23 markus Exp $");
8efc0c15 16
17#include "ssh.h"
8efc0c15 18#include "readconf.h"
7368a6c8 19#include "match.h"
8efc0c15 20#include "xmalloc.h"
a8be9f80 21#include "compat.h"
8efc0c15 22
23/* Format of the configuration file:
24
25 # Configuration data is parsed as follows:
26 # 1. command line options
27 # 2. user-specific file
28 # 3. system-wide file
29 # Any configuration value is only changed the first time it is set.
30 # Thus, host-specific definitions should be at the beginning of the
31 # configuration file, and defaults at the end.
32
33 # Host-specific declarations. These may override anything above. A single
34 # host may match multiple declarations; these are processed in the order
35 # that they are given in.
36
37 Host *.ngs.fi ngs.fi
38 FallBackToRsh no
39
40 Host fake.com
41 HostName another.host.name.real.org
42 User blaah
43 Port 34289
44 ForwardX11 no
45 ForwardAgent no
46
47 Host books.com
48 RemoteForward 9999 shadows.cs.hut.fi:9999
49 Cipher 3des
50
51 Host fascist.blob.com
52 Port 23123
53 User tylonen
54 RhostsAuthentication no
55 PasswordAuthentication no
56
57 Host puukko.hut.fi
58 User t35124p
59 ProxyCommand ssh-proxy %h %p
60
61 Host *.fr
62 UseRsh yes
63
64 Host *.su
65 Cipher none
66 PasswordAuthentication no
67
68 # Defaults for various options
69 Host *
70 ForwardAgent no
71 ForwardX11 yes
72 RhostsAuthentication yes
73 PasswordAuthentication yes
74 RSAAuthentication yes
75 RhostsRSAAuthentication yes
76 FallBackToRsh no
77 UseRsh no
78 StrictHostKeyChecking yes
79 KeepAlives no
80 IdentityFile ~/.ssh/identity
81 Port 22
82 EscapeChar ~
83
84*/
85
86/* Keyword tokens. */
87
5260325f 88typedef enum {
89 oBadOption,
90 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
91 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
fa649821 92 oSkeyAuthentication, oXAuthLocation,
8efc0c15 93#ifdef KRB4
5260325f 94 oKerberosAuthentication,
8efc0c15 95#endif /* KRB4 */
96#ifdef AFS
5260325f 97 oKerberosTgtPassing, oAFSTokenPassing,
8efc0c15 98#endif
5260325f 99 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
100 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
a306f2dd 104 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
94ec8c6b 105 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication,
106 oKbdInteractiveAuthentication, oKbdInteractiveDevices
8efc0c15 107} OpCodes;
108
109/* Textual representations of the tokens. */
110
5260325f 111static struct {
112 const char *name;
113 OpCodes opcode;
114} keywords[] = {
115 { "forwardagent", oForwardAgent },
116 { "forwardx11", oForwardX11 },
fa649821 117 { "xauthlocation", oXAuthLocation },
5260325f 118 { "gatewayports", oGatewayPorts },
119 { "useprivilegedport", oUsePrivilegedPort },
120 { "rhostsauthentication", oRhostsAuthentication },
121 { "passwordauthentication", oPasswordAuthentication },
94ec8c6b 122 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
123 { "kbdinteractivedevices", oKbdInteractiveDevices },
5260325f 124 { "rsaauthentication", oRSAAuthentication },
1d1ffb87 125 { "dsaauthentication", oDSAAuthentication },
5260325f 126 { "skeyauthentication", oSkeyAuthentication },
8efc0c15 127#ifdef KRB4
5260325f 128 { "kerberosauthentication", oKerberosAuthentication },
8efc0c15 129#endif /* KRB4 */
130#ifdef AFS
5260325f 131 { "kerberostgtpassing", oKerberosTgtPassing },
132 { "afstokenpassing", oAFSTokenPassing },
8efc0c15 133#endif
5260325f 134 { "fallbacktorsh", oFallBackToRsh },
135 { "usersh", oUseRsh },
136 { "identityfile", oIdentityFile },
a306f2dd 137 { "identityfile2", oIdentityFile2 },
5260325f 138 { "hostname", oHostName },
139 { "proxycommand", oProxyCommand },
140 { "port", oPort },
141 { "cipher", oCipher },
a8be9f80 142 { "ciphers", oCiphers },
143 { "protocol", oProtocol },
5260325f 144 { "remoteforward", oRemoteForward },
145 { "localforward", oLocalForward },
146 { "user", oUser },
147 { "host", oHost },
148 { "escapechar", oEscapeChar },
149 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
150 { "globalknownhostsfile", oGlobalKnownHostsFile },
151 { "userknownhostsfile", oUserKnownHostsFile },
a306f2dd 152 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
153 { "userknownhostsfile2", oUserKnownHostsFile2 },
5260325f 154 { "connectionattempts", oConnectionAttempts },
155 { "batchmode", oBatchMode },
156 { "checkhostip", oCheckHostIP },
157 { "stricthostkeychecking", oStrictHostKeyChecking },
158 { "compression", oCompression },
159 { "compressionlevel", oCompressionLevel },
160 { "keepalive", oKeepAlives },
161 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
162 { "tisauthentication", oTISAuthentication },
163 { "loglevel", oLogLevel },
164 { NULL, 0 }
6a17f9c2 165};
166
aa3378df 167/*
168 * Adds a local TCP/IP port forward to options. Never returns if there is an
169 * error.
170 */
8efc0c15 171
6ae2364d 172void
57112b5a 173add_local_forward(Options *options, u_short port, const char *host,
174 u_short host_port)
8efc0c15 175{
5260325f 176 Forward *fwd;
3c62e7eb 177#ifndef HAVE_CYGWIN
5260325f 178 extern uid_t original_real_uid;
5260325f 179 if (port < IPPORT_RESERVED && original_real_uid != 0)
180 fatal("Privileged ports can only be forwarded by root.\n");
3c62e7eb 181#endif
5260325f 182 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
183 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
184 fwd = &options->local_forwards[options->num_local_forwards++];
185 fwd->port = port;
186 fwd->host = xstrdup(host);
187 fwd->host_port = host_port;
8efc0c15 188}
189
aa3378df 190/*
191 * Adds a remote TCP/IP port forward to options. Never returns if there is
192 * an error.
193 */
8efc0c15 194
6ae2364d 195void
57112b5a 196add_remote_forward(Options *options, u_short port, const char *host,
197 u_short host_port)
8efc0c15 198{
5260325f 199 Forward *fwd;
200 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
201 fatal("Too many remote forwards (max %d).",
202 SSH_MAX_FORWARDS_PER_DIRECTION);
203 fwd = &options->remote_forwards[options->num_remote_forwards++];
204 fwd->port = port;
205 fwd->host = xstrdup(host);
206 fwd->host_port = host_port;
8efc0c15 207}
208
aa3378df 209/*
210 * Returns the number of the token pointed to by cp of length len. Never
211 * returns if the token is not known.
212 */
8efc0c15 213
6ae2364d 214static OpCodes
5260325f 215parse_token(const char *cp, const char *filename, int linenum)
8efc0c15 216{
5260325f 217 unsigned int i;
8efc0c15 218
5260325f 219 for (i = 0; keywords[i].name; i++)
aa3378df 220 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 221 return keywords[i].opcode;
8efc0c15 222
5260325f 223 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
224 filename, linenum, cp);
225 return oBadOption;
8efc0c15 226}
227
aa3378df 228/*
229 * Processes a single option line as used in the configuration files. This
230 * only sets those values that have not already been set.
231 */
8efc0c15 232
e7c0f9d5 233int
234process_config_line(Options *options, const char *host,
5260325f 235 char *line, const char *filename, int linenum,
236 int *activep)
8efc0c15 237{
089fbbd2 238 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
57112b5a 239 int opcode, *intptr, value;
240 u_short fwd_port, fwd_host_port;
5260325f 241
704b1659 242 s = line;
243 /* Get the keyword. (Each line is supposed to begin with a keyword). */
244 keyword = strdelim(&s);
245 /* Ignore leading whitespace. */
246 if (*keyword == '\0')
247 keyword = strdelim(&s);
248 if (!*keyword || *keyword == '\n' || *keyword == '#')
5260325f 249 return 0;
250
089fbbd2 251 opcode = parse_token(keyword, filename, linenum);
5260325f 252
253 switch (opcode) {
254 case oBadOption:
aa3378df 255 /* don't panic, but count bad options */
256 return -1;
5260325f 257 /* NOTREACHED */
258 case oForwardAgent:
259 intptr = &options->forward_agent;
260parse_flag:
704b1659 261 arg = strdelim(&s);
089fbbd2 262 if (!arg || *arg == '\0')
5260325f 263 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
264 value = 0; /* To avoid compiler warning... */
089fbbd2 265 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 266 value = 1;
089fbbd2 267 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 268 value = 0;
269 else
270 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
271 if (*activep && *intptr == -1)
272 *intptr = value;
273 break;
274
275 case oForwardX11:
276 intptr = &options->forward_x11;
277 goto parse_flag;
278
279 case oGatewayPorts:
280 intptr = &options->gateway_ports;
281 goto parse_flag;
282
283 case oUsePrivilegedPort:
284 intptr = &options->use_privileged_port;
285 goto parse_flag;
286
287 case oRhostsAuthentication:
288 intptr = &options->rhosts_authentication;
289 goto parse_flag;
290
291 case oPasswordAuthentication:
292 intptr = &options->password_authentication;
293 goto parse_flag;
294
94ec8c6b 295 case oKbdInteractiveAuthentication:
296 intptr = &options->kbd_interactive_authentication;
297 goto parse_flag;
298
299 case oKbdInteractiveDevices:
300 charptr = &options->kbd_interactive_devices;
301 goto parse_string;
302
1d1ffb87 303 case oDSAAuthentication:
304 intptr = &options->dsa_authentication;
305 goto parse_flag;
306
5260325f 307 case oRSAAuthentication:
308 intptr = &options->rsa_authentication;
309 goto parse_flag;
310
311 case oRhostsRSAAuthentication:
312 intptr = &options->rhosts_rsa_authentication;
313 goto parse_flag;
314
315 case oTISAuthentication:
316 /* fallthrough, there is no difference on the client side */
317 case oSkeyAuthentication:
318 intptr = &options->skey_authentication;
319 goto parse_flag;
8efc0c15 320
321#ifdef KRB4
5260325f 322 case oKerberosAuthentication:
323 intptr = &options->kerberos_authentication;
324 goto parse_flag;
8efc0c15 325#endif /* KRB4 */
326
327#ifdef AFS
5260325f 328 case oKerberosTgtPassing:
329 intptr = &options->kerberos_tgt_passing;
330 goto parse_flag;
8efc0c15 331
5260325f 332 case oAFSTokenPassing:
333 intptr = &options->afs_token_passing;
334 goto parse_flag;
8efc0c15 335#endif
5260325f 336
337 case oFallBackToRsh:
338 intptr = &options->fallback_to_rsh;
339 goto parse_flag;
340
341 case oUseRsh:
342 intptr = &options->use_rsh;
343 goto parse_flag;
344
345 case oBatchMode:
346 intptr = &options->batch_mode;
347 goto parse_flag;
348
349 case oCheckHostIP:
350 intptr = &options->check_host_ip;
351 goto parse_flag;
352
353 case oStrictHostKeyChecking:
354 intptr = &options->strict_host_key_checking;
704b1659 355 arg = strdelim(&s);
089fbbd2 356 if (!arg || *arg == '\0')
5260325f 357 fatal("%.200s line %d: Missing yes/no argument.",
358 filename, linenum);
359 value = 0; /* To avoid compiler warning... */
089fbbd2 360 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 361 value = 1;
089fbbd2 362 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 363 value = 0;
089fbbd2 364 else if (strcmp(arg, "ask") == 0)
5260325f 365 value = 2;
366 else
367 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
368 if (*activep && *intptr == -1)
369 *intptr = value;
370 break;
371
372 case oCompression:
373 intptr = &options->compression;
374 goto parse_flag;
375
376 case oKeepAlives:
377 intptr = &options->keepalives;
378 goto parse_flag;
379
380 case oNumberOfPasswordPrompts:
381 intptr = &options->number_of_password_prompts;
382 goto parse_int;
383
384 case oCompressionLevel:
385 intptr = &options->compression_level;
386 goto parse_int;
387
388 case oIdentityFile:
a306f2dd 389 case oIdentityFile2:
704b1659 390 arg = strdelim(&s);
089fbbd2 391 if (!arg || *arg == '\0')
5260325f 392 fatal("%.200s line %d: Missing argument.", filename, linenum);
393 if (*activep) {
a306f2dd 394 intptr = (opcode == oIdentityFile) ?
395 &options->num_identity_files :
396 &options->num_identity_files2;
397 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 398 fatal("%.200s line %d: Too many identity files specified (max %d).",
399 filename, linenum, SSH_MAX_IDENTITY_FILES);
a306f2dd 400 charptr = (opcode == oIdentityFile) ?
401 &options->identity_files[*intptr] :
402 &options->identity_files2[*intptr];
089fbbd2 403 *charptr = xstrdup(arg);
a306f2dd 404 *intptr = *intptr + 1;
5260325f 405 }
406 break;
407
fa649821 408 case oXAuthLocation:
409 charptr=&options->xauth_location;
410 goto parse_string;
411
5260325f 412 case oUser:
413 charptr = &options->user;
414parse_string:
704b1659 415 arg = strdelim(&s);
089fbbd2 416 if (!arg || *arg == '\0')
5260325f 417 fatal("%.200s line %d: Missing argument.", filename, linenum);
418 if (*activep && *charptr == NULL)
089fbbd2 419 *charptr = xstrdup(arg);
5260325f 420 break;
421
422 case oGlobalKnownHostsFile:
423 charptr = &options->system_hostfile;
424 goto parse_string;
425
426 case oUserKnownHostsFile:
427 charptr = &options->user_hostfile;
428 goto parse_string;
429
a306f2dd 430 case oGlobalKnownHostsFile2:
431 charptr = &options->system_hostfile2;
432 goto parse_string;
433
434 case oUserKnownHostsFile2:
435 charptr = &options->user_hostfile2;
436 goto parse_string;
437
5260325f 438 case oHostName:
439 charptr = &options->hostname;
440 goto parse_string;
441
442 case oProxyCommand:
443 charptr = &options->proxy_command;
444 string = xstrdup("");
704b1659 445 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 446 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
5260325f 447 strcat(string, " ");
089fbbd2 448 strcat(string, arg);
5260325f 449 }
450 if (*activep && *charptr == NULL)
451 *charptr = string;
452 else
453 xfree(string);
454 return 0;
455
456 case oPort:
457 intptr = &options->port;
458parse_int:
704b1659 459 arg = strdelim(&s);
089fbbd2 460 if (!arg || *arg == '\0')
5260325f 461 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 462 if (arg[0] < '0' || arg[0] > '9')
5260325f 463 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 464
465 /* Octal, decimal, or hex format? */
089fbbd2 466 value = strtol(arg, &endofnumber, 0);
467 if (arg == endofnumber)
aa3378df 468 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 469 if (*activep && *intptr == -1)
470 *intptr = value;
471 break;
472
473 case oConnectionAttempts:
474 intptr = &options->connection_attempts;
475 goto parse_int;
476
477 case oCipher:
478 intptr = &options->cipher;
704b1659 479 arg = strdelim(&s);
089fbbd2 480 if (!arg || *arg == '\0')
71276795 481 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 482 value = cipher_number(arg);
5260325f 483 if (value == -1)
484 fatal("%.200s line %d: Bad cipher '%s'.",
089fbbd2 485 filename, linenum, arg ? arg : "<NONE>");
5260325f 486 if (*activep && *intptr == -1)
487 *intptr = value;
488 break;
489
a8be9f80 490 case oCiphers:
704b1659 491 arg = strdelim(&s);
089fbbd2 492 if (!arg || *arg == '\0')
71276795 493 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 494 if (!ciphers_valid(arg))
d0c832f3 495 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
089fbbd2 496 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 497 if (*activep && options->ciphers == NULL)
089fbbd2 498 options->ciphers = xstrdup(arg);
a8be9f80 499 break;
500
501 case oProtocol:
502 intptr = &options->protocol;
704b1659 503 arg = strdelim(&s);
089fbbd2 504 if (!arg || *arg == '\0')
71276795 505 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 506 value = proto_spec(arg);
a8be9f80 507 if (value == SSH_PROTO_UNKNOWN)
508 fatal("%.200s line %d: Bad protocol spec '%s'.",
089fbbd2 509 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 510 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
511 *intptr = value;
512 break;
513
5260325f 514 case oLogLevel:
515 intptr = (int *) &options->log_level;
704b1659 516 arg = strdelim(&s);
089fbbd2 517 value = log_level_number(arg);
5260325f 518 if (value == (LogLevel) - 1)
519 fatal("%.200s line %d: unsupported log level '%s'\n",
089fbbd2 520 filename, linenum, arg ? arg : "<NONE>");
5260325f 521 if (*activep && (LogLevel) * intptr == -1)
522 *intptr = (LogLevel) value;
523 break;
524
525 case oRemoteForward:
704b1659 526 arg = strdelim(&s);
089fbbd2 527 if (!arg || *arg == '\0')
5260325f 528 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 529 if (arg[0] < '0' || arg[0] > '9')
5260325f 530 fatal("%.200s line %d: Badly formatted port number.",
531 filename, linenum);
089fbbd2 532 fwd_port = atoi(arg);
704b1659 533 arg = strdelim(&s);
089fbbd2 534 if (!arg || *arg == '\0')
5260325f 535 fatal("%.200s line %d: Missing second argument.",
536 filename, linenum);
089fbbd2 537 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 538 fatal("%.200s line %d: Badly formatted host:port.",
539 filename, linenum);
540 if (*activep)
541 add_remote_forward(options, fwd_port, buf, fwd_host_port);
542 break;
543
544 case oLocalForward:
704b1659 545 arg = strdelim(&s);
089fbbd2 546 if (!arg || *arg == '\0')
5260325f 547 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 548 if (arg[0] < '0' || arg[0] > '9')
5260325f 549 fatal("%.200s line %d: Badly formatted port number.",
550 filename, linenum);
089fbbd2 551 fwd_port = atoi(arg);
704b1659 552 arg = strdelim(&s);
089fbbd2 553 if (!arg || *arg == '\0')
5260325f 554 fatal("%.200s line %d: Missing second argument.",
555 filename, linenum);
089fbbd2 556 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 557 fatal("%.200s line %d: Badly formatted host:port.",
558 filename, linenum);
559 if (*activep)
560 add_local_forward(options, fwd_port, buf, fwd_host_port);
561 break;
562
563 case oHost:
564 *activep = 0;
704b1659 565 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 566 if (match_pattern(host, arg)) {
567 debug("Applying options for %.100s", arg);
5260325f 568 *activep = 1;
569 break;
570 }
704b1659 571 /* Avoid garbage check below, as strdelim is done. */
5260325f 572 return 0;
573
574 case oEscapeChar:
575 intptr = &options->escape_char;
704b1659 576 arg = strdelim(&s);
089fbbd2 577 if (!arg || *arg == '\0')
5260325f 578 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 579 if (arg[0] == '^' && arg[2] == 0 &&
580 (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128)
581 value = (unsigned char) arg[1] & 31;
582 else if (strlen(arg) == 1)
583 value = (unsigned char) arg[0];
584 else if (strcmp(arg, "none") == 0)
5260325f 585 value = -2;
586 else {
587 fatal("%.200s line %d: Bad escape character.",
588 filename, linenum);
589 /* NOTREACHED */
590 value = 0; /* Avoid compiler warning. */
591 }
592 if (*activep && *intptr == -1)
593 *intptr = value;
594 break;
595
596 default:
597 fatal("process_config_line: Unimplemented opcode %d", opcode);
598 }
599
600 /* Check that there is no garbage at end of line. */
704b1659 601 if ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 602 {
603 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
604 filename, linenum, arg);
605 }
5260325f 606 return 0;
8efc0c15 607}
608
609
aa3378df 610/*
611 * Reads the config file and modifies the options accordingly. Options
612 * should already be initialized before this call. This never returns if
613 * there is an error. If the file does not exist, this returns immediately.
614 */
8efc0c15 615
6ae2364d 616void
5260325f 617read_config_file(const char *filename, const char *host, Options *options)
8efc0c15 618{
5260325f 619 FILE *f;
620 char line[1024];
621 int active, linenum;
622 int bad_options = 0;
623
624 /* Open the file. */
625 f = fopen(filename, "r");
626 if (!f)
627 return;
628
629 debug("Reading configuration data %.200s", filename);
630
aa3378df 631 /*
632 * Mark that we are now processing the options. This flag is turned
633 * on/off by Host specifications.
634 */
5260325f 635 active = 1;
636 linenum = 0;
637 while (fgets(line, sizeof(line), f)) {
638 /* Update line number counter. */
639 linenum++;
640 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
641 bad_options++;
642 }
643 fclose(f);
644 if (bad_options > 0)
645 fatal("%s: terminating, %d bad configuration options\n",
646 filename, bad_options);
8efc0c15 647}
648
aa3378df 649/*
650 * Initializes options to special values that indicate that they have not yet
651 * been set. Read_config_file will only set options with this value. Options
652 * are processed in the following order: command line, user config file,
653 * system config file. Last, fill_default_options is called.
654 */
8efc0c15 655
6ae2364d 656void
5260325f 657initialize_options(Options * options)
8efc0c15 658{
5260325f 659 memset(options, 'X', sizeof(*options));
660 options->forward_agent = -1;
661 options->forward_x11 = -1;
fa649821 662 options->xauth_location = NULL;
5260325f 663 options->gateway_ports = -1;
664 options->use_privileged_port = -1;
665 options->rhosts_authentication = -1;
666 options->rsa_authentication = -1;
1d1ffb87 667 options->dsa_authentication = -1;
5260325f 668 options->skey_authentication = -1;
8efc0c15 669#ifdef KRB4
5260325f 670 options->kerberos_authentication = -1;
8efc0c15 671#endif
672#ifdef AFS
5260325f 673 options->kerberos_tgt_passing = -1;
674 options->afs_token_passing = -1;
8efc0c15 675#endif
5260325f 676 options->password_authentication = -1;
94ec8c6b 677 options->kbd_interactive_authentication = -1;
678 options->kbd_interactive_devices = NULL;
5260325f 679 options->rhosts_rsa_authentication = -1;
680 options->fallback_to_rsh = -1;
681 options->use_rsh = -1;
682 options->batch_mode = -1;
683 options->check_host_ip = -1;
684 options->strict_host_key_checking = -1;
685 options->compression = -1;
686 options->keepalives = -1;
687 options->compression_level = -1;
688 options->port = -1;
689 options->connection_attempts = -1;
690 options->number_of_password_prompts = -1;
691 options->cipher = -1;
a8be9f80 692 options->ciphers = NULL;
693 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 694 options->num_identity_files = 0;
a306f2dd 695 options->num_identity_files2 = 0;
5260325f 696 options->hostname = NULL;
697 options->proxy_command = NULL;
698 options->user = NULL;
699 options->escape_char = -1;
700 options->system_hostfile = NULL;
701 options->user_hostfile = NULL;
a306f2dd 702 options->system_hostfile2 = NULL;
703 options->user_hostfile2 = NULL;
5260325f 704 options->num_local_forwards = 0;
705 options->num_remote_forwards = 0;
706 options->log_level = (LogLevel) - 1;
8efc0c15 707}
708
aa3378df 709/*
710 * Called after processing other sources of option data, this fills those
711 * options for which no value has been specified with their default values.
712 */
8efc0c15 713
6ae2364d 714void
5260325f 715fill_default_options(Options * options)
8efc0c15 716{
5260325f 717 if (options->forward_agent == -1)
71276795 718 options->forward_agent = 0;
5260325f 719 if (options->forward_x11 == -1)
c8d54615 720 options->forward_x11 = 0;
fa649821 721#ifdef XAUTH_PATH
722 if (options->xauth_location == NULL)
723 options->xauth_location = XAUTH_PATH;
724#endif /* XAUTH_PATH */
5260325f 725 if (options->gateway_ports == -1)
726 options->gateway_ports = 0;
727 if (options->use_privileged_port == -1)
728 options->use_privileged_port = 1;
729 if (options->rhosts_authentication == -1)
730 options->rhosts_authentication = 1;
731 if (options->rsa_authentication == -1)
732 options->rsa_authentication = 1;
1d1ffb87 733 if (options->dsa_authentication == -1)
734 options->dsa_authentication = 1;
5260325f 735 if (options->skey_authentication == -1)
736 options->skey_authentication = 0;
8efc0c15 737#ifdef KRB4
5260325f 738 if (options->kerberos_authentication == -1)
739 options->kerberos_authentication = 1;
8efc0c15 740#endif /* KRB4 */
741#ifdef AFS
5260325f 742 if (options->kerberos_tgt_passing == -1)
743 options->kerberos_tgt_passing = 1;
744 if (options->afs_token_passing == -1)
745 options->afs_token_passing = 1;
8efc0c15 746#endif /* AFS */
5260325f 747 if (options->password_authentication == -1)
748 options->password_authentication = 1;
94ec8c6b 749 if (options->kbd_interactive_authentication == -1)
750 options->kbd_interactive_authentication = 0;
5260325f 751 if (options->rhosts_rsa_authentication == -1)
752 options->rhosts_rsa_authentication = 1;
753 if (options->fallback_to_rsh == -1)
3f7a7e4a 754 options->fallback_to_rsh = 0;
5260325f 755 if (options->use_rsh == -1)
756 options->use_rsh = 0;
757 if (options->batch_mode == -1)
758 options->batch_mode = 0;
759 if (options->check_host_ip == -1)
760 options->check_host_ip = 1;
761 if (options->strict_host_key_checking == -1)
762 options->strict_host_key_checking = 2; /* 2 is default */
763 if (options->compression == -1)
764 options->compression = 0;
765 if (options->keepalives == -1)
766 options->keepalives = 1;
767 if (options->compression_level == -1)
768 options->compression_level = 6;
769 if (options->port == -1)
770 options->port = 0; /* Filled in ssh_connect. */
771 if (options->connection_attempts == -1)
772 options->connection_attempts = 4;
773 if (options->number_of_password_prompts == -1)
774 options->number_of_password_prompts = 3;
775 /* Selected in ssh_login(). */
776 if (options->cipher == -1)
777 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 778 /* options->ciphers, default set in myproposals.h */
a8be9f80 779 if (options->protocol == SSH_PROTO_UNKNOWN)
a306f2dd 780 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
5260325f 781 if (options->num_identity_files == 0) {
782 options->identity_files[0] =
783 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
784 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
785 options->num_identity_files = 1;
786 }
a306f2dd 787 if (options->num_identity_files2 == 0) {
788 options->identity_files2[0] =
1d1ffb87 789 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
790 sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
a306f2dd 791 options->num_identity_files2 = 1;
792 }
5260325f 793 if (options->escape_char == -1)
794 options->escape_char = '~';
795 if (options->system_hostfile == NULL)
796 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
797 if (options->user_hostfile == NULL)
798 options->user_hostfile = SSH_USER_HOSTFILE;
a306f2dd 799 if (options->system_hostfile2 == NULL)
800 options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
801 if (options->user_hostfile2 == NULL)
802 options->user_hostfile2 = SSH_USER_HOSTFILE2;
5260325f 803 if (options->log_level == (LogLevel) - 1)
804 options->log_level = SYSLOG_LEVEL_INFO;
805 /* options->proxy_command should not be set by default */
806 /* options->user will be set in the main program if appropriate */
807 /* options->hostname will be set in the main program if appropriate */
8efc0c15 808}
This page took 0.559021 seconds and 5 git commands to generate.