]> andersk Git - openssh.git/blame - readconf.c
- markus@cvs.openbsd.org 2003/09/01 12:50:46
[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"
eac292f8 15RCSID("$OpenBSD: readconf.c,v 1.120 2003/09/01 12:50:46 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,
1c590258 95 oKerberosAuthentication, oKerberosTgtPassing,
5260325f 96 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
97 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
98 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
99 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
d464095c 100 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
b2552997 101 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
fa08c86b 102 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
cab80f75 103 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
e961a8f9 104 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
e1c5bfaf 105 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
80fcb74e 106 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
09ab3296 107 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
7364bd04 108 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
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 },
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 },
a2144546 186#ifdef DNS
21289cd0 187 { "verifyhostkeydns", oVerifyHostKeyDNS },
a2144546 188#else
189 { "verifyhostkeydns", oUnsupported },
190#endif
184eed6a 191 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
ffd7b36b 192 { "rekeylimit", oRekeyLimit },
09ab3296 193 { "connecttimeout", oConnectTimeout },
f811e52a 194 { "addressfamily", oAddressFamily },
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;
313/* parse_time: */
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
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
5260325f 386 case oKerberosAuthentication:
387 intptr = &options->kerberos_authentication;
388 goto parse_flag;
d0ec7f42 389
5260325f 390 case oKerberosTgtPassing:
391 intptr = &options->kerberos_tgt_passing;
392 goto parse_flag;
d0ec7f42 393
7364bd04 394 case oGssAuthentication:
395 intptr = &options->gss_authentication;
396 goto parse_flag;
397
398 case oGssDelegateCreds:
399 intptr = &options->gss_deleg_creds;
400 goto parse_flag;
401
5260325f 402 case oBatchMode:
403 intptr = &options->batch_mode;
404 goto parse_flag;
405
406 case oCheckHostIP:
407 intptr = &options->check_host_ip;
408 goto parse_flag;
409
21289cd0 410 case oVerifyHostKeyDNS:
411 intptr = &options->verify_host_key_dns;
412 goto parse_flag;
413
5260325f 414 case oStrictHostKeyChecking:
415 intptr = &options->strict_host_key_checking;
704b1659 416 arg = strdelim(&s);
089fbbd2 417 if (!arg || *arg == '\0')
c76c8819 418 fatal("%.200s line %d: Missing yes/no/ask argument.",
184eed6a 419 filename, linenum);
5260325f 420 value = 0; /* To avoid compiler warning... */
089fbbd2 421 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 422 value = 1;
089fbbd2 423 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 424 value = 0;
089fbbd2 425 else if (strcmp(arg, "ask") == 0)
5260325f 426 value = 2;
427 else
428 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
429 if (*activep && *intptr == -1)
430 *intptr = value;
431 break;
432
433 case oCompression:
434 intptr = &options->compression;
435 goto parse_flag;
436
437 case oKeepAlives:
438 intptr = &options->keepalives;
439 goto parse_flag;
440
8bbc048a 441 case oNoHostAuthenticationForLocalhost:
442 intptr = &options->no_host_authentication_for_localhost;
443 goto parse_flag;
444
5260325f 445 case oNumberOfPasswordPrompts:
446 intptr = &options->number_of_password_prompts;
447 goto parse_int;
448
449 case oCompressionLevel:
450 intptr = &options->compression_level;
451 goto parse_int;
452
ffd7b36b 453 case oRekeyLimit:
454 intptr = &options->rekey_limit;
455 arg = strdelim(&s);
456 if (!arg || *arg == '\0')
457 fatal("%.200s line %d: Missing argument.", filename, linenum);
458 if (arg[0] < '0' || arg[0] > '9')
459 fatal("%.200s line %d: Bad number.", filename, linenum);
460 value = strtol(arg, &endofnumber, 10);
461 if (arg == endofnumber)
462 fatal("%.200s line %d: Bad number.", filename, linenum);
463 switch (toupper(*endofnumber)) {
464 case 'K':
465 value *= 1<<10;
466 break;
467 case 'M':
468 value *= 1<<20;
469 break;
470 case 'G':
471 value *= 1<<30;
472 break;
473 }
474 if (*activep && *intptr == -1)
475 *intptr = value;
476 break;
477
5260325f 478 case oIdentityFile:
704b1659 479 arg = strdelim(&s);
089fbbd2 480 if (!arg || *arg == '\0')
5260325f 481 fatal("%.200s line %d: Missing argument.", filename, linenum);
482 if (*activep) {
fa08c86b 483 intptr = &options->num_identity_files;
a306f2dd 484 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 485 fatal("%.200s line %d: Too many identity files specified (max %d).",
184eed6a 486 filename, linenum, SSH_MAX_IDENTITY_FILES);
fa08c86b 487 charptr = &options->identity_files[*intptr];
089fbbd2 488 *charptr = xstrdup(arg);
a306f2dd 489 *intptr = *intptr + 1;
5260325f 490 }
491 break;
492
fa649821 493 case oXAuthLocation:
494 charptr=&options->xauth_location;
495 goto parse_string;
496
5260325f 497 case oUser:
498 charptr = &options->user;
499parse_string:
704b1659 500 arg = strdelim(&s);
089fbbd2 501 if (!arg || *arg == '\0')
5260325f 502 fatal("%.200s line %d: Missing argument.", filename, linenum);
503 if (*activep && *charptr == NULL)
089fbbd2 504 *charptr = xstrdup(arg);
5260325f 505 break;
506
507 case oGlobalKnownHostsFile:
508 charptr = &options->system_hostfile;
509 goto parse_string;
510
511 case oUserKnownHostsFile:
512 charptr = &options->user_hostfile;
513 goto parse_string;
514
a306f2dd 515 case oGlobalKnownHostsFile2:
516 charptr = &options->system_hostfile2;
517 goto parse_string;
518
519 case oUserKnownHostsFile2:
520 charptr = &options->user_hostfile2;
521 goto parse_string;
522
5260325f 523 case oHostName:
524 charptr = &options->hostname;
525 goto parse_string;
526
8abcdba4 527 case oHostKeyAlias:
528 charptr = &options->host_key_alias;
529 goto parse_string;
530
cab80f75 531 case oPreferredAuthentications:
532 charptr = &options->preferred_authentications;
533 goto parse_string;
534
3435f5a6 535 case oBindAddress:
536 charptr = &options->bind_address;
537 goto parse_string;
538
eea098a3 539 case oSmartcardDevice:
9ff6f66f 540 charptr = &options->smartcard_device;
541 goto parse_string;
eea098a3 542
5260325f 543 case oProxyCommand:
2d9c1828 544 if (s == NULL)
545 fatal("%.200s line %d: Missing argument.", filename, linenum);
5260325f 546 charptr = &options->proxy_command;
d718e75d 547 len = strspn(s, WHITESPACE "=");
5260325f 548 if (*activep && *charptr == NULL)
d718e75d 549 *charptr = xstrdup(s + len);
5260325f 550 return 0;
551
552 case oPort:
553 intptr = &options->port;
554parse_int:
704b1659 555 arg = strdelim(&s);
089fbbd2 556 if (!arg || *arg == '\0')
5260325f 557 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 558 if (arg[0] < '0' || arg[0] > '9')
5260325f 559 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 560
561 /* Octal, decimal, or hex format? */
089fbbd2 562 value = strtol(arg, &endofnumber, 0);
563 if (arg == endofnumber)
aa3378df 564 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 565 if (*activep && *intptr == -1)
566 *intptr = value;
567 break;
568
569 case oConnectionAttempts:
570 intptr = &options->connection_attempts;
571 goto parse_int;
572
573 case oCipher:
574 intptr = &options->cipher;
704b1659 575 arg = strdelim(&s);
089fbbd2 576 if (!arg || *arg == '\0')
71276795 577 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 578 value = cipher_number(arg);
5260325f 579 if (value == -1)
580 fatal("%.200s line %d: Bad cipher '%s'.",
184eed6a 581 filename, linenum, arg ? arg : "<NONE>");
5260325f 582 if (*activep && *intptr == -1)
583 *intptr = value;
584 break;
585
a8be9f80 586 case oCiphers:
704b1659 587 arg = strdelim(&s);
089fbbd2 588 if (!arg || *arg == '\0')
71276795 589 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 590 if (!ciphers_valid(arg))
d0c832f3 591 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
184eed6a 592 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 593 if (*activep && options->ciphers == NULL)
089fbbd2 594 options->ciphers = xstrdup(arg);
a8be9f80 595 break;
596
b2552997 597 case oMacs:
598 arg = strdelim(&s);
599 if (!arg || *arg == '\0')
600 fatal("%.200s line %d: Missing argument.", filename, linenum);
601 if (!mac_valid(arg))
602 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
184eed6a 603 filename, linenum, arg ? arg : "<NONE>");
b2552997 604 if (*activep && options->macs == NULL)
605 options->macs = xstrdup(arg);
606 break;
607
e961a8f9 608 case oHostKeyAlgorithms:
609 arg = strdelim(&s);
610 if (!arg || *arg == '\0')
611 fatal("%.200s line %d: Missing argument.", filename, linenum);
612 if (!key_names_valid2(arg))
613 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
184eed6a 614 filename, linenum, arg ? arg : "<NONE>");
e961a8f9 615 if (*activep && options->hostkeyalgorithms == NULL)
616 options->hostkeyalgorithms = xstrdup(arg);
617 break;
618
a8be9f80 619 case oProtocol:
620 intptr = &options->protocol;
704b1659 621 arg = strdelim(&s);
089fbbd2 622 if (!arg || *arg == '\0')
71276795 623 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 624 value = proto_spec(arg);
a8be9f80 625 if (value == SSH_PROTO_UNKNOWN)
626 fatal("%.200s line %d: Bad protocol spec '%s'.",
184eed6a 627 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 628 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
629 *intptr = value;
630 break;
631
5260325f 632 case oLogLevel:
633 intptr = (int *) &options->log_level;
704b1659 634 arg = strdelim(&s);
089fbbd2 635 value = log_level_number(arg);
5eaf8578 636 if (value == SYSLOG_LEVEL_NOT_SET)
54b974dc 637 fatal("%.200s line %d: unsupported log level '%s'",
184eed6a 638 filename, linenum, arg ? arg : "<NONE>");
5eaf8578 639 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
5260325f 640 *intptr = (LogLevel) value;
641 break;
642
5260325f 643 case oLocalForward:
3a8aabf0 644 case oRemoteForward:
704b1659 645 arg = strdelim(&s);
089fbbd2 646 if (!arg || *arg == '\0')
3a8aabf0 647 fatal("%.200s line %d: Missing port argument.",
648 filename, linenum);
649 if ((fwd_port = a2port(arg)) == 0)
650 fatal("%.200s line %d: Bad listen port.",
651 filename, linenum);
704b1659 652 arg = strdelim(&s);
089fbbd2 653 if (!arg || *arg == '\0')
5260325f 654 fatal("%.200s line %d: Missing second argument.",
3a8aabf0 655 filename, linenum);
656 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
657 sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
658 fatal("%.200s line %d: Bad forwarding specification.",
659 filename, linenum);
660 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
661 fatal("%.200s line %d: Bad forwarding port.",
662 filename, linenum);
663 if (*activep) {
664 if (opcode == oLocalForward)
665 add_local_forward(options, fwd_port, buf,
666 fwd_host_port);
667 else if (opcode == oRemoteForward)
668 add_remote_forward(options, fwd_port, buf,
669 fwd_host_port);
670 }
5260325f 671 break;
672
0490e609 673 case oDynamicForward:
674 arg = strdelim(&s);
675 if (!arg || *arg == '\0')
676 fatal("%.200s line %d: Missing port argument.",
677 filename, linenum);
2d2a2c65 678 fwd_port = a2port(arg);
679 if (fwd_port == 0)
0490e609 680 fatal("%.200s line %d: Badly formatted port number.",
681 filename, linenum);
14e4a15f 682 if (*activep)
37ba5172 683 add_local_forward(options, fwd_port, "socks", 0);
8002af61 684 break;
0490e609 685
e1c5bfaf 686 case oClearAllForwardings:
687 intptr = &options->clear_forwardings;
688 goto parse_flag;
689
5260325f 690 case oHost:
691 *activep = 0;
704b1659 692 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 693 if (match_pattern(host, arg)) {
694 debug("Applying options for %.100s", arg);
5260325f 695 *activep = 1;
696 break;
697 }
704b1659 698 /* Avoid garbage check below, as strdelim is done. */
5260325f 699 return 0;
700
701 case oEscapeChar:
702 intptr = &options->escape_char;
704b1659 703 arg = strdelim(&s);
089fbbd2 704 if (!arg || *arg == '\0')
5260325f 705 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 706 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 707 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
708 value = (u_char) arg[1] & 31;
089fbbd2 709 else if (strlen(arg) == 1)
1e3b8b07 710 value = (u_char) arg[0];
089fbbd2 711 else if (strcmp(arg, "none") == 0)
4bf9c10e 712 value = SSH_ESCAPECHAR_NONE;
5260325f 713 else {
714 fatal("%.200s line %d: Bad escape character.",
184eed6a 715 filename, linenum);
5260325f 716 /* NOTREACHED */
717 value = 0; /* Avoid compiler warning. */
718 }
719 if (*activep && *intptr == -1)
720 *intptr = value;
721 break;
722
f811e52a 723 case oAddressFamily:
724 arg = strdelim(&s);
1572b90f 725 intptr = &options->address_family;
f811e52a 726 if (strcasecmp(arg, "inet") == 0)
1572b90f 727 value = AF_INET;
f811e52a 728 else if (strcasecmp(arg, "inet6") == 0)
1572b90f 729 value = AF_INET6;
f811e52a 730 else if (strcasecmp(arg, "any") == 0)
1572b90f 731 value = AF_UNSPEC;
f811e52a 732 else
733 fatal("Unsupported AddressFamily \"%s\"", arg);
1572b90f 734 if (*activep && *intptr == -1)
735 *intptr = value;
f811e52a 736 break;
737
cc46e2ee 738 case oEnableSSHKeysign:
739 intptr = &options->enable_ssh_keysign;
740 goto parse_flag;
741
80fcb74e 742 case oDeprecated:
4feae93d 743 debug("%s line %d: Deprecated option \"%s\"",
80fcb74e 744 filename, linenum, keyword);
4feae93d 745 return 0;
80fcb74e 746
a2144546 747 case oUnsupported:
748 error("%s line %d: Unsupported option \"%s\"",
749 filename, linenum, keyword);
750 return 0;
751
5260325f 752 default:
753 fatal("process_config_line: Unimplemented opcode %d", opcode);
754 }
755
756 /* Check that there is no garbage at end of line. */
42f11eb2 757 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 758 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
184eed6a 759 filename, linenum, arg);
089fbbd2 760 }
5260325f 761 return 0;
8efc0c15 762}
763
764
aa3378df 765/*
766 * Reads the config file and modifies the options accordingly. Options
767 * should already be initialized before this call. This never returns if
93111dfa 768 * there is an error. If the file does not exist, this returns 0.
aa3378df 769 */
8efc0c15 770
93111dfa 771int
5260325f 772read_config_file(const char *filename, const char *host, Options *options)
8efc0c15 773{
5260325f 774 FILE *f;
775 char line[1024];
776 int active, linenum;
777 int bad_options = 0;
778
779 /* Open the file. */
780 f = fopen(filename, "r");
781 if (!f)
93111dfa 782 return 0;
5260325f 783
784 debug("Reading configuration data %.200s", filename);
785
aa3378df 786 /*
787 * Mark that we are now processing the options. This flag is turned
788 * on/off by Host specifications.
789 */
5260325f 790 active = 1;
791 linenum = 0;
792 while (fgets(line, sizeof(line), f)) {
793 /* Update line number counter. */
794 linenum++;
795 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
796 bad_options++;
797 }
798 fclose(f);
799 if (bad_options > 0)
54b974dc 800 fatal("%s: terminating, %d bad configuration options",
184eed6a 801 filename, bad_options);
93111dfa 802 return 1;
8efc0c15 803}
804
aa3378df 805/*
806 * Initializes options to special values that indicate that they have not yet
807 * been set. Read_config_file will only set options with this value. Options
808 * are processed in the following order: command line, user config file,
809 * system config file. Last, fill_default_options is called.
810 */
8efc0c15 811
6ae2364d 812void
5260325f 813initialize_options(Options * options)
8efc0c15 814{
5260325f 815 memset(options, 'X', sizeof(*options));
816 options->forward_agent = -1;
817 options->forward_x11 = -1;
fa649821 818 options->xauth_location = NULL;
5260325f 819 options->gateway_ports = -1;
820 options->use_privileged_port = -1;
5260325f 821 options->rsa_authentication = -1;
fa08c86b 822 options->pubkey_authentication = -1;
5ba55ada 823 options->challenge_response_authentication = -1;
5260325f 824 options->kerberos_authentication = -1;
5260325f 825 options->kerberos_tgt_passing = -1;
7364bd04 826 options->gss_authentication = -1;
827 options->gss_deleg_creds = -1;
5260325f 828 options->password_authentication = -1;
94ec8c6b 829 options->kbd_interactive_authentication = -1;
830 options->kbd_interactive_devices = NULL;
5260325f 831 options->rhosts_rsa_authentication = -1;
8002af61 832 options->hostbased_authentication = -1;
5260325f 833 options->batch_mode = -1;
834 options->check_host_ip = -1;
835 options->strict_host_key_checking = -1;
836 options->compression = -1;
837 options->keepalives = -1;
838 options->compression_level = -1;
839 options->port = -1;
1572b90f 840 options->address_family = -1;
5260325f 841 options->connection_attempts = -1;
09ab3296 842 options->connection_timeout = -1;
5260325f 843 options->number_of_password_prompts = -1;
844 options->cipher = -1;
a8be9f80 845 options->ciphers = NULL;
b2552997 846 options->macs = NULL;
e961a8f9 847 options->hostkeyalgorithms = NULL;
a8be9f80 848 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 849 options->num_identity_files = 0;
850 options->hostname = NULL;
8abcdba4 851 options->host_key_alias = NULL;
5260325f 852 options->proxy_command = NULL;
853 options->user = NULL;
854 options->escape_char = -1;
855 options->system_hostfile = NULL;
856 options->user_hostfile = NULL;
a306f2dd 857 options->system_hostfile2 = NULL;
858 options->user_hostfile2 = NULL;
5260325f 859 options->num_local_forwards = 0;
860 options->num_remote_forwards = 0;
e1c5bfaf 861 options->clear_forwardings = -1;
5eaf8578 862 options->log_level = SYSLOG_LEVEL_NOT_SET;
cab80f75 863 options->preferred_authentications = NULL;
3435f5a6 864 options->bind_address = NULL;
9ff6f66f 865 options->smartcard_device = NULL;
cc46e2ee 866 options->enable_ssh_keysign = - 1;
8bbc048a 867 options->no_host_authentication_for_localhost = - 1;
ffd7b36b 868 options->rekey_limit = - 1;
21289cd0 869 options->verify_host_key_dns = -1;
8efc0c15 870}
871
aa3378df 872/*
873 * Called after processing other sources of option data, this fills those
874 * options for which no value has been specified with their default values.
875 */
8efc0c15 876
6ae2364d 877void
5260325f 878fill_default_options(Options * options)
8efc0c15 879{
d2c46e77 880 int len;
881
5260325f 882 if (options->forward_agent == -1)
71276795 883 options->forward_agent = 0;
5260325f 884 if (options->forward_x11 == -1)
c8d54615 885 options->forward_x11 = 0;
fa649821 886 if (options->xauth_location == NULL)
fd9ede94 887 options->xauth_location = _PATH_XAUTH;
5260325f 888 if (options->gateway_ports == -1)
889 options->gateway_ports = 0;
890 if (options->use_privileged_port == -1)
d5ebca2b 891 options->use_privileged_port = 0;
5260325f 892 if (options->rsa_authentication == -1)
893 options->rsa_authentication = 1;
fa08c86b 894 if (options->pubkey_authentication == -1)
895 options->pubkey_authentication = 1;
5ba55ada 896 if (options->challenge_response_authentication == -1)
10a2cbef 897 options->challenge_response_authentication = 1;
5260325f 898 if (options->kerberos_authentication == -1)
899 options->kerberos_authentication = 1;
5260325f 900 if (options->kerberos_tgt_passing == -1)
901 options->kerberos_tgt_passing = 1;
7364bd04 902 if (options->gss_authentication == -1)
903 options->gss_authentication = 1;
904 if (options->gss_deleg_creds == -1)
905 options->gss_deleg_creds = 0;
5260325f 906 if (options->password_authentication == -1)
907 options->password_authentication = 1;
94ec8c6b 908 if (options->kbd_interactive_authentication == -1)
d464095c 909 options->kbd_interactive_authentication = 1;
5260325f 910 if (options->rhosts_rsa_authentication == -1)
4b3d23b4 911 options->rhosts_rsa_authentication = 0;
8002af61 912 if (options->hostbased_authentication == -1)
913 options->hostbased_authentication = 0;
5260325f 914 if (options->batch_mode == -1)
915 options->batch_mode = 0;
916 if (options->check_host_ip == -1)
917 options->check_host_ip = 1;
918 if (options->strict_host_key_checking == -1)
919 options->strict_host_key_checking = 2; /* 2 is default */
920 if (options->compression == -1)
921 options->compression = 0;
922 if (options->keepalives == -1)
923 options->keepalives = 1;
924 if (options->compression_level == -1)
925 options->compression_level = 6;
926 if (options->port == -1)
927 options->port = 0; /* Filled in ssh_connect. */
1572b90f 928 if (options->address_family == -1)
929 options->address_family = AF_UNSPEC;
5260325f 930 if (options->connection_attempts == -1)
ce773142 931 options->connection_attempts = 1;
5260325f 932 if (options->number_of_password_prompts == -1)
933 options->number_of_password_prompts = 3;
934 /* Selected in ssh_login(). */
935 if (options->cipher == -1)
936 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 937 /* options->ciphers, default set in myproposals.h */
b2552997 938 /* options->macs, default set in myproposals.h */
e961a8f9 939 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 940 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 941 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 942 if (options->num_identity_files == 0) {
fa08c86b 943 if (options->protocol & SSH_PROTO_1) {
d2c46e77 944 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 945 options->identity_files[options->num_identity_files] =
d2c46e77 946 xmalloc(len);
947 snprintf(options->identity_files[options->num_identity_files++],
948 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 949 }
950 if (options->protocol & SSH_PROTO_2) {
ec63b02d 951 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
952 options->identity_files[options->num_identity_files] =
953 xmalloc(len);
954 snprintf(options->identity_files[options->num_identity_files++],
955 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
956
d2c46e77 957 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 958 options->identity_files[options->num_identity_files] =
d2c46e77 959 xmalloc(len);
960 snprintf(options->identity_files[options->num_identity_files++],
961 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 962 }
a306f2dd 963 }
5260325f 964 if (options->escape_char == -1)
965 options->escape_char = '~';
966 if (options->system_hostfile == NULL)
42f11eb2 967 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 968 if (options->user_hostfile == NULL)
42f11eb2 969 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 970 if (options->system_hostfile2 == NULL)
42f11eb2 971 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 972 if (options->user_hostfile2 == NULL)
42f11eb2 973 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5eaf8578 974 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 975 options->log_level = SYSLOG_LEVEL_INFO;
e1c5bfaf 976 if (options->clear_forwardings == 1)
977 clear_forwardings(options);
8bbc048a 978 if (options->no_host_authentication_for_localhost == - 1)
979 options->no_host_authentication_for_localhost = 0;
cc46e2ee 980 if (options->enable_ssh_keysign == -1)
981 options->enable_ssh_keysign = 0;
ffd7b36b 982 if (options->rekey_limit == -1)
983 options->rekey_limit = 0;
21289cd0 984 if (options->verify_host_key_dns == -1)
985 options->verify_host_key_dns = 0;
5260325f 986 /* options->proxy_command should not be set by default */
987 /* options->user will be set in the main program if appropriate */
988 /* options->hostname will be set in the main program if appropriate */
8abcdba4 989 /* options->host_key_alias should not be set by default */
cab80f75 990 /* options->preferred_authentications will be set in ssh */
8efc0c15 991}
This page took 0.352473 seconds and 5 git commands to generate.