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