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