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