]> andersk Git - gssapi-openssh.git/blame - openssh/readconf.c
Import of OpenSSH 4.0p1
[gssapi-openssh.git] / openssh / readconf.c
CommitLineData
3c0ef626 1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Functions for reading the configuration files.
6 *
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".
12 */
13
14#include "includes.h"
996d5e62 15RCSID("$OpenBSD: readconf.c,v 1.137 2005/03/04 08:48:06 djm Exp $");
3c0ef626 16
17#include "ssh.h"
18#include "xmalloc.h"
19#include "compat.h"
20#include "cipher.h"
21#include "pathnames.h"
22#include "log.h"
23#include "readconf.h"
24#include "match.h"
25#include "misc.h"
26#include "kex.h"
27#include "mac.h"
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
f5799ae1 44 User foo
3c0ef626 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
3c0ef626 60 PasswordAuthentication no
61
62 Host puukko.hut.fi
63 User t35124p
64 ProxyCommand ssh-proxy %h %p
65
66 Host *.fr
f5799ae1 67 PublicKeyAuthentication no
3c0ef626 68
69 Host *.su
70 Cipher none
71 PasswordAuthentication no
72
73 # Defaults for various options
74 Host *
75 ForwardAgent no
76 ForwardX11 no
3c0ef626 77 PasswordAuthentication yes
78 RSAAuthentication yes
79 RhostsRSAAuthentication yes
3c0ef626 80 StrictHostKeyChecking yes
cdd66111 81 TcpKeepAlive no
3c0ef626 82 IdentityFile ~/.ssh/identity
83 Port 22
84 EscapeChar ~
85
86*/
87
88/* Keyword tokens. */
89
90typedef enum {
91 oBadOption,
cdd66111 92 oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
f5799ae1 93 oPasswordAuthentication, oRSAAuthentication,
3c0ef626 94 oChallengeResponseAuthentication, oXAuthLocation,
3c0ef626 95 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
96 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
97 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
98 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
cdd66111 99 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
3c0ef626 100 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
101 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
102 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
103 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
104 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
f5799ae1 105 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
0fff78ff 106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
99be0775 108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
996d5e62 109 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
0fff78ff 110 oDeprecated, oUnsupported
3c0ef626 111} OpCodes;
112
113/* Textual representations of the tokens. */
114
115static struct {
116 const char *name;
117 OpCodes opcode;
118} keywords[] = {
119 { "forwardagent", oForwardAgent },
120 { "forwardx11", oForwardX11 },
cdd66111 121 { "forwardx11trusted", oForwardX11Trusted },
3c0ef626 122 { "xauthlocation", oXAuthLocation },
123 { "gatewayports", oGatewayPorts },
124 { "useprivilegedport", oUsePrivilegedPort },
0fff78ff 125 { "rhostsauthentication", oDeprecated },
3c0ef626 126 { "passwordauthentication", oPasswordAuthentication },
127 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
128 { "kbdinteractivedevices", oKbdInteractiveDevices },
129 { "rsaauthentication", oRSAAuthentication },
130 { "pubkeyauthentication", oPubkeyAuthentication },
131 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
132 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
133 { "hostbasedauthentication", oHostbasedAuthentication },
134 { "challengeresponseauthentication", oChallengeResponseAuthentication },
135 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
136 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
0fff78ff 137 { "kerberosauthentication", oUnsupported },
138 { "kerberostgtpassing", oUnsupported },
139 { "afstokenpassing", oUnsupported },
140#if defined(GSSAPI)
141 { "gssapiauthentication", oGssAuthentication },
142 { "gssapidelegatecredentials", oGssDelegateCreds },
143#else
144 { "gssapiauthentication", oUnsupported },
145 { "gssapidelegatecredentials", oUnsupported },
3c0ef626 146#endif
f5799ae1 147 { "fallbacktorsh", oDeprecated },
148 { "usersh", oDeprecated },
3c0ef626 149 { "identityfile", oIdentityFile },
150 { "identityfile2", oIdentityFile }, /* alias */
99be0775 151 { "identitiesonly", oIdentitiesOnly },
3c0ef626 152 { "hostname", oHostName },
153 { "hostkeyalias", oHostKeyAlias },
154 { "proxycommand", oProxyCommand },
155 { "port", oPort },
156 { "cipher", oCipher },
157 { "ciphers", oCiphers },
158 { "macs", oMacs },
159 { "protocol", oProtocol },
160 { "remoteforward", oRemoteForward },
161 { "localforward", oLocalForward },
162 { "user", oUser },
163 { "host", oHost },
164 { "escapechar", oEscapeChar },
165 { "globalknownhostsfile", oGlobalKnownHostsFile },
166 { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */
167 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
168 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
169 { "connectionattempts", oConnectionAttempts },
170 { "batchmode", oBatchMode },
171 { "checkhostip", oCheckHostIP },
172 { "stricthostkeychecking", oStrictHostKeyChecking },
173 { "compression", oCompression },
174 { "compressionlevel", oCompressionLevel },
cdd66111 175 { "tcpkeepalive", oTCPKeepAlive },
176 { "keepalive", oTCPKeepAlive }, /* obsolete */
3c0ef626 177 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
178 { "loglevel", oLogLevel },
179 { "dynamicforward", oDynamicForward },
180 { "preferredauthentications", oPreferredAuthentications },
181 { "hostkeyalgorithms", oHostKeyAlgorithms },
182 { "bindaddress", oBindAddress },
0fff78ff 183#ifdef SMARTCARD
3c0ef626 184 { "smartcarddevice", oSmartcardDevice },
0fff78ff 185#else
186 { "smartcarddevice", oUnsupported },
187#endif
e9a17296 188 { "clearallforwardings", oClearAllForwardings },
6a9b3198 189 { "enablesshkeysign", oEnableSSHKeysign },
0fff78ff 190 { "verifyhostkeydns", oVerifyHostKeyDNS },
e9a17296 191 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
0fff78ff 192 { "rekeylimit", oRekeyLimit },
193 { "connecttimeout", oConnectTimeout },
194 { "addressfamily", oAddressFamily },
cdd66111 195 { "serveraliveinterval", oServerAliveInterval },
196 { "serveralivecountmax", oServerAliveCountMax },
c9f39d2c 197 { "sendenv", oSendEnv },
198 { "controlpath", oControlPath },
199 { "controlmaster", oControlMaster },
996d5e62 200 { "hashknownhosts", oHashKnownHosts },
e9a17296 201 { NULL, oBadOption }
3c0ef626 202};
203
204/*
205 * Adds a local TCP/IP port forward to options. Never returns if there is an
206 * error.
207 */
208
209void
996d5e62 210add_local_forward(Options *options, const Forward *newfwd)
3c0ef626 211{
212 Forward *fwd;
41b2f314 213#ifndef NO_IPPORT_RESERVED_CONCEPT
3c0ef626 214 extern uid_t original_real_uid;
996d5e62 215 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
3c0ef626 216 fatal("Privileged ports can only be forwarded by root.");
217#endif
218 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
219 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
220 fwd = &options->local_forwards[options->num_local_forwards++];
996d5e62 221
222 fwd->listen_host = (newfwd->listen_host == NULL) ?
223 NULL : xstrdup(newfwd->listen_host);
224 fwd->listen_port = newfwd->listen_port;
225 fwd->connect_host = xstrdup(newfwd->connect_host);
226 fwd->connect_port = newfwd->connect_port;
3c0ef626 227}
228
229/*
230 * Adds a remote TCP/IP port forward to options. Never returns if there is
231 * an error.
232 */
233
234void
996d5e62 235add_remote_forward(Options *options, const Forward *newfwd)
3c0ef626 236{
237 Forward *fwd;
238 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
239 fatal("Too many remote forwards (max %d).",
e9a17296 240 SSH_MAX_FORWARDS_PER_DIRECTION);
3c0ef626 241 fwd = &options->remote_forwards[options->num_remote_forwards++];
996d5e62 242
243 fwd->listen_host = (newfwd->listen_host == NULL) ?
244 NULL : xstrdup(newfwd->listen_host);
245 fwd->listen_port = newfwd->listen_port;
246 fwd->connect_host = xstrdup(newfwd->connect_host);
247 fwd->connect_port = newfwd->connect_port;
3c0ef626 248}
249
250static void
251clear_forwardings(Options *options)
252{
253 int i;
254
996d5e62 255 for (i = 0; i < options->num_local_forwards; i++) {
256 xfree(options->local_forwards[i].listen_host);
257 xfree(options->local_forwards[i].connect_host);
258 }
3c0ef626 259 options->num_local_forwards = 0;
996d5e62 260 for (i = 0; i < options->num_remote_forwards; i++) {
261 xfree(options->remote_forwards[i].listen_host);
262 xfree(options->remote_forwards[i].connect_host);
263 }
3c0ef626 264 options->num_remote_forwards = 0;
265}
266
267/*
268 * Returns the number of the token pointed to by cp or oBadOption.
269 */
270
271static OpCodes
272parse_token(const char *cp, const char *filename, int linenum)
273{
274 u_int i;
275
276 for (i = 0; keywords[i].name; i++)
277 if (strcasecmp(cp, keywords[i].name) == 0)
278 return keywords[i].opcode;
279
280 error("%s: line %d: Bad configuration option: %s",
281 filename, linenum, cp);
282 return oBadOption;
283}
284
285/*
286 * Processes a single option line as used in the configuration files. This
287 * only sets those values that have not already been set.
288 */
6a9b3198 289#define WHITESPACE " \t\r\n"
3c0ef626 290
291int
292process_config_line(Options *options, const char *host,
293 char *line, const char *filename, int linenum,
294 int *activep)
295{
996d5e62 296 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
3c0ef626 297 int opcode, *intptr, value;
6a9b3198 298 size_t len;
996d5e62 299 Forward fwd;
3c0ef626 300
0fff78ff 301 /* Strip trailing whitespace */
302 for(len = strlen(line) - 1; len > 0; len--) {
303 if (strchr(WHITESPACE, line[len]) == NULL)
304 break;
305 line[len] = '\0';
306 }
307
3c0ef626 308 s = line;
309 /* Get the keyword. (Each line is supposed to begin with a keyword). */
310 keyword = strdelim(&s);
311 /* Ignore leading whitespace. */
312 if (*keyword == '\0')
313 keyword = strdelim(&s);
314 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
315 return 0;
316
317 opcode = parse_token(keyword, filename, linenum);
318
319 switch (opcode) {
320 case oBadOption:
321 /* don't panic, but count bad options */
322 return -1;
323 /* NOTREACHED */
0fff78ff 324 case oConnectTimeout:
325 intptr = &options->connection_timeout;
cdd66111 326parse_time:
0fff78ff 327 arg = strdelim(&s);
328 if (!arg || *arg == '\0')
329 fatal("%s line %d: missing time value.",
330 filename, linenum);
331 if ((value = convtime(arg)) == -1)
332 fatal("%s line %d: invalid time value.",
333 filename, linenum);
334 if (*intptr == -1)
335 *intptr = value;
336 break;
337
3c0ef626 338 case oForwardAgent:
339 intptr = &options->forward_agent;
340parse_flag:
341 arg = strdelim(&s);
342 if (!arg || *arg == '\0')
343 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
344 value = 0; /* To avoid compiler warning... */
345 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
346 value = 1;
347 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
348 value = 0;
349 else
350 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
351 if (*activep && *intptr == -1)
352 *intptr = value;
353 break;
354
355 case oForwardX11:
356 intptr = &options->forward_x11;
357 goto parse_flag;
358
cdd66111 359 case oForwardX11Trusted:
360 intptr = &options->forward_x11_trusted;
361 goto parse_flag;
362
3c0ef626 363 case oGatewayPorts:
364 intptr = &options->gateway_ports;
365 goto parse_flag;
366
367 case oUsePrivilegedPort:
368 intptr = &options->use_privileged_port;
369 goto parse_flag;
370
3c0ef626 371 case oPasswordAuthentication:
372 intptr = &options->password_authentication;
373 goto parse_flag;
374
375 case oKbdInteractiveAuthentication:
376 intptr = &options->kbd_interactive_authentication;
377 goto parse_flag;
378
379 case oKbdInteractiveDevices:
380 charptr = &options->kbd_interactive_devices;
381 goto parse_string;
382
383 case oPubkeyAuthentication:
384 intptr = &options->pubkey_authentication;
385 goto parse_flag;
386
387 case oRSAAuthentication:
388 intptr = &options->rsa_authentication;
389 goto parse_flag;
390
391 case oRhostsRSAAuthentication:
392 intptr = &options->rhosts_rsa_authentication;
393 goto parse_flag;
394
395 case oHostbasedAuthentication:
396 intptr = &options->hostbased_authentication;
397 goto parse_flag;
398
399 case oChallengeResponseAuthentication:
400 intptr = &options->challenge_response_authentication;
401 goto parse_flag;
0fff78ff 402
403 case oGssAuthentication:
404 intptr = &options->gss_authentication;
3c0ef626 405 goto parse_flag;
0fff78ff 406
407 case oGssDelegateCreds:
408 intptr = &options->gss_deleg_creds;
3c0ef626 409 goto parse_flag;
0fff78ff 410
3c0ef626 411 case oBatchMode:
412 intptr = &options->batch_mode;
413 goto parse_flag;
414
415 case oCheckHostIP:
416 intptr = &options->check_host_ip;
417 goto parse_flag;
418
0fff78ff 419 case oVerifyHostKeyDNS:
420 intptr = &options->verify_host_key_dns;
cdd66111 421 goto parse_yesnoask;
0fff78ff 422
3c0ef626 423 case oStrictHostKeyChecking:
424 intptr = &options->strict_host_key_checking;
cdd66111 425parse_yesnoask:
3c0ef626 426 arg = strdelim(&s);
427 if (!arg || *arg == '\0')
428 fatal("%.200s line %d: Missing yes/no/ask argument.",
e9a17296 429 filename, linenum);
3c0ef626 430 value = 0; /* To avoid compiler warning... */
431 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
432 value = 1;
433 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
434 value = 0;
435 else if (strcmp(arg, "ask") == 0)
436 value = 2;
437 else
438 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
439 if (*activep && *intptr == -1)
440 *intptr = value;
441 break;
442
443 case oCompression:
444 intptr = &options->compression;
445 goto parse_flag;
446
cdd66111 447 case oTCPKeepAlive:
448 intptr = &options->tcp_keep_alive;
3c0ef626 449 goto parse_flag;
450
451 case oNoHostAuthenticationForLocalhost:
452 intptr = &options->no_host_authentication_for_localhost;
453 goto parse_flag;
454
455 case oNumberOfPasswordPrompts:
456 intptr = &options->number_of_password_prompts;
457 goto parse_int;
458
459 case oCompressionLevel:
460 intptr = &options->compression_level;
461 goto parse_int;
462
0fff78ff 463 case oRekeyLimit:
464 intptr = &options->rekey_limit;
465 arg = strdelim(&s);
466 if (!arg || *arg == '\0')
467 fatal("%.200s line %d: Missing argument.", filename, linenum);
468 if (arg[0] < '0' || arg[0] > '9')
469 fatal("%.200s line %d: Bad number.", filename, linenum);
470 value = strtol(arg, &endofnumber, 10);
471 if (arg == endofnumber)
472 fatal("%.200s line %d: Bad number.", filename, linenum);
473 switch (toupper(*endofnumber)) {
474 case 'K':
475 value *= 1<<10;
476 break;
477 case 'M':
478 value *= 1<<20;
479 break;
480 case 'G':
481 value *= 1<<30;
482 break;
483 }
484 if (*activep && *intptr == -1)
485 *intptr = value;
486 break;
487
3c0ef626 488 case oIdentityFile:
489 arg = strdelim(&s);
490 if (!arg || *arg == '\0')
491 fatal("%.200s line %d: Missing argument.", filename, linenum);
492 if (*activep) {
493 intptr = &options->num_identity_files;
494 if (*intptr >= SSH_MAX_IDENTITY_FILES)
495 fatal("%.200s line %d: Too many identity files specified (max %d).",
e9a17296 496 filename, linenum, SSH_MAX_IDENTITY_FILES);
3c0ef626 497 charptr = &options->identity_files[*intptr];
498 *charptr = xstrdup(arg);
499 *intptr = *intptr + 1;
500 }
501 break;
502
503 case oXAuthLocation:
504 charptr=&options->xauth_location;
505 goto parse_string;
506
507 case oUser:
508 charptr = &options->user;
509parse_string:
510 arg = strdelim(&s);
511 if (!arg || *arg == '\0')
512 fatal("%.200s line %d: Missing argument.", filename, linenum);
513 if (*activep && *charptr == NULL)
514 *charptr = xstrdup(arg);
515 break;
516
517 case oGlobalKnownHostsFile:
518 charptr = &options->system_hostfile;
519 goto parse_string;
520
521 case oUserKnownHostsFile:
522 charptr = &options->user_hostfile;
523 goto parse_string;
524
525 case oGlobalKnownHostsFile2:
526 charptr = &options->system_hostfile2;
527 goto parse_string;
528
529 case oUserKnownHostsFile2:
530 charptr = &options->user_hostfile2;
531 goto parse_string;
532
533 case oHostName:
534 charptr = &options->hostname;
535 goto parse_string;
536
537 case oHostKeyAlias:
538 charptr = &options->host_key_alias;
539 goto parse_string;
540
541 case oPreferredAuthentications:
542 charptr = &options->preferred_authentications;
543 goto parse_string;
544
545 case oBindAddress:
546 charptr = &options->bind_address;
547 goto parse_string;
548
549 case oSmartcardDevice:
550 charptr = &options->smartcard_device;
551 goto parse_string;
552
553 case oProxyCommand:
0fff78ff 554 if (s == NULL)
555 fatal("%.200s line %d: Missing argument.", filename, linenum);
3c0ef626 556 charptr = &options->proxy_command;
6a9b3198 557 len = strspn(s, WHITESPACE "=");
3c0ef626 558 if (*activep && *charptr == NULL)
6a9b3198 559 *charptr = xstrdup(s + len);
3c0ef626 560 return 0;
561
562 case oPort:
563 intptr = &options->port;
564parse_int:
565 arg = strdelim(&s);
566 if (!arg || *arg == '\0')
567 fatal("%.200s line %d: Missing argument.", filename, linenum);
568 if (arg[0] < '0' || arg[0] > '9')
569 fatal("%.200s line %d: Bad number.", filename, linenum);
570
571 /* Octal, decimal, or hex format? */
572 value = strtol(arg, &endofnumber, 0);
573 if (arg == endofnumber)
574 fatal("%.200s line %d: Bad number.", filename, linenum);
575 if (*activep && *intptr == -1)
576 *intptr = value;
577 break;
578
579 case oConnectionAttempts:
580 intptr = &options->connection_attempts;
581 goto parse_int;
582
583 case oCipher:
584 intptr = &options->cipher;
585 arg = strdelim(&s);
586 if (!arg || *arg == '\0')
587 fatal("%.200s line %d: Missing argument.", filename, linenum);
588 value = cipher_number(arg);
589 if (value == -1)
590 fatal("%.200s line %d: Bad cipher '%s'.",
e9a17296 591 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 592 if (*activep && *intptr == -1)
593 *intptr = value;
594 break;
595
596 case oCiphers:
597 arg = strdelim(&s);
598 if (!arg || *arg == '\0')
599 fatal("%.200s line %d: Missing argument.", filename, linenum);
600 if (!ciphers_valid(arg))
601 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
e9a17296 602 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 603 if (*activep && options->ciphers == NULL)
604 options->ciphers = xstrdup(arg);
605 break;
606
607 case oMacs:
608 arg = strdelim(&s);
609 if (!arg || *arg == '\0')
610 fatal("%.200s line %d: Missing argument.", filename, linenum);
611 if (!mac_valid(arg))
612 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
e9a17296 613 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 614 if (*activep && options->macs == NULL)
615 options->macs = xstrdup(arg);
616 break;
617
618 case oHostKeyAlgorithms:
619 arg = strdelim(&s);
620 if (!arg || *arg == '\0')
621 fatal("%.200s line %d: Missing argument.", filename, linenum);
622 if (!key_names_valid2(arg))
623 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
e9a17296 624 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 625 if (*activep && options->hostkeyalgorithms == NULL)
626 options->hostkeyalgorithms = xstrdup(arg);
627 break;
628
629 case oProtocol:
630 intptr = &options->protocol;
631 arg = strdelim(&s);
632 if (!arg || *arg == '\0')
633 fatal("%.200s line %d: Missing argument.", filename, linenum);
634 value = proto_spec(arg);
635 if (value == SSH_PROTO_UNKNOWN)
636 fatal("%.200s line %d: Bad protocol spec '%s'.",
e9a17296 637 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 638 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
639 *intptr = value;
640 break;
641
642 case oLogLevel:
643 intptr = (int *) &options->log_level;
644 arg = strdelim(&s);
645 value = log_level_number(arg);
e9a17296 646 if (value == SYSLOG_LEVEL_NOT_SET)
3c0ef626 647 fatal("%.200s line %d: unsupported log level '%s'",
e9a17296 648 filename, linenum, arg ? arg : "<NONE>");
649 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
3c0ef626 650 *intptr = (LogLevel) value;
651 break;
652
653 case oLocalForward:
654 case oRemoteForward:
655 arg = strdelim(&s);
996d5e62 656 if (arg == NULL || *arg == '\0')
3c0ef626 657 fatal("%.200s line %d: Missing port argument.",
658 filename, linenum);
996d5e62 659 arg2 = strdelim(&s);
660 if (arg2 == NULL || *arg2 == '\0')
661 fatal("%.200s line %d: Missing target argument.",
3c0ef626 662 filename, linenum);
996d5e62 663
664 /* construct a string for parse_forward */
665 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
666
667 if (parse_forward(&fwd, fwdarg) == 0)
3c0ef626 668 fatal("%.200s line %d: Bad forwarding specification.",
669 filename, linenum);
996d5e62 670
3c0ef626 671 if (*activep) {
672 if (opcode == oLocalForward)
996d5e62 673 add_local_forward(options, &fwd);
3c0ef626 674 else if (opcode == oRemoteForward)
996d5e62 675 add_remote_forward(options, &fwd);
3c0ef626 676 }
677 break;
678
679 case oDynamicForward:
680 arg = strdelim(&s);
681 if (!arg || *arg == '\0')
682 fatal("%.200s line %d: Missing port argument.",
683 filename, linenum);
996d5e62 684 memset(&fwd, '\0', sizeof(fwd));
685 fwd.connect_host = "socks";
686 fwd.listen_host = hpdelim(&arg);
687 if (fwd.listen_host == NULL ||
688 strlen(fwd.listen_host) >= NI_MAXHOST)
689 fatal("%.200s line %d: Bad forwarding specification.",
690 filename, linenum);
691 if (arg) {
692 fwd.listen_port = a2port(arg);
693 fwd.listen_host = cleanhostname(fwd.listen_host);
694 } else {
695 fwd.listen_port = a2port(fwd.listen_host);
696 fwd.listen_host = "";
697 }
698 if (fwd.listen_port == 0)
3c0ef626 699 fatal("%.200s line %d: Badly formatted port number.",
700 filename, linenum);
701 if (*activep)
996d5e62 702 add_local_forward(options, &fwd);
3c0ef626 703 break;
704
705 case oClearAllForwardings:
706 intptr = &options->clear_forwardings;
707 goto parse_flag;
708
709 case oHost:
710 *activep = 0;
711 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
712 if (match_pattern(host, arg)) {
713 debug("Applying options for %.100s", arg);
714 *activep = 1;
715 break;
716 }
717 /* Avoid garbage check below, as strdelim is done. */
718 return 0;
719
720 case oEscapeChar:
721 intptr = &options->escape_char;
722 arg = strdelim(&s);
723 if (!arg || *arg == '\0')
724 fatal("%.200s line %d: Missing argument.", filename, linenum);
725 if (arg[0] == '^' && arg[2] == 0 &&
726 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
727 value = (u_char) arg[1] & 31;
728 else if (strlen(arg) == 1)
729 value = (u_char) arg[0];
730 else if (strcmp(arg, "none") == 0)
731 value = SSH_ESCAPECHAR_NONE;
732 else {
733 fatal("%.200s line %d: Bad escape character.",
e9a17296 734 filename, linenum);
3c0ef626 735 /* NOTREACHED */
736 value = 0; /* Avoid compiler warning. */
737 }
738 if (*activep && *intptr == -1)
739 *intptr = value;
740 break;
741
0fff78ff 742 case oAddressFamily:
743 arg = strdelim(&s);
744 intptr = &options->address_family;
745 if (strcasecmp(arg, "inet") == 0)
746 value = AF_INET;
747 else if (strcasecmp(arg, "inet6") == 0)
748 value = AF_INET6;
749 else if (strcasecmp(arg, "any") == 0)
750 value = AF_UNSPEC;
751 else
752 fatal("Unsupported AddressFamily \"%s\"", arg);
753 if (*activep && *intptr == -1)
754 *intptr = value;
755 break;
756
6a9b3198 757 case oEnableSSHKeysign:
758 intptr = &options->enable_ssh_keysign;
759 goto parse_flag;
760
99be0775 761 case oIdentitiesOnly:
762 intptr = &options->identities_only;
763 goto parse_flag;
764
cdd66111 765 case oServerAliveInterval:
766 intptr = &options->server_alive_interval;
767 goto parse_time;
768
769 case oServerAliveCountMax:
770 intptr = &options->server_alive_count_max;
771 goto parse_int;
772
c9f39d2c 773 case oSendEnv:
774 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
775 if (strchr(arg, '=') != NULL)
776 fatal("%s line %d: Invalid environment name.",
777 filename, linenum);
996d5e62 778 if (!*activep)
779 continue;
c9f39d2c 780 if (options->num_send_env >= MAX_SEND_ENV)
781 fatal("%s line %d: too many send env.",
782 filename, linenum);
783 options->send_env[options->num_send_env++] =
784 xstrdup(arg);
785 }
786 break;
787
788 case oControlPath:
789 charptr = &options->control_path;
790 goto parse_string;
791
792 case oControlMaster:
793 intptr = &options->control_master;
794 goto parse_yesnoask;
795
996d5e62 796 case oHashKnownHosts:
797 intptr = &options->hash_known_hosts;
798 goto parse_flag;
799
f5799ae1 800 case oDeprecated:
801 debug("%s line %d: Deprecated option \"%s\"",
802 filename, linenum, keyword);
803 return 0;
804
0fff78ff 805 case oUnsupported:
806 error("%s line %d: Unsupported option \"%s\"",
807 filename, linenum, keyword);
808 return 0;
809
3c0ef626 810 default:
811 fatal("process_config_line: Unimplemented opcode %d", opcode);
812 }
813
814 /* Check that there is no garbage at end of line. */
815 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
816 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
e9a17296 817 filename, linenum, arg);
3c0ef626 818 }
819 return 0;
820}
821
822
823/*
824 * Reads the config file and modifies the options accordingly. Options
825 * should already be initialized before this call. This never returns if
826 * there is an error. If the file does not exist, this returns 0.
827 */
828
829int
c9f39d2c 830read_config_file(const char *filename, const char *host, Options *options,
831 int checkperm)
3c0ef626 832{
833 FILE *f;
834 char line[1024];
835 int active, linenum;
836 int bad_options = 0;
837
838 /* Open the file. */
c9f39d2c 839 if ((f = fopen(filename, "r")) == NULL)
3c0ef626 840 return 0;
841
c9f39d2c 842 if (checkperm) {
843 struct stat sb;
844
845 if (fstat(fileno(f), &sb) == -1)
846 fatal("fstat %s: %s", filename, strerror(errno));
847 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
848 (sb.st_mode & 022) != 0))
849 fatal("Bad owner or permissions on %s", filename);
850 }
851
3c0ef626 852 debug("Reading configuration data %.200s", filename);
853
854 /*
855 * Mark that we are now processing the options. This flag is turned
856 * on/off by Host specifications.
857 */
858 active = 1;
859 linenum = 0;
860 while (fgets(line, sizeof(line), f)) {
861 /* Update line number counter. */
862 linenum++;
863 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
864 bad_options++;
865 }
866 fclose(f);
867 if (bad_options > 0)
868 fatal("%s: terminating, %d bad configuration options",
e9a17296 869 filename, bad_options);
3c0ef626 870 return 1;
871}
872
873/*
874 * Initializes options to special values that indicate that they have not yet
875 * been set. Read_config_file will only set options with this value. Options
876 * are processed in the following order: command line, user config file,
877 * system config file. Last, fill_default_options is called.
878 */
879
880void
881initialize_options(Options * options)
882{
883 memset(options, 'X', sizeof(*options));
884 options->forward_agent = -1;
885 options->forward_x11 = -1;
cdd66111 886 options->forward_x11_trusted = -1;
3c0ef626 887 options->xauth_location = NULL;
888 options->gateway_ports = -1;
889 options->use_privileged_port = -1;
3c0ef626 890 options->rsa_authentication = -1;
891 options->pubkey_authentication = -1;
892 options->challenge_response_authentication = -1;
0fff78ff 893 options->gss_authentication = -1;
894 options->gss_deleg_creds = -1;
3c0ef626 895 options->password_authentication = -1;
896 options->kbd_interactive_authentication = -1;
897 options->kbd_interactive_devices = NULL;
898 options->rhosts_rsa_authentication = -1;
899 options->hostbased_authentication = -1;
3c0ef626 900 options->batch_mode = -1;
901 options->check_host_ip = -1;
902 options->strict_host_key_checking = -1;
903 options->compression = -1;
cdd66111 904 options->tcp_keep_alive = -1;
3c0ef626 905 options->compression_level = -1;
906 options->port = -1;
0fff78ff 907 options->address_family = -1;
3c0ef626 908 options->connection_attempts = -1;
0fff78ff 909 options->connection_timeout = -1;
3c0ef626 910 options->number_of_password_prompts = -1;
911 options->cipher = -1;
912 options->ciphers = NULL;
913 options->macs = NULL;
914 options->hostkeyalgorithms = NULL;
915 options->protocol = SSH_PROTO_UNKNOWN;
916 options->num_identity_files = 0;
917 options->hostname = NULL;
918 options->host_key_alias = NULL;
919 options->proxy_command = NULL;
920 options->user = NULL;
921 options->escape_char = -1;
922 options->system_hostfile = NULL;
923 options->user_hostfile = NULL;
924 options->system_hostfile2 = NULL;
925 options->user_hostfile2 = NULL;
926 options->num_local_forwards = 0;
927 options->num_remote_forwards = 0;
928 options->clear_forwardings = -1;
e9a17296 929 options->log_level = SYSLOG_LEVEL_NOT_SET;
3c0ef626 930 options->preferred_authentications = NULL;
931 options->bind_address = NULL;
932 options->smartcard_device = NULL;
6a9b3198 933 options->enable_ssh_keysign = - 1;
3c0ef626 934 options->no_host_authentication_for_localhost = - 1;
99be0775 935 options->identities_only = - 1;
0fff78ff 936 options->rekey_limit = - 1;
937 options->verify_host_key_dns = -1;
cdd66111 938 options->server_alive_interval = -1;
939 options->server_alive_count_max = -1;
c9f39d2c 940 options->num_send_env = 0;
941 options->control_path = NULL;
942 options->control_master = -1;
996d5e62 943 options->hash_known_hosts = -1;
3c0ef626 944}
945
946/*
947 * Called after processing other sources of option data, this fills those
948 * options for which no value has been specified with their default values.
949 */
950
951void
952fill_default_options(Options * options)
953{
954 int len;
955
956 if (options->forward_agent == -1)
957 options->forward_agent = 0;
958 if (options->forward_x11 == -1)
959 options->forward_x11 = 0;
cdd66111 960 if (options->forward_x11_trusted == -1)
961 options->forward_x11_trusted = 0;
3c0ef626 962 if (options->xauth_location == NULL)
963 options->xauth_location = _PATH_XAUTH;
3c0ef626 964 if (options->gateway_ports == -1)
965 options->gateway_ports = 0;
966 if (options->use_privileged_port == -1)
967 options->use_privileged_port = 0;
3c0ef626 968 if (options->rsa_authentication == -1)
969 options->rsa_authentication = 1;
970 if (options->pubkey_authentication == -1)
971 options->pubkey_authentication = 1;
972 if (options->challenge_response_authentication == -1)
973 options->challenge_response_authentication = 1;
0fff78ff 974 if (options->gss_authentication == -1)
cdd66111 975 options->gss_authentication = 0;
0fff78ff 976 if (options->gss_deleg_creds == -1)
977 options->gss_deleg_creds = 0;
3c0ef626 978 if (options->password_authentication == -1)
979 options->password_authentication = 1;
980 if (options->kbd_interactive_authentication == -1)
981 options->kbd_interactive_authentication = 1;
982 if (options->rhosts_rsa_authentication == -1)
f5799ae1 983 options->rhosts_rsa_authentication = 0;
3c0ef626 984 if (options->hostbased_authentication == -1)
985 options->hostbased_authentication = 0;
3c0ef626 986 if (options->batch_mode == -1)
987 options->batch_mode = 0;
988 if (options->check_host_ip == -1)
989 options->check_host_ip = 1;
990 if (options->strict_host_key_checking == -1)
991 options->strict_host_key_checking = 2; /* 2 is default */
992 if (options->compression == -1)
993 options->compression = 0;
cdd66111 994 if (options->tcp_keep_alive == -1)
995 options->tcp_keep_alive = 1;
3c0ef626 996 if (options->compression_level == -1)
997 options->compression_level = 6;
998 if (options->port == -1)
999 options->port = 0; /* Filled in ssh_connect. */
0fff78ff 1000 if (options->address_family == -1)
1001 options->address_family = AF_UNSPEC;
3c0ef626 1002 if (options->connection_attempts == -1)
1003 options->connection_attempts = 1;
1004 if (options->number_of_password_prompts == -1)
1005 options->number_of_password_prompts = 3;
1006 /* Selected in ssh_login(). */
1007 if (options->cipher == -1)
1008 options->cipher = SSH_CIPHER_NOT_SET;
1009 /* options->ciphers, default set in myproposals.h */
1010 /* options->macs, default set in myproposals.h */
1011 /* options->hostkeyalgorithms, default set in myproposals.h */
1012 if (options->protocol == SSH_PROTO_UNKNOWN)
1013 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1014 if (options->num_identity_files == 0) {
1015 if (options->protocol & SSH_PROTO_1) {
1016 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1017 options->identity_files[options->num_identity_files] =
1018 xmalloc(len);
1019 snprintf(options->identity_files[options->num_identity_files++],
1020 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1021 }
1022 if (options->protocol & SSH_PROTO_2) {
1023 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1024 options->identity_files[options->num_identity_files] =
1025 xmalloc(len);
1026 snprintf(options->identity_files[options->num_identity_files++],
1027 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1028
1029 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1030 options->identity_files[options->num_identity_files] =
1031 xmalloc(len);
1032 snprintf(options->identity_files[options->num_identity_files++],
1033 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1034 }
1035 }
1036 if (options->escape_char == -1)
1037 options->escape_char = '~';
1038 if (options->system_hostfile == NULL)
1039 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1040 if (options->user_hostfile == NULL)
1041 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1042 if (options->system_hostfile2 == NULL)
1043 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1044 if (options->user_hostfile2 == NULL)
1045 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
e9a17296 1046 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
3c0ef626 1047 options->log_level = SYSLOG_LEVEL_INFO;
1048 if (options->clear_forwardings == 1)
1049 clear_forwardings(options);
1050 if (options->no_host_authentication_for_localhost == - 1)
1051 options->no_host_authentication_for_localhost = 0;
99be0775 1052 if (options->identities_only == -1)
1053 options->identities_only = 0;
6a9b3198 1054 if (options->enable_ssh_keysign == -1)
1055 options->enable_ssh_keysign = 0;
0fff78ff 1056 if (options->rekey_limit == -1)
1057 options->rekey_limit = 0;
1058 if (options->verify_host_key_dns == -1)
1059 options->verify_host_key_dns = 0;
cdd66111 1060 if (options->server_alive_interval == -1)
1061 options->server_alive_interval = 0;
1062 if (options->server_alive_count_max == -1)
1063 options->server_alive_count_max = 3;
c9f39d2c 1064 if (options->control_master == -1)
1065 options->control_master = 0;
996d5e62 1066 if (options->hash_known_hosts == -1)
1067 options->hash_known_hosts = 0;
3c0ef626 1068 /* options->proxy_command should not be set by default */
1069 /* options->user will be set in the main program if appropriate */
1070 /* options->hostname will be set in the main program if appropriate */
1071 /* options->host_key_alias should not be set by default */
1072 /* options->preferred_authentications will be set in ssh */
1073}
996d5e62 1074
1075/*
1076 * parse_forward
1077 * parses a string containing a port forwarding specification of the form:
1078 * [listenhost:]listenport:connecthost:connectport
1079 * returns number of arguments parsed or zero on error
1080 */
1081int
1082parse_forward(Forward *fwd, const char *fwdspec)
1083{
1084 int i;
1085 char *p, *cp, *fwdarg[4];
1086
1087 memset(fwd, '\0', sizeof(*fwd));
1088
1089 cp = p = xstrdup(fwdspec);
1090
1091 /* skip leading spaces */
1092 while (*cp && isspace(*cp))
1093 cp++;
1094
1095 for (i = 0; i < 4; ++i)
1096 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1097 break;
1098
1099 /* Check for trailing garbage in 4-arg case*/
1100 if (cp != NULL)
1101 i = 0; /* failure */
1102
1103 switch (i) {
1104 case 3:
1105 fwd->listen_host = NULL;
1106 fwd->listen_port = a2port(fwdarg[0]);
1107 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1108 fwd->connect_port = a2port(fwdarg[2]);
1109 break;
1110
1111 case 4:
1112 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1113 fwd->listen_port = a2port(fwdarg[1]);
1114 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1115 fwd->connect_port = a2port(fwdarg[3]);
1116 break;
1117 default:
1118 i = 0; /* failure */
1119 }
1120
1121 xfree(p);
1122
1123 if (fwd->listen_port == 0 && fwd->connect_port == 0)
1124 goto fail_free;
1125
1126 if (fwd->connect_host != NULL &&
1127 strlen(fwd->connect_host) >= NI_MAXHOST)
1128 goto fail_free;
1129
1130 return (i);
1131
1132 fail_free:
1133 if (fwd->connect_host != NULL)
1134 xfree(fwd->connect_host);
1135 if (fwd->listen_host != NULL)
1136 xfree(fwd->listen_host);
1137 return (0);
1138}
This page took 0.228028 seconds and 5 git commands to generate.