]> andersk Git - openssh.git/blame - readconf.c
- (dtucker) [auth-pam.c scard-opensc.c] Tinderbox says auth-pam.c uses
[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"
61a2c1da 15RCSID("$OpenBSD: readconf.c,v 1.130 2004/04/27 09:46:36 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,
61a2c1da 109 oSendEnv,
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 },
17a3011c 198 { NULL, oBadOption }
6a17f9c2 199};
200
aa3378df 201/*
202 * Adds a local TCP/IP port forward to options. Never returns if there is an
203 * error.
204 */
8efc0c15 205
6ae2364d 206void
57112b5a 207add_local_forward(Options *options, u_short port, const char *host,
208 u_short host_port)
8efc0c15 209{
5260325f 210 Forward *fwd;
e6f15ed1 211#ifndef NO_IPPORT_RESERVED_CONCEPT
5260325f 212 extern uid_t original_real_uid;
5260325f 213 if (port < IPPORT_RESERVED && original_real_uid != 0)
54b974dc 214 fatal("Privileged ports can only be forwarded by root.");
3c62e7eb 215#endif
5260325f 216 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
217 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
218 fwd = &options->local_forwards[options->num_local_forwards++];
219 fwd->port = port;
220 fwd->host = xstrdup(host);
221 fwd->host_port = host_port;
8efc0c15 222}
223
aa3378df 224/*
225 * Adds a remote TCP/IP port forward to options. Never returns if there is
226 * an error.
227 */
8efc0c15 228
6ae2364d 229void
57112b5a 230add_remote_forward(Options *options, u_short port, const char *host,
231 u_short host_port)
8efc0c15 232{
5260325f 233 Forward *fwd;
234 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
235 fatal("Too many remote forwards (max %d).",
184eed6a 236 SSH_MAX_FORWARDS_PER_DIRECTION);
5260325f 237 fwd = &options->remote_forwards[options->num_remote_forwards++];
238 fwd->port = port;
239 fwd->host = xstrdup(host);
240 fwd->host_port = host_port;
8efc0c15 241}
242
e1c5bfaf 243static void
244clear_forwardings(Options *options)
245{
246 int i;
247
248 for (i = 0; i < options->num_local_forwards; i++)
249 xfree(options->local_forwards[i].host);
250 options->num_local_forwards = 0;
251 for (i = 0; i < options->num_remote_forwards; i++)
252 xfree(options->remote_forwards[i].host);
253 options->num_remote_forwards = 0;
254}
255
aa3378df 256/*
6be9a5e8 257 * Returns the number of the token pointed to by cp or oBadOption.
aa3378df 258 */
8efc0c15 259
6ae2364d 260static OpCodes
5260325f 261parse_token(const char *cp, const char *filename, int linenum)
8efc0c15 262{
1e3b8b07 263 u_int i;
8efc0c15 264
5260325f 265 for (i = 0; keywords[i].name; i++)
aa3378df 266 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 267 return keywords[i].opcode;
8efc0c15 268
b7c70970 269 error("%s: line %d: Bad configuration option: %s",
270 filename, linenum, cp);
5260325f 271 return oBadOption;
8efc0c15 272}
273
aa3378df 274/*
275 * Processes a single option line as used in the configuration files. This
276 * only sets those values that have not already been set.
277 */
d718e75d 278#define WHITESPACE " \t\r\n"
8efc0c15 279
e7c0f9d5 280int
281process_config_line(Options *options, const char *host,
5260325f 282 char *line, const char *filename, int linenum,
283 int *activep)
8efc0c15 284{
d718e75d 285 char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
57112b5a 286 int opcode, *intptr, value;
d718e75d 287 size_t len;
57112b5a 288 u_short fwd_port, fwd_host_port;
3a8aabf0 289 char sfwd_host_port[6];
5260325f 290
204fde99 291 /* Strip trailing whitespace */
292 for(len = strlen(line) - 1; len > 0; len--) {
293 if (strchr(WHITESPACE, line[len]) == NULL)
294 break;
295 line[len] = '\0';
296 }
297
704b1659 298 s = line;
299 /* Get the keyword. (Each line is supposed to begin with a keyword). */
300 keyword = strdelim(&s);
301 /* Ignore leading whitespace. */
302 if (*keyword == '\0')
303 keyword = strdelim(&s);
42f11eb2 304 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 305 return 0;
306
089fbbd2 307 opcode = parse_token(keyword, filename, linenum);
5260325f 308
309 switch (opcode) {
310 case oBadOption:
aa3378df 311 /* don't panic, but count bad options */
312 return -1;
5260325f 313 /* NOTREACHED */
09ab3296 314 case oConnectTimeout:
315 intptr = &options->connection_timeout;
5d8d32a3 316parse_time:
09ab3296 317 arg = strdelim(&s);
318 if (!arg || *arg == '\0')
319 fatal("%s line %d: missing time value.",
320 filename, linenum);
321 if ((value = convtime(arg)) == -1)
322 fatal("%s line %d: invalid time value.",
323 filename, linenum);
324 if (*intptr == -1)
325 *intptr = value;
326 break;
327
5260325f 328 case oForwardAgent:
329 intptr = &options->forward_agent;
330parse_flag:
704b1659 331 arg = strdelim(&s);
089fbbd2 332 if (!arg || *arg == '\0')
5260325f 333 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
334 value = 0; /* To avoid compiler warning... */
089fbbd2 335 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 336 value = 1;
089fbbd2 337 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 338 value = 0;
339 else
340 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
341 if (*activep && *intptr == -1)
342 *intptr = value;
343 break;
344
345 case oForwardX11:
346 intptr = &options->forward_x11;
347 goto parse_flag;
348
d73a67d7 349 case oForwardX11Trusted:
350 intptr = &options->forward_x11_trusted;
351 goto parse_flag;
352
5260325f 353 case oGatewayPorts:
354 intptr = &options->gateway_ports;
355 goto parse_flag;
356
357 case oUsePrivilegedPort:
358 intptr = &options->use_privileged_port;
359 goto parse_flag;
360
5260325f 361 case oPasswordAuthentication:
362 intptr = &options->password_authentication;
363 goto parse_flag;
364
94ec8c6b 365 case oKbdInteractiveAuthentication:
366 intptr = &options->kbd_interactive_authentication;
367 goto parse_flag;
368
369 case oKbdInteractiveDevices:
370 charptr = &options->kbd_interactive_devices;
371 goto parse_string;
372
fa08c86b 373 case oPubkeyAuthentication:
374 intptr = &options->pubkey_authentication;
1d1ffb87 375 goto parse_flag;
376
5260325f 377 case oRSAAuthentication:
378 intptr = &options->rsa_authentication;
379 goto parse_flag;
380
381 case oRhostsRSAAuthentication:
382 intptr = &options->rhosts_rsa_authentication;
383 goto parse_flag;
384
8002af61 385 case oHostbasedAuthentication:
386 intptr = &options->hostbased_authentication;
387 goto parse_flag;
388
d464095c 389 case oChallengeResponseAuthentication:
5ba55ada 390 intptr = &options->challenge_response_authentication;
5260325f 391 goto parse_flag;
d0ec7f42 392
7364bd04 393 case oGssAuthentication:
394 intptr = &options->gss_authentication;
395 goto parse_flag;
396
397 case oGssDelegateCreds:
398 intptr = &options->gss_deleg_creds;
399 goto parse_flag;
400
5260325f 401 case oBatchMode:
402 intptr = &options->batch_mode;
403 goto parse_flag;
404
405 case oCheckHostIP:
406 intptr = &options->check_host_ip;
407 goto parse_flag;
408
21289cd0 409 case oVerifyHostKeyDNS:
410 intptr = &options->verify_host_key_dns;
0161a13d 411 goto parse_yesnoask;
21289cd0 412
5260325f 413 case oStrictHostKeyChecking:
414 intptr = &options->strict_host_key_checking;
0161a13d 415parse_yesnoask:
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
fd573618 437 case oTCPKeepAlive:
438 intptr = &options->tcp_keep_alive;
5260325f 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
3a065ed0 742 case oIdentitiesOnly:
743 intptr = &options->identities_only;
744 goto parse_flag;
745
5d8d32a3 746 case oServerAliveInterval:
747 intptr = &options->server_alive_interval;
748 goto parse_time;
749
750 case oServerAliveCountMax:
751 intptr = &options->server_alive_count_max;
752 goto parse_int;
753
61a2c1da 754 case oSendEnv:
755 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
756 if (strchr(arg, '=') != NULL)
757 fatal("%s line %d: Invalid environment name.",
758 filename, linenum);
759 if (options->num_send_env >= MAX_SEND_ENV)
760 fatal("%s line %d: too many send env.",
761 filename, linenum);
762 options->send_env[options->num_send_env++] =
763 xstrdup(arg);
764 }
765 break;
766
80fcb74e 767 case oDeprecated:
4feae93d 768 debug("%s line %d: Deprecated option \"%s\"",
80fcb74e 769 filename, linenum, keyword);
4feae93d 770 return 0;
80fcb74e 771
a2144546 772 case oUnsupported:
773 error("%s line %d: Unsupported option \"%s\"",
774 filename, linenum, keyword);
775 return 0;
776
5260325f 777 default:
778 fatal("process_config_line: Unimplemented opcode %d", opcode);
779 }
780
781 /* Check that there is no garbage at end of line. */
42f11eb2 782 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 783 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
184eed6a 784 filename, linenum, arg);
089fbbd2 785 }
5260325f 786 return 0;
8efc0c15 787}
788
789
aa3378df 790/*
791 * Reads the config file and modifies the options accordingly. Options
792 * should already be initialized before this call. This never returns if
93111dfa 793 * there is an error. If the file does not exist, this returns 0.
aa3378df 794 */
8efc0c15 795
93111dfa 796int
9f6cab4b 797read_config_file(const char *filename, const char *host, Options *options,
798 int checkperm)
8efc0c15 799{
5260325f 800 FILE *f;
801 char line[1024];
802 int active, linenum;
803 int bad_options = 0;
804
805 /* Open the file. */
9f6cab4b 806 if ((f = fopen(filename, "r")) == NULL)
93111dfa 807 return 0;
5260325f 808
9f6cab4b 809 if (checkperm) {
810 struct stat sb;
811
812 if (fstat(fileno(f), &sb) == -1) {
813 fatal("fstat %s: %s", filename, strerror(errno));
814 fclose(f);
815 return (0);
816 }
817 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
818 (sb.st_mode & 022) != 0)) {
819 fatal("Bad owner or permissions on %s", filename);
820 return 0;
821 }
822 }
823
5260325f 824 debug("Reading configuration data %.200s", filename);
825
aa3378df 826 /*
827 * Mark that we are now processing the options. This flag is turned
828 * on/off by Host specifications.
829 */
5260325f 830 active = 1;
831 linenum = 0;
832 while (fgets(line, sizeof(line), f)) {
833 /* Update line number counter. */
834 linenum++;
835 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
836 bad_options++;
837 }
838 fclose(f);
839 if (bad_options > 0)
54b974dc 840 fatal("%s: terminating, %d bad configuration options",
184eed6a 841 filename, bad_options);
93111dfa 842 return 1;
8efc0c15 843}
844
aa3378df 845/*
846 * Initializes options to special values that indicate that they have not yet
847 * been set. Read_config_file will only set options with this value. Options
848 * are processed in the following order: command line, user config file,
849 * system config file. Last, fill_default_options is called.
850 */
8efc0c15 851
6ae2364d 852void
5260325f 853initialize_options(Options * options)
8efc0c15 854{
5260325f 855 memset(options, 'X', sizeof(*options));
856 options->forward_agent = -1;
857 options->forward_x11 = -1;
d73a67d7 858 options->forward_x11_trusted = -1;
fa649821 859 options->xauth_location = NULL;
5260325f 860 options->gateway_ports = -1;
861 options->use_privileged_port = -1;
5260325f 862 options->rsa_authentication = -1;
fa08c86b 863 options->pubkey_authentication = -1;
5ba55ada 864 options->challenge_response_authentication = -1;
7364bd04 865 options->gss_authentication = -1;
866 options->gss_deleg_creds = -1;
5260325f 867 options->password_authentication = -1;
94ec8c6b 868 options->kbd_interactive_authentication = -1;
869 options->kbd_interactive_devices = NULL;
5260325f 870 options->rhosts_rsa_authentication = -1;
8002af61 871 options->hostbased_authentication = -1;
5260325f 872 options->batch_mode = -1;
873 options->check_host_ip = -1;
874 options->strict_host_key_checking = -1;
875 options->compression = -1;
fd573618 876 options->tcp_keep_alive = -1;
5260325f 877 options->compression_level = -1;
878 options->port = -1;
1572b90f 879 options->address_family = -1;
5260325f 880 options->connection_attempts = -1;
09ab3296 881 options->connection_timeout = -1;
5260325f 882 options->number_of_password_prompts = -1;
883 options->cipher = -1;
a8be9f80 884 options->ciphers = NULL;
b2552997 885 options->macs = NULL;
e961a8f9 886 options->hostkeyalgorithms = NULL;
a8be9f80 887 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 888 options->num_identity_files = 0;
889 options->hostname = NULL;
8abcdba4 890 options->host_key_alias = NULL;
5260325f 891 options->proxy_command = NULL;
892 options->user = NULL;
893 options->escape_char = -1;
894 options->system_hostfile = NULL;
895 options->user_hostfile = NULL;
a306f2dd 896 options->system_hostfile2 = NULL;
897 options->user_hostfile2 = NULL;
5260325f 898 options->num_local_forwards = 0;
899 options->num_remote_forwards = 0;
e1c5bfaf 900 options->clear_forwardings = -1;
5eaf8578 901 options->log_level = SYSLOG_LEVEL_NOT_SET;
cab80f75 902 options->preferred_authentications = NULL;
3435f5a6 903 options->bind_address = NULL;
9ff6f66f 904 options->smartcard_device = NULL;
cc46e2ee 905 options->enable_ssh_keysign = - 1;
8bbc048a 906 options->no_host_authentication_for_localhost = - 1;
3a065ed0 907 options->identities_only = - 1;
ffd7b36b 908 options->rekey_limit = - 1;
21289cd0 909 options->verify_host_key_dns = -1;
5d8d32a3 910 options->server_alive_interval = -1;
911 options->server_alive_count_max = -1;
61a2c1da 912 options->num_send_env = 0;
8efc0c15 913}
914
aa3378df 915/*
916 * Called after processing other sources of option data, this fills those
917 * options for which no value has been specified with their default values.
918 */
8efc0c15 919
6ae2364d 920void
5260325f 921fill_default_options(Options * options)
8efc0c15 922{
d2c46e77 923 int len;
924
5260325f 925 if (options->forward_agent == -1)
71276795 926 options->forward_agent = 0;
5260325f 927 if (options->forward_x11 == -1)
c8d54615 928 options->forward_x11 = 0;
d73a67d7 929 if (options->forward_x11_trusted == -1)
930 options->forward_x11_trusted = 0;
fa649821 931 if (options->xauth_location == NULL)
fd9ede94 932 options->xauth_location = _PATH_XAUTH;
5260325f 933 if (options->gateway_ports == -1)
934 options->gateway_ports = 0;
935 if (options->use_privileged_port == -1)
d5ebca2b 936 options->use_privileged_port = 0;
5260325f 937 if (options->rsa_authentication == -1)
938 options->rsa_authentication = 1;
fa08c86b 939 if (options->pubkey_authentication == -1)
940 options->pubkey_authentication = 1;
5ba55ada 941 if (options->challenge_response_authentication == -1)
10a2cbef 942 options->challenge_response_authentication = 1;
7364bd04 943 if (options->gss_authentication == -1)
2ecb78df 944 options->gss_authentication = 0;
7364bd04 945 if (options->gss_deleg_creds == -1)
946 options->gss_deleg_creds = 0;
5260325f 947 if (options->password_authentication == -1)
948 options->password_authentication = 1;
94ec8c6b 949 if (options->kbd_interactive_authentication == -1)
d464095c 950 options->kbd_interactive_authentication = 1;
5260325f 951 if (options->rhosts_rsa_authentication == -1)
4b3d23b4 952 options->rhosts_rsa_authentication = 0;
8002af61 953 if (options->hostbased_authentication == -1)
954 options->hostbased_authentication = 0;
5260325f 955 if (options->batch_mode == -1)
956 options->batch_mode = 0;
957 if (options->check_host_ip == -1)
958 options->check_host_ip = 1;
959 if (options->strict_host_key_checking == -1)
960 options->strict_host_key_checking = 2; /* 2 is default */
961 if (options->compression == -1)
962 options->compression = 0;
fd573618 963 if (options->tcp_keep_alive == -1)
964 options->tcp_keep_alive = 1;
5260325f 965 if (options->compression_level == -1)
966 options->compression_level = 6;
967 if (options->port == -1)
968 options->port = 0; /* Filled in ssh_connect. */
1572b90f 969 if (options->address_family == -1)
970 options->address_family = AF_UNSPEC;
5260325f 971 if (options->connection_attempts == -1)
ce773142 972 options->connection_attempts = 1;
5260325f 973 if (options->number_of_password_prompts == -1)
974 options->number_of_password_prompts = 3;
975 /* Selected in ssh_login(). */
976 if (options->cipher == -1)
977 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 978 /* options->ciphers, default set in myproposals.h */
b2552997 979 /* options->macs, default set in myproposals.h */
e961a8f9 980 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 981 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 982 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 983 if (options->num_identity_files == 0) {
fa08c86b 984 if (options->protocol & SSH_PROTO_1) {
d2c46e77 985 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 986 options->identity_files[options->num_identity_files] =
d2c46e77 987 xmalloc(len);
988 snprintf(options->identity_files[options->num_identity_files++],
989 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 990 }
991 if (options->protocol & SSH_PROTO_2) {
ec63b02d 992 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
993 options->identity_files[options->num_identity_files] =
994 xmalloc(len);
995 snprintf(options->identity_files[options->num_identity_files++],
996 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
997
d2c46e77 998 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 999 options->identity_files[options->num_identity_files] =
d2c46e77 1000 xmalloc(len);
1001 snprintf(options->identity_files[options->num_identity_files++],
1002 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 1003 }
a306f2dd 1004 }
5260325f 1005 if (options->escape_char == -1)
1006 options->escape_char = '~';
1007 if (options->system_hostfile == NULL)
42f11eb2 1008 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 1009 if (options->user_hostfile == NULL)
42f11eb2 1010 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 1011 if (options->system_hostfile2 == NULL)
42f11eb2 1012 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 1013 if (options->user_hostfile2 == NULL)
42f11eb2 1014 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5eaf8578 1015 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 1016 options->log_level = SYSLOG_LEVEL_INFO;
e1c5bfaf 1017 if (options->clear_forwardings == 1)
1018 clear_forwardings(options);
8bbc048a 1019 if (options->no_host_authentication_for_localhost == - 1)
1020 options->no_host_authentication_for_localhost = 0;
3a065ed0 1021 if (options->identities_only == -1)
1022 options->identities_only = 0;
cc46e2ee 1023 if (options->enable_ssh_keysign == -1)
1024 options->enable_ssh_keysign = 0;
ffd7b36b 1025 if (options->rekey_limit == -1)
1026 options->rekey_limit = 0;
21289cd0 1027 if (options->verify_host_key_dns == -1)
1028 options->verify_host_key_dns = 0;
5d8d32a3 1029 if (options->server_alive_interval == -1)
1030 options->server_alive_interval = 0;
1031 if (options->server_alive_count_max == -1)
1032 options->server_alive_count_max = 3;
5260325f 1033 /* options->proxy_command should not be set by default */
1034 /* options->user will be set in the main program if appropriate */
1035 /* options->hostname will be set in the main program if appropriate */
8abcdba4 1036 /* options->host_key_alias should not be set by default */
cab80f75 1037 /* options->preferred_authentications will be set in ssh */
8efc0c15 1038}
This page took 0.506426 seconds and 5 git commands to generate.