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