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