]> andersk Git - openssh.git/blame - readconf.c
- markus@cvs.openbsd.org 2001/07/25 11:59:35
[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"
10a2cbef 15RCSID("$OpenBSD: readconf.c,v 1.83 2001/07/22 22:04:19 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,
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{
4f7893dc 259 char buf[256], *s, *string = NULL, **charptr, *endofnumber, *keyword,
260 *arg;
57112b5a 261 int opcode, *intptr, value;
262 u_short fwd_port, fwd_host_port;
5260325f 263
704b1659 264 s = line;
265 /* Get the keyword. (Each line is supposed to begin with a keyword). */
266 keyword = strdelim(&s);
267 /* Ignore leading whitespace. */
268 if (*keyword == '\0')
269 keyword = strdelim(&s);
42f11eb2 270 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 271 return 0;
272
089fbbd2 273 opcode = parse_token(keyword, filename, linenum);
5260325f 274
275 switch (opcode) {
276 case oBadOption:
aa3378df 277 /* don't panic, but count bad options */
278 return -1;
5260325f 279 /* NOTREACHED */
280 case oForwardAgent:
281 intptr = &options->forward_agent;
282parse_flag:
704b1659 283 arg = strdelim(&s);
089fbbd2 284 if (!arg || *arg == '\0')
5260325f 285 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
286 value = 0; /* To avoid compiler warning... */
089fbbd2 287 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 288 value = 1;
089fbbd2 289 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 290 value = 0;
291 else
292 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
293 if (*activep && *intptr == -1)
294 *intptr = value;
295 break;
296
297 case oForwardX11:
298 intptr = &options->forward_x11;
299 goto parse_flag;
300
301 case oGatewayPorts:
302 intptr = &options->gateway_ports;
303 goto parse_flag;
304
305 case oUsePrivilegedPort:
306 intptr = &options->use_privileged_port;
307 goto parse_flag;
308
309 case oRhostsAuthentication:
310 intptr = &options->rhosts_authentication;
311 goto parse_flag;
312
313 case oPasswordAuthentication:
314 intptr = &options->password_authentication;
315 goto parse_flag;
316
94ec8c6b 317 case oKbdInteractiveAuthentication:
318 intptr = &options->kbd_interactive_authentication;
319 goto parse_flag;
320
321 case oKbdInteractiveDevices:
322 charptr = &options->kbd_interactive_devices;
323 goto parse_string;
324
fa08c86b 325 case oPubkeyAuthentication:
326 intptr = &options->pubkey_authentication;
1d1ffb87 327 goto parse_flag;
328
5260325f 329 case oRSAAuthentication:
330 intptr = &options->rsa_authentication;
331 goto parse_flag;
332
333 case oRhostsRSAAuthentication:
334 intptr = &options->rhosts_rsa_authentication;
335 goto parse_flag;
336
8002af61 337 case oHostbasedAuthentication:
338 intptr = &options->hostbased_authentication;
339 goto parse_flag;
340
d464095c 341 case oChallengeResponseAuthentication:
5ba55ada 342 intptr = &options->challenge_response_authentication;
5260325f 343 goto parse_flag;
ced49be2 344#if defined(KRB4) || defined(KRB5)
5260325f 345 case oKerberosAuthentication:
346 intptr = &options->kerberos_authentication;
347 goto parse_flag;
ced49be2 348#endif
349#if defined(AFS) || defined(KRB5)
5260325f 350 case oKerberosTgtPassing:
351 intptr = &options->kerberos_tgt_passing;
352 goto parse_flag;
ced49be2 353#endif
354#ifdef AFS
5260325f 355 case oAFSTokenPassing:
356 intptr = &options->afs_token_passing;
357 goto parse_flag;
8efc0c15 358#endif
5260325f 359 case oFallBackToRsh:
360 intptr = &options->fallback_to_rsh;
361 goto parse_flag;
362
363 case oUseRsh:
364 intptr = &options->use_rsh;
365 goto parse_flag;
366
367 case oBatchMode:
368 intptr = &options->batch_mode;
369 goto parse_flag;
370
371 case oCheckHostIP:
372 intptr = &options->check_host_ip;
373 goto parse_flag;
374
375 case oStrictHostKeyChecking:
376 intptr = &options->strict_host_key_checking;
704b1659 377 arg = strdelim(&s);
089fbbd2 378 if (!arg || *arg == '\0')
c76c8819 379 fatal("%.200s line %d: Missing yes/no/ask argument.",
5260325f 380 filename, linenum);
381 value = 0; /* To avoid compiler warning... */
089fbbd2 382 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 383 value = 1;
089fbbd2 384 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 385 value = 0;
089fbbd2 386 else if (strcmp(arg, "ask") == 0)
5260325f 387 value = 2;
388 else
389 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
390 if (*activep && *intptr == -1)
391 *intptr = value;
392 break;
393
394 case oCompression:
395 intptr = &options->compression;
396 goto parse_flag;
397
398 case oKeepAlives:
399 intptr = &options->keepalives;
400 goto parse_flag;
401
402 case oNumberOfPasswordPrompts:
403 intptr = &options->number_of_password_prompts;
404 goto parse_int;
405
406 case oCompressionLevel:
407 intptr = &options->compression_level;
408 goto parse_int;
409
410 case oIdentityFile:
704b1659 411 arg = strdelim(&s);
089fbbd2 412 if (!arg || *arg == '\0')
5260325f 413 fatal("%.200s line %d: Missing argument.", filename, linenum);
414 if (*activep) {
fa08c86b 415 intptr = &options->num_identity_files;
a306f2dd 416 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 417 fatal("%.200s line %d: Too many identity files specified (max %d).",
418 filename, linenum, SSH_MAX_IDENTITY_FILES);
fa08c86b 419 charptr = &options->identity_files[*intptr];
089fbbd2 420 *charptr = xstrdup(arg);
a306f2dd 421 *intptr = *intptr + 1;
5260325f 422 }
423 break;
424
fa649821 425 case oXAuthLocation:
426 charptr=&options->xauth_location;
427 goto parse_string;
428
5260325f 429 case oUser:
430 charptr = &options->user;
431parse_string:
704b1659 432 arg = strdelim(&s);
089fbbd2 433 if (!arg || *arg == '\0')
5260325f 434 fatal("%.200s line %d: Missing argument.", filename, linenum);
435 if (*activep && *charptr == NULL)
089fbbd2 436 *charptr = xstrdup(arg);
5260325f 437 break;
438
439 case oGlobalKnownHostsFile:
440 charptr = &options->system_hostfile;
441 goto parse_string;
442
443 case oUserKnownHostsFile:
444 charptr = &options->user_hostfile;
445 goto parse_string;
446
a306f2dd 447 case oGlobalKnownHostsFile2:
448 charptr = &options->system_hostfile2;
449 goto parse_string;
450
451 case oUserKnownHostsFile2:
452 charptr = &options->user_hostfile2;
453 goto parse_string;
454
5260325f 455 case oHostName:
456 charptr = &options->hostname;
457 goto parse_string;
458
8abcdba4 459 case oHostKeyAlias:
460 charptr = &options->host_key_alias;
461 goto parse_string;
462
cab80f75 463 case oPreferredAuthentications:
464 charptr = &options->preferred_authentications;
465 goto parse_string;
466
3435f5a6 467 case oBindAddress:
468 charptr = &options->bind_address;
469 goto parse_string;
470
5260325f 471 case oProxyCommand:
472 charptr = &options->proxy_command;
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)
10a2cbef 806 options->challenge_response_authentication = 1;
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.265591 seconds and 5 git commands to generate.