]> andersk Git - openssh.git/blame - readconf.c
- markus@cvs.openbsd.org 2001/08/01 22:03:33
[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"
9ff6f66f 15RCSID("$OpenBSD: readconf.c,v 1.86 2001/08/01 22:03:33 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{
4f7893dc 260 char buf[256], *s, *string = NULL, **charptr, *endofnumber, *keyword,
261 *arg;
57112b5a 262 int opcode, *intptr, value;
263 u_short fwd_port, fwd_host_port;
5260325f 264
704b1659 265 s = line;
266 /* Get the keyword. (Each line is supposed to begin with a keyword). */
267 keyword = strdelim(&s);
268 /* Ignore leading whitespace. */
269 if (*keyword == '\0')
270 keyword = strdelim(&s);
42f11eb2 271 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 272 return 0;
273
089fbbd2 274 opcode = parse_token(keyword, filename, linenum);
5260325f 275
276 switch (opcode) {
277 case oBadOption:
aa3378df 278 /* don't panic, but count bad options */
279 return -1;
5260325f 280 /* NOTREACHED */
281 case oForwardAgent:
282 intptr = &options->forward_agent;
283parse_flag:
704b1659 284 arg = strdelim(&s);
089fbbd2 285 if (!arg || *arg == '\0')
5260325f 286 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
287 value = 0; /* To avoid compiler warning... */
089fbbd2 288 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 289 value = 1;
089fbbd2 290 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 291 value = 0;
292 else
293 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
294 if (*activep && *intptr == -1)
295 *intptr = value;
296 break;
297
298 case oForwardX11:
299 intptr = &options->forward_x11;
300 goto parse_flag;
301
302 case oGatewayPorts:
303 intptr = &options->gateway_ports;
304 goto parse_flag;
305
306 case oUsePrivilegedPort:
307 intptr = &options->use_privileged_port;
308 goto parse_flag;
309
310 case oRhostsAuthentication:
311 intptr = &options->rhosts_authentication;
312 goto parse_flag;
313
314 case oPasswordAuthentication:
315 intptr = &options->password_authentication;
316 goto parse_flag;
317
94ec8c6b 318 case oKbdInteractiveAuthentication:
319 intptr = &options->kbd_interactive_authentication;
320 goto parse_flag;
321
322 case oKbdInteractiveDevices:
323 charptr = &options->kbd_interactive_devices;
324 goto parse_string;
325
fa08c86b 326 case oPubkeyAuthentication:
327 intptr = &options->pubkey_authentication;
1d1ffb87 328 goto parse_flag;
329
5260325f 330 case oRSAAuthentication:
331 intptr = &options->rsa_authentication;
332 goto parse_flag;
333
334 case oRhostsRSAAuthentication:
335 intptr = &options->rhosts_rsa_authentication;
336 goto parse_flag;
337
8002af61 338 case oHostbasedAuthentication:
339 intptr = &options->hostbased_authentication;
340 goto parse_flag;
341
d464095c 342 case oChallengeResponseAuthentication:
5ba55ada 343 intptr = &options->challenge_response_authentication;
5260325f 344 goto parse_flag;
ced49be2 345#if defined(KRB4) || defined(KRB5)
5260325f 346 case oKerberosAuthentication:
347 intptr = &options->kerberos_authentication;
348 goto parse_flag;
ced49be2 349#endif
350#if defined(AFS) || defined(KRB5)
5260325f 351 case oKerberosTgtPassing:
352 intptr = &options->kerberos_tgt_passing;
353 goto parse_flag;
ced49be2 354#endif
355#ifdef AFS
5260325f 356 case oAFSTokenPassing:
357 intptr = &options->afs_token_passing;
358 goto parse_flag;
8efc0c15 359#endif
5260325f 360 case oFallBackToRsh:
361 intptr = &options->fallback_to_rsh;
362 goto parse_flag;
363
364 case oUseRsh:
365 intptr = &options->use_rsh;
366 goto parse_flag;
367
368 case oBatchMode:
369 intptr = &options->batch_mode;
370 goto parse_flag;
371
372 case oCheckHostIP:
373 intptr = &options->check_host_ip;
374 goto parse_flag;
375
376 case oStrictHostKeyChecking:
377 intptr = &options->strict_host_key_checking;
704b1659 378 arg = strdelim(&s);
089fbbd2 379 if (!arg || *arg == '\0')
c76c8819 380 fatal("%.200s line %d: Missing yes/no/ask argument.",
5260325f 381 filename, linenum);
382 value = 0; /* To avoid compiler warning... */
089fbbd2 383 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 384 value = 1;
089fbbd2 385 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 386 value = 0;
089fbbd2 387 else if (strcmp(arg, "ask") == 0)
5260325f 388 value = 2;
389 else
390 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
391 if (*activep && *intptr == -1)
392 *intptr = value;
393 break;
394
395 case oCompression:
396 intptr = &options->compression;
397 goto parse_flag;
398
399 case oKeepAlives:
400 intptr = &options->keepalives;
401 goto parse_flag;
402
403 case oNumberOfPasswordPrompts:
404 intptr = &options->number_of_password_prompts;
405 goto parse_int;
406
407 case oCompressionLevel:
408 intptr = &options->compression_level;
409 goto parse_int;
410
411 case oIdentityFile:
704b1659 412 arg = strdelim(&s);
089fbbd2 413 if (!arg || *arg == '\0')
5260325f 414 fatal("%.200s line %d: Missing argument.", filename, linenum);
415 if (*activep) {
fa08c86b 416 intptr = &options->num_identity_files;
a306f2dd 417 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 418 fatal("%.200s line %d: Too many identity files specified (max %d).",
419 filename, linenum, SSH_MAX_IDENTITY_FILES);
fa08c86b 420 charptr = &options->identity_files[*intptr];
089fbbd2 421 *charptr = xstrdup(arg);
a306f2dd 422 *intptr = *intptr + 1;
5260325f 423 }
424 break;
425
fa649821 426 case oXAuthLocation:
427 charptr=&options->xauth_location;
428 goto parse_string;
429
5260325f 430 case oUser:
431 charptr = &options->user;
432parse_string:
704b1659 433 arg = strdelim(&s);
089fbbd2 434 if (!arg || *arg == '\0')
5260325f 435 fatal("%.200s line %d: Missing argument.", filename, linenum);
436 if (*activep && *charptr == NULL)
089fbbd2 437 *charptr = xstrdup(arg);
5260325f 438 break;
439
440 case oGlobalKnownHostsFile:
441 charptr = &options->system_hostfile;
442 goto parse_string;
443
444 case oUserKnownHostsFile:
445 charptr = &options->user_hostfile;
446 goto parse_string;
447
a306f2dd 448 case oGlobalKnownHostsFile2:
449 charptr = &options->system_hostfile2;
450 goto parse_string;
451
452 case oUserKnownHostsFile2:
453 charptr = &options->user_hostfile2;
454 goto parse_string;
455
5260325f 456 case oHostName:
457 charptr = &options->hostname;
458 goto parse_string;
459
8abcdba4 460 case oHostKeyAlias:
461 charptr = &options->host_key_alias;
462 goto parse_string;
463
cab80f75 464 case oPreferredAuthentications:
465 charptr = &options->preferred_authentications;
466 goto parse_string;
467
3435f5a6 468 case oBindAddress:
469 charptr = &options->bind_address;
470 goto parse_string;
471
eea098a3 472 case oSmartcardDevice:
9ff6f66f 473 charptr = &options->smartcard_device;
474 goto parse_string;
eea098a3 475
5260325f 476 case oProxyCommand:
477 charptr = &options->proxy_command;
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);
0490e609 627 add_local_forward(options, fwd_port, "socks4", 0);
8002af61 628 break;
0490e609 629
5260325f 630 case oHost:
631 *activep = 0;
704b1659 632 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 633 if (match_pattern(host, arg)) {
634 debug("Applying options for %.100s", arg);
5260325f 635 *activep = 1;
636 break;
637 }
704b1659 638 /* Avoid garbage check below, as strdelim is done. */
5260325f 639 return 0;
640
641 case oEscapeChar:
642 intptr = &options->escape_char;
704b1659 643 arg = strdelim(&s);
089fbbd2 644 if (!arg || *arg == '\0')
5260325f 645 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 646 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 647 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
648 value = (u_char) arg[1] & 31;
089fbbd2 649 else if (strlen(arg) == 1)
1e3b8b07 650 value = (u_char) arg[0];
089fbbd2 651 else if (strcmp(arg, "none") == 0)
4bf9c10e 652 value = SSH_ESCAPECHAR_NONE;
5260325f 653 else {
654 fatal("%.200s line %d: Bad escape character.",
655 filename, linenum);
656 /* NOTREACHED */
657 value = 0; /* Avoid compiler warning. */
658 }
659 if (*activep && *intptr == -1)
660 *intptr = value;
661 break;
662
663 default:
664 fatal("process_config_line: Unimplemented opcode %d", opcode);
665 }
666
667 /* Check that there is no garbage at end of line. */
42f11eb2 668 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 669 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
670 filename, linenum, arg);
671 }
5260325f 672 return 0;
8efc0c15 673}
674
675
aa3378df 676/*
677 * Reads the config file and modifies the options accordingly. Options
678 * should already be initialized before this call. This never returns if
679 * there is an error. If the file does not exist, this returns immediately.
680 */
8efc0c15 681
6ae2364d 682void
5260325f 683read_config_file(const char *filename, const char *host, Options *options)
8efc0c15 684{
5260325f 685 FILE *f;
686 char line[1024];
687 int active, linenum;
688 int bad_options = 0;
689
690 /* Open the file. */
691 f = fopen(filename, "r");
692 if (!f)
693 return;
694
695 debug("Reading configuration data %.200s", filename);
696
aa3378df 697 /*
698 * Mark that we are now processing the options. This flag is turned
699 * on/off by Host specifications.
700 */
5260325f 701 active = 1;
702 linenum = 0;
703 while (fgets(line, sizeof(line), f)) {
704 /* Update line number counter. */
705 linenum++;
706 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
707 bad_options++;
708 }
709 fclose(f);
710 if (bad_options > 0)
54b974dc 711 fatal("%s: terminating, %d bad configuration options",
5260325f 712 filename, bad_options);
8efc0c15 713}
714
aa3378df 715/*
716 * Initializes options to special values that indicate that they have not yet
717 * been set. Read_config_file will only set options with this value. Options
718 * are processed in the following order: command line, user config file,
719 * system config file. Last, fill_default_options is called.
720 */
8efc0c15 721
6ae2364d 722void
5260325f 723initialize_options(Options * options)
8efc0c15 724{
5260325f 725 memset(options, 'X', sizeof(*options));
726 options->forward_agent = -1;
727 options->forward_x11 = -1;
fa649821 728 options->xauth_location = NULL;
5260325f 729 options->gateway_ports = -1;
730 options->use_privileged_port = -1;
731 options->rhosts_authentication = -1;
732 options->rsa_authentication = -1;
fa08c86b 733 options->pubkey_authentication = -1;
5ba55ada 734 options->challenge_response_authentication = -1;
ced49be2 735#if defined(KRB4) || defined(KRB5)
5260325f 736 options->kerberos_authentication = -1;
8efc0c15 737#endif
ced49be2 738#if defined(AFS) || defined(KRB5)
5260325f 739 options->kerberos_tgt_passing = -1;
ced49be2 740#endif
741#ifdef AFS
5260325f 742 options->afs_token_passing = -1;
8efc0c15 743#endif
5260325f 744 options->password_authentication = -1;
94ec8c6b 745 options->kbd_interactive_authentication = -1;
746 options->kbd_interactive_devices = NULL;
5260325f 747 options->rhosts_rsa_authentication = -1;
8002af61 748 options->hostbased_authentication = -1;
5260325f 749 options->fallback_to_rsh = -1;
750 options->use_rsh = -1;
751 options->batch_mode = -1;
752 options->check_host_ip = -1;
753 options->strict_host_key_checking = -1;
754 options->compression = -1;
755 options->keepalives = -1;
756 options->compression_level = -1;
757 options->port = -1;
758 options->connection_attempts = -1;
759 options->number_of_password_prompts = -1;
760 options->cipher = -1;
a8be9f80 761 options->ciphers = NULL;
b2552997 762 options->macs = NULL;
e961a8f9 763 options->hostkeyalgorithms = NULL;
a8be9f80 764 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 765 options->num_identity_files = 0;
766 options->hostname = NULL;
8abcdba4 767 options->host_key_alias = NULL;
5260325f 768 options->proxy_command = NULL;
769 options->user = NULL;
770 options->escape_char = -1;
771 options->system_hostfile = NULL;
772 options->user_hostfile = NULL;
a306f2dd 773 options->system_hostfile2 = NULL;
774 options->user_hostfile2 = NULL;
5260325f 775 options->num_local_forwards = 0;
776 options->num_remote_forwards = 0;
777 options->log_level = (LogLevel) - 1;
cab80f75 778 options->preferred_authentications = NULL;
3435f5a6 779 options->bind_address = NULL;
9ff6f66f 780 options->smartcard_device = NULL;
8efc0c15 781}
782
aa3378df 783/*
784 * Called after processing other sources of option data, this fills those
785 * options for which no value has been specified with their default values.
786 */
8efc0c15 787
6ae2364d 788void
5260325f 789fill_default_options(Options * options)
8efc0c15 790{
d2c46e77 791 int len;
792
5260325f 793 if (options->forward_agent == -1)
71276795 794 options->forward_agent = 0;
5260325f 795 if (options->forward_x11 == -1)
c8d54615 796 options->forward_x11 = 0;
fd9ede94 797#ifdef _PATH_XAUTH
fa649821 798 if (options->xauth_location == NULL)
fd9ede94 799 options->xauth_location = _PATH_XAUTH;
800#endif
5260325f 801 if (options->gateway_ports == -1)
802 options->gateway_ports = 0;
803 if (options->use_privileged_port == -1)
d5ebca2b 804 options->use_privileged_port = 0;
5260325f 805 if (options->rhosts_authentication == -1)
806 options->rhosts_authentication = 1;
807 if (options->rsa_authentication == -1)
808 options->rsa_authentication = 1;
fa08c86b 809 if (options->pubkey_authentication == -1)
810 options->pubkey_authentication = 1;
5ba55ada 811 if (options->challenge_response_authentication == -1)
10a2cbef 812 options->challenge_response_authentication = 1;
ced49be2 813#if defined(KRB4) || defined(KRB5)
5260325f 814 if (options->kerberos_authentication == -1)
815 options->kerberos_authentication = 1;
ced49be2 816#endif
817#if defined(AFS) || defined(KRB5)
5260325f 818 if (options->kerberos_tgt_passing == -1)
819 options->kerberos_tgt_passing = 1;
ced49be2 820#endif
821#ifdef AFS
5260325f 822 if (options->afs_token_passing == -1)
823 options->afs_token_passing = 1;
ced49be2 824#endif
5260325f 825 if (options->password_authentication == -1)
826 options->password_authentication = 1;
94ec8c6b 827 if (options->kbd_interactive_authentication == -1)
d464095c 828 options->kbd_interactive_authentication = 1;
5260325f 829 if (options->rhosts_rsa_authentication == -1)
830 options->rhosts_rsa_authentication = 1;
8002af61 831 if (options->hostbased_authentication == -1)
832 options->hostbased_authentication = 0;
5260325f 833 if (options->fallback_to_rsh == -1)
3f7a7e4a 834 options->fallback_to_rsh = 0;
5260325f 835 if (options->use_rsh == -1)
836 options->use_rsh = 0;
837 if (options->batch_mode == -1)
838 options->batch_mode = 0;
839 if (options->check_host_ip == -1)
840 options->check_host_ip = 1;
841 if (options->strict_host_key_checking == -1)
842 options->strict_host_key_checking = 2; /* 2 is default */
843 if (options->compression == -1)
844 options->compression = 0;
845 if (options->keepalives == -1)
846 options->keepalives = 1;
847 if (options->compression_level == -1)
848 options->compression_level = 6;
849 if (options->port == -1)
850 options->port = 0; /* Filled in ssh_connect. */
851 if (options->connection_attempts == -1)
ce773142 852 options->connection_attempts = 1;
5260325f 853 if (options->number_of_password_prompts == -1)
854 options->number_of_password_prompts = 3;
855 /* Selected in ssh_login(). */
856 if (options->cipher == -1)
857 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 858 /* options->ciphers, default set in myproposals.h */
b2552997 859 /* options->macs, default set in myproposals.h */
e961a8f9 860 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 861 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 862 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 863 if (options->num_identity_files == 0) {
fa08c86b 864 if (options->protocol & SSH_PROTO_1) {
d2c46e77 865 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 866 options->identity_files[options->num_identity_files] =
d2c46e77 867 xmalloc(len);
868 snprintf(options->identity_files[options->num_identity_files++],
869 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 870 }
871 if (options->protocol & SSH_PROTO_2) {
ec63b02d 872 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
873 options->identity_files[options->num_identity_files] =
874 xmalloc(len);
875 snprintf(options->identity_files[options->num_identity_files++],
876 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
877
d2c46e77 878 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 879 options->identity_files[options->num_identity_files] =
d2c46e77 880 xmalloc(len);
881 snprintf(options->identity_files[options->num_identity_files++],
882 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 883 }
a306f2dd 884 }
5260325f 885 if (options->escape_char == -1)
886 options->escape_char = '~';
887 if (options->system_hostfile == NULL)
42f11eb2 888 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 889 if (options->user_hostfile == NULL)
42f11eb2 890 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 891 if (options->system_hostfile2 == NULL)
42f11eb2 892 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 893 if (options->user_hostfile2 == NULL)
42f11eb2 894 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5260325f 895 if (options->log_level == (LogLevel) - 1)
59c97189 896 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 897 /* options->proxy_command should not be set by default */
898 /* options->user will be set in the main program if appropriate */
899 /* options->hostname will be set in the main program if appropriate */
8abcdba4 900 /* options->host_key_alias should not be set by default */
cab80f75 901 /* options->preferred_authentications will be set in ssh */
8efc0c15 902}
This page took 0.281525 seconds and 5 git commands to generate.