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