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