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