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