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