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