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