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