]> andersk Git - openssh.git/blame - readconf.c
- naddy@cvs.openbsd.org 2001/08/30 15:42:36
[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"
14e4a15f 15RCSID("$OpenBSD: readconf.c,v 1.87 2001/08/28 09:51:26 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,
eea098a3 117 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice
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 },
eea098a3 186 { "smartcarddevice", oSmartcardDevice },
5260325f 187 { NULL, 0 }
6a17f9c2 188};
189
aa3378df 190/*
191 * Adds a local TCP/IP port forward to options. Never returns if there is an
192 * error.
193 */
8efc0c15 194
6ae2364d 195void
57112b5a 196add_local_forward(Options *options, u_short port, const char *host,
197 u_short host_port)
8efc0c15 198{
5260325f 199 Forward *fwd;
3c62e7eb 200#ifndef HAVE_CYGWIN
5260325f 201 extern uid_t original_real_uid;
5260325f 202 if (port < IPPORT_RESERVED && original_real_uid != 0)
54b974dc 203 fatal("Privileged ports can only be forwarded by root.");
3c62e7eb 204#endif
5260325f 205 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
206 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
207 fwd = &options->local_forwards[options->num_local_forwards++];
208 fwd->port = port;
209 fwd->host = xstrdup(host);
210 fwd->host_port = host_port;
8efc0c15 211}
212
aa3378df 213/*
214 * Adds a remote TCP/IP port forward to options. Never returns if there is
215 * an error.
216 */
8efc0c15 217
6ae2364d 218void
57112b5a 219add_remote_forward(Options *options, u_short port, const char *host,
220 u_short host_port)
8efc0c15 221{
5260325f 222 Forward *fwd;
223 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
224 fatal("Too many remote forwards (max %d).",
225 SSH_MAX_FORWARDS_PER_DIRECTION);
226 fwd = &options->remote_forwards[options->num_remote_forwards++];
227 fwd->port = port;
228 fwd->host = xstrdup(host);
229 fwd->host_port = host_port;
8efc0c15 230}
231
aa3378df 232/*
6be9a5e8 233 * Returns the number of the token pointed to by cp or oBadOption.
aa3378df 234 */
8efc0c15 235
6ae2364d 236static OpCodes
5260325f 237parse_token(const char *cp, const char *filename, int linenum)
8efc0c15 238{
1e3b8b07 239 u_int i;
8efc0c15 240
5260325f 241 for (i = 0; keywords[i].name; i++)
aa3378df 242 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 243 return keywords[i].opcode;
8efc0c15 244
b7c70970 245 error("%s: line %d: Bad configuration option: %s",
246 filename, linenum, cp);
5260325f 247 return oBadOption;
8efc0c15 248}
249
aa3378df 250/*
251 * Processes a single option line as used in the configuration files. This
252 * only sets those values that have not already been set.
253 */
8efc0c15 254
e7c0f9d5 255int
256process_config_line(Options *options, const char *host,
5260325f 257 char *line, const char *filename, int linenum,
258 int *activep)
8efc0c15 259{
c6ed03bd 260 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *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
eea098a3 471 case oSmartcardDevice:
9ff6f66f 472 charptr = &options->smartcard_device;
473 goto parse_string;
eea098a3 474
5260325f 475 case oProxyCommand:
476 charptr = &options->proxy_command;
c6ed03bd 477 string = xstrdup("");
704b1659 478 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 479 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
5260325f 480 strcat(string, " ");
089fbbd2 481 strcat(string, arg);
5260325f 482 }
483 if (*activep && *charptr == NULL)
484 *charptr = string;
485 else
486 xfree(string);
487 return 0;
488
489 case oPort:
490 intptr = &options->port;
491parse_int:
704b1659 492 arg = strdelim(&s);
089fbbd2 493 if (!arg || *arg == '\0')
5260325f 494 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 495 if (arg[0] < '0' || arg[0] > '9')
5260325f 496 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 497
498 /* Octal, decimal, or hex format? */
089fbbd2 499 value = strtol(arg, &endofnumber, 0);
500 if (arg == endofnumber)
aa3378df 501 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 502 if (*activep && *intptr == -1)
503 *intptr = value;
504 break;
505
506 case oConnectionAttempts:
507 intptr = &options->connection_attempts;
508 goto parse_int;
509
510 case oCipher:
511 intptr = &options->cipher;
704b1659 512 arg = strdelim(&s);
089fbbd2 513 if (!arg || *arg == '\0')
71276795 514 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 515 value = cipher_number(arg);
5260325f 516 if (value == -1)
517 fatal("%.200s line %d: Bad cipher '%s'.",
089fbbd2 518 filename, linenum, arg ? arg : "<NONE>");
5260325f 519 if (*activep && *intptr == -1)
520 *intptr = value;
521 break;
522
a8be9f80 523 case oCiphers:
704b1659 524 arg = strdelim(&s);
089fbbd2 525 if (!arg || *arg == '\0')
71276795 526 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 527 if (!ciphers_valid(arg))
d0c832f3 528 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
089fbbd2 529 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 530 if (*activep && options->ciphers == NULL)
089fbbd2 531 options->ciphers = xstrdup(arg);
a8be9f80 532 break;
533
b2552997 534 case oMacs:
535 arg = strdelim(&s);
536 if (!arg || *arg == '\0')
537 fatal("%.200s line %d: Missing argument.", filename, linenum);
538 if (!mac_valid(arg))
539 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
540 filename, linenum, arg ? arg : "<NONE>");
541 if (*activep && options->macs == NULL)
542 options->macs = xstrdup(arg);
543 break;
544
e961a8f9 545 case oHostKeyAlgorithms:
546 arg = strdelim(&s);
547 if (!arg || *arg == '\0')
548 fatal("%.200s line %d: Missing argument.", filename, linenum);
549 if (!key_names_valid2(arg))
550 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
551 filename, linenum, arg ? arg : "<NONE>");
552 if (*activep && options->hostkeyalgorithms == NULL)
553 options->hostkeyalgorithms = xstrdup(arg);
554 break;
555
a8be9f80 556 case oProtocol:
557 intptr = &options->protocol;
704b1659 558 arg = strdelim(&s);
089fbbd2 559 if (!arg || *arg == '\0')
71276795 560 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 561 value = proto_spec(arg);
a8be9f80 562 if (value == SSH_PROTO_UNKNOWN)
563 fatal("%.200s line %d: Bad protocol spec '%s'.",
089fbbd2 564 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 565 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
566 *intptr = value;
567 break;
568
5260325f 569 case oLogLevel:
570 intptr = (int *) &options->log_level;
704b1659 571 arg = strdelim(&s);
089fbbd2 572 value = log_level_number(arg);
5260325f 573 if (value == (LogLevel) - 1)
54b974dc 574 fatal("%.200s line %d: unsupported log level '%s'",
089fbbd2 575 filename, linenum, arg ? arg : "<NONE>");
5260325f 576 if (*activep && (LogLevel) * intptr == -1)
577 *intptr = (LogLevel) value;
578 break;
579
580 case oRemoteForward:
704b1659 581 arg = strdelim(&s);
089fbbd2 582 if (!arg || *arg == '\0')
5260325f 583 fatal("%.200s line %d: Missing argument.", filename, linenum);
2d2a2c65 584 fwd_port = a2port(arg);
585 if (fwd_port == 0)
5260325f 586 fatal("%.200s line %d: Badly formatted port number.",
587 filename, linenum);
704b1659 588 arg = strdelim(&s);
089fbbd2 589 if (!arg || *arg == '\0')
5260325f 590 fatal("%.200s line %d: Missing second argument.",
591 filename, linenum);
089fbbd2 592 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 593 fatal("%.200s line %d: Badly formatted host:port.",
594 filename, linenum);
595 if (*activep)
596 add_remote_forward(options, fwd_port, buf, fwd_host_port);
597 break;
598
599 case oLocalForward:
704b1659 600 arg = strdelim(&s);
089fbbd2 601 if (!arg || *arg == '\0')
5260325f 602 fatal("%.200s line %d: Missing argument.", filename, linenum);
2d2a2c65 603 fwd_port = a2port(arg);
604 if (fwd_port == 0)
5260325f 605 fatal("%.200s line %d: Badly formatted port number.",
606 filename, linenum);
704b1659 607 arg = strdelim(&s);
089fbbd2 608 if (!arg || *arg == '\0')
5260325f 609 fatal("%.200s line %d: Missing second argument.",
610 filename, linenum);
089fbbd2 611 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 612 fatal("%.200s line %d: Badly formatted host:port.",
613 filename, linenum);
614 if (*activep)
615 add_local_forward(options, fwd_port, buf, fwd_host_port);
616 break;
617
0490e609 618 case oDynamicForward:
619 arg = strdelim(&s);
620 if (!arg || *arg == '\0')
621 fatal("%.200s line %d: Missing port argument.",
622 filename, linenum);
2d2a2c65 623 fwd_port = a2port(arg);
624 if (fwd_port == 0)
0490e609 625 fatal("%.200s line %d: Badly formatted port number.",
626 filename, linenum);
14e4a15f 627 if (*activep)
628 add_local_forward(options, fwd_port, "socks4", 0);
8002af61 629 break;
0490e609 630
5260325f 631 case oHost:
632 *activep = 0;
704b1659 633 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 634 if (match_pattern(host, arg)) {
635 debug("Applying options for %.100s", arg);
5260325f 636 *activep = 1;
637 break;
638 }
704b1659 639 /* Avoid garbage check below, as strdelim is done. */
5260325f 640 return 0;
641
642 case oEscapeChar:
643 intptr = &options->escape_char;
704b1659 644 arg = strdelim(&s);
089fbbd2 645 if (!arg || *arg == '\0')
5260325f 646 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 647 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 648 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
649 value = (u_char) arg[1] & 31;
089fbbd2 650 else if (strlen(arg) == 1)
1e3b8b07 651 value = (u_char) arg[0];
089fbbd2 652 else if (strcmp(arg, "none") == 0)
4bf9c10e 653 value = SSH_ESCAPECHAR_NONE;
5260325f 654 else {
655 fatal("%.200s line %d: Bad escape character.",
656 filename, linenum);
657 /* NOTREACHED */
658 value = 0; /* Avoid compiler warning. */
659 }
660 if (*activep && *intptr == -1)
661 *intptr = value;
662 break;
663
664 default:
665 fatal("process_config_line: Unimplemented opcode %d", opcode);
666 }
667
668 /* Check that there is no garbage at end of line. */
42f11eb2 669 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 670 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
671 filename, linenum, arg);
672 }
5260325f 673 return 0;
8efc0c15 674}
675
676
aa3378df 677/*
678 * Reads the config file and modifies the options accordingly. Options
679 * should already be initialized before this call. This never returns if
680 * there is an error. If the file does not exist, this returns immediately.
681 */
8efc0c15 682
6ae2364d 683void
5260325f 684read_config_file(const char *filename, const char *host, Options *options)
8efc0c15 685{
5260325f 686 FILE *f;
687 char line[1024];
688 int active, linenum;
689 int bad_options = 0;
690
691 /* Open the file. */
692 f = fopen(filename, "r");
693 if (!f)
694 return;
695
696 debug("Reading configuration data %.200s", filename);
697
aa3378df 698 /*
699 * Mark that we are now processing the options. This flag is turned
700 * on/off by Host specifications.
701 */
5260325f 702 active = 1;
703 linenum = 0;
704 while (fgets(line, sizeof(line), f)) {
705 /* Update line number counter. */
706 linenum++;
707 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
708 bad_options++;
709 }
710 fclose(f);
711 if (bad_options > 0)
54b974dc 712 fatal("%s: terminating, %d bad configuration options",
5260325f 713 filename, bad_options);
8efc0c15 714}
715
aa3378df 716/*
717 * Initializes options to special values that indicate that they have not yet
718 * been set. Read_config_file will only set options with this value. Options
719 * are processed in the following order: command line, user config file,
720 * system config file. Last, fill_default_options is called.
721 */
8efc0c15 722
6ae2364d 723void
5260325f 724initialize_options(Options * options)
8efc0c15 725{
5260325f 726 memset(options, 'X', sizeof(*options));
727 options->forward_agent = -1;
728 options->forward_x11 = -1;
fa649821 729 options->xauth_location = NULL;
5260325f 730 options->gateway_ports = -1;
731 options->use_privileged_port = -1;
732 options->rhosts_authentication = -1;
733 options->rsa_authentication = -1;
fa08c86b 734 options->pubkey_authentication = -1;
5ba55ada 735 options->challenge_response_authentication = -1;
ced49be2 736#if defined(KRB4) || defined(KRB5)
5260325f 737 options->kerberos_authentication = -1;
8efc0c15 738#endif
ced49be2 739#if defined(AFS) || defined(KRB5)
5260325f 740 options->kerberos_tgt_passing = -1;
ced49be2 741#endif
742#ifdef AFS
5260325f 743 options->afs_token_passing = -1;
8efc0c15 744#endif
5260325f 745 options->password_authentication = -1;
94ec8c6b 746 options->kbd_interactive_authentication = -1;
747 options->kbd_interactive_devices = NULL;
5260325f 748 options->rhosts_rsa_authentication = -1;
8002af61 749 options->hostbased_authentication = -1;
5260325f 750 options->fallback_to_rsh = -1;
751 options->use_rsh = -1;
752 options->batch_mode = -1;
753 options->check_host_ip = -1;
754 options->strict_host_key_checking = -1;
755 options->compression = -1;
756 options->keepalives = -1;
757 options->compression_level = -1;
758 options->port = -1;
759 options->connection_attempts = -1;
760 options->number_of_password_prompts = -1;
761 options->cipher = -1;
a8be9f80 762 options->ciphers = NULL;
b2552997 763 options->macs = NULL;
e961a8f9 764 options->hostkeyalgorithms = NULL;
a8be9f80 765 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 766 options->num_identity_files = 0;
767 options->hostname = NULL;
8abcdba4 768 options->host_key_alias = NULL;
5260325f 769 options->proxy_command = NULL;
770 options->user = NULL;
771 options->escape_char = -1;
772 options->system_hostfile = NULL;
773 options->user_hostfile = NULL;
a306f2dd 774 options->system_hostfile2 = NULL;
775 options->user_hostfile2 = NULL;
5260325f 776 options->num_local_forwards = 0;
777 options->num_remote_forwards = 0;
778 options->log_level = (LogLevel) - 1;
cab80f75 779 options->preferred_authentications = NULL;
3435f5a6 780 options->bind_address = NULL;
9ff6f66f 781 options->smartcard_device = NULL;
8efc0c15 782}
783
aa3378df 784/*
785 * Called after processing other sources of option data, this fills those
786 * options for which no value has been specified with their default values.
787 */
8efc0c15 788
6ae2364d 789void
5260325f 790fill_default_options(Options * options)
8efc0c15 791{
d2c46e77 792 int len;
793
5260325f 794 if (options->forward_agent == -1)
71276795 795 options->forward_agent = 0;
5260325f 796 if (options->forward_x11 == -1)
c8d54615 797 options->forward_x11 = 0;
fd9ede94 798#ifdef _PATH_XAUTH
fa649821 799 if (options->xauth_location == NULL)
fd9ede94 800 options->xauth_location = _PATH_XAUTH;
801#endif
5260325f 802 if (options->gateway_ports == -1)
803 options->gateway_ports = 0;
804 if (options->use_privileged_port == -1)
d5ebca2b 805 options->use_privileged_port = 0;
5260325f 806 if (options->rhosts_authentication == -1)
807 options->rhosts_authentication = 1;
808 if (options->rsa_authentication == -1)
809 options->rsa_authentication = 1;
fa08c86b 810 if (options->pubkey_authentication == -1)
811 options->pubkey_authentication = 1;
5ba55ada 812 if (options->challenge_response_authentication == -1)
10a2cbef 813 options->challenge_response_authentication = 1;
ced49be2 814#if defined(KRB4) || defined(KRB5)
5260325f 815 if (options->kerberos_authentication == -1)
816 options->kerberos_authentication = 1;
ced49be2 817#endif
818#if defined(AFS) || defined(KRB5)
5260325f 819 if (options->kerberos_tgt_passing == -1)
820 options->kerberos_tgt_passing = 1;
ced49be2 821#endif
822#ifdef AFS
5260325f 823 if (options->afs_token_passing == -1)
824 options->afs_token_passing = 1;
ced49be2 825#endif
5260325f 826 if (options->password_authentication == -1)
827 options->password_authentication = 1;
94ec8c6b 828 if (options->kbd_interactive_authentication == -1)
d464095c 829 options->kbd_interactive_authentication = 1;
5260325f 830 if (options->rhosts_rsa_authentication == -1)
831 options->rhosts_rsa_authentication = 1;
8002af61 832 if (options->hostbased_authentication == -1)
833 options->hostbased_authentication = 0;
5260325f 834 if (options->fallback_to_rsh == -1)
3f7a7e4a 835 options->fallback_to_rsh = 0;
5260325f 836 if (options->use_rsh == -1)
837 options->use_rsh = 0;
838 if (options->batch_mode == -1)
839 options->batch_mode = 0;
840 if (options->check_host_ip == -1)
841 options->check_host_ip = 1;
842 if (options->strict_host_key_checking == -1)
843 options->strict_host_key_checking = 2; /* 2 is default */
844 if (options->compression == -1)
845 options->compression = 0;
846 if (options->keepalives == -1)
847 options->keepalives = 1;
848 if (options->compression_level == -1)
849 options->compression_level = 6;
850 if (options->port == -1)
851 options->port = 0; /* Filled in ssh_connect. */
852 if (options->connection_attempts == -1)
ce773142 853 options->connection_attempts = 1;
5260325f 854 if (options->number_of_password_prompts == -1)
855 options->number_of_password_prompts = 3;
856 /* Selected in ssh_login(). */
857 if (options->cipher == -1)
858 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 859 /* options->ciphers, default set in myproposals.h */
b2552997 860 /* options->macs, default set in myproposals.h */
e961a8f9 861 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 862 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 863 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 864 if (options->num_identity_files == 0) {
fa08c86b 865 if (options->protocol & SSH_PROTO_1) {
d2c46e77 866 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 867 options->identity_files[options->num_identity_files] =
d2c46e77 868 xmalloc(len);
869 snprintf(options->identity_files[options->num_identity_files++],
870 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 871 }
872 if (options->protocol & SSH_PROTO_2) {
ec63b02d 873 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
874 options->identity_files[options->num_identity_files] =
875 xmalloc(len);
876 snprintf(options->identity_files[options->num_identity_files++],
877 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
878
d2c46e77 879 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 880 options->identity_files[options->num_identity_files] =
d2c46e77 881 xmalloc(len);
882 snprintf(options->identity_files[options->num_identity_files++],
883 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 884 }
a306f2dd 885 }
5260325f 886 if (options->escape_char == -1)
887 options->escape_char = '~';
888 if (options->system_hostfile == NULL)
42f11eb2 889 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 890 if (options->user_hostfile == NULL)
42f11eb2 891 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 892 if (options->system_hostfile2 == NULL)
42f11eb2 893 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 894 if (options->user_hostfile2 == NULL)
42f11eb2 895 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5260325f 896 if (options->log_level == (LogLevel) - 1)
59c97189 897 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 898 /* options->proxy_command should not be set by default */
899 /* options->user will be set in the main program if appropriate */
900 /* options->hostname will be set in the main program if appropriate */
8abcdba4 901 /* options->host_key_alias should not be set by default */
cab80f75 902 /* options->preferred_authentications will be set in ssh */
8efc0c15 903}
This page took 3.811445 seconds and 5 git commands to generate.