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