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