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