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