]> andersk Git - openssh.git/blame - readconf.c
- djm@cvs.openbsd.org 2008/06/26 09:19:40
[openssh.git] / readconf.c
CommitLineData
aff73c5f 1/* $OpenBSD: readconf.c,v 1.166 2008/06/11 21:01:35 grunk Exp $ */
8efc0c15 2/*
5260325f 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5260325f 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
5260325f 6 * Functions for reading the configuration files.
6ae2364d 7 *
bcbf86ec 8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
5260325f 13 */
8efc0c15 14
15#include "includes.h"
4095f623 16
17#include <sys/types.h>
18#include <sys/stat.h>
9794d008 19#include <sys/socket.h>
20
21#include <netinet/in.h>
8efc0c15 22
b6438382 23#include <ctype.h>
028094f4 24#include <errno.h>
28cb0a43 25#include <netdb.h>
31652869 26#include <signal.h>
24436b92 27#include <stdarg.h>
cf851879 28#include <stdio.h>
00146caa 29#include <string.h>
5188ba17 30#include <unistd.h>
b6438382 31
8efc0c15 32#include "xmalloc.h"
31652869 33#include "ssh.h"
a8be9f80 34#include "compat.h"
42f11eb2 35#include "cipher.h"
36#include "pathnames.h"
37#include "log.h"
31652869 38#include "key.h"
42f11eb2 39#include "readconf.h"
40#include "match.h"
41#include "misc.h"
31652869 42#include "buffer.h"
b2552997 43#include "kex.h"
44#include "mac.h"
8efc0c15 45
46/* Format of the configuration file:
47
48 # Configuration data is parsed as follows:
49 # 1. command line options
50 # 2. user-specific file
51 # 3. system-wide file
52 # Any configuration value is only changed the first time it is set.
53 # Thus, host-specific definitions should be at the beginning of the
54 # configuration file, and defaults at the end.
55
56 # Host-specific declarations. These may override anything above. A single
57 # host may match multiple declarations; these are processed in the order
58 # that they are given in.
59
60 Host *.ngs.fi ngs.fi
80fcb74e 61 User foo
8efc0c15 62
63 Host fake.com
64 HostName another.host.name.real.org
65 User blaah
66 Port 34289
67 ForwardX11 no
68 ForwardAgent no
69
70 Host books.com
71 RemoteForward 9999 shadows.cs.hut.fi:9999
72 Cipher 3des
73
74 Host fascist.blob.com
75 Port 23123
76 User tylonen
8efc0c15 77 PasswordAuthentication no
78
79 Host puukko.hut.fi
80 User t35124p
81 ProxyCommand ssh-proxy %h %p
82
83 Host *.fr
80fcb74e 84 PublicKeyAuthentication no
8efc0c15 85
86 Host *.su
87 Cipher none
88 PasswordAuthentication no
89
d20f3c9e 90 Host vpn.fake.com
91 Tunnel yes
92 TunnelDevice 3
93
8efc0c15 94 # Defaults for various options
95 Host *
96 ForwardAgent no
fa08c86b 97 ForwardX11 no
8efc0c15 98 PasswordAuthentication yes
99 RSAAuthentication yes
100 RhostsRSAAuthentication yes
8efc0c15 101 StrictHostKeyChecking yes
fd573618 102 TcpKeepAlive no
8efc0c15 103 IdentityFile ~/.ssh/identity
104 Port 22
105 EscapeChar ~
106
107*/
108
109/* Keyword tokens. */
110
5260325f 111typedef enum {
112 oBadOption,
d73a67d7 113 oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
42ea6f5e 114 oExitOnForwardFailure,
7203d6bb 115 oPasswordAuthentication, oRSAAuthentication,
d464095c 116 oChallengeResponseAuthentication, oXAuthLocation,
5260325f 117 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
118 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
119 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
120 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
fd573618 121 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
b2552997 122 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
fa08c86b 123 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
cab80f75 124 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
e961a8f9 125 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
e1c5bfaf 126 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
80fcb74e 127 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
09ab3296 128 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
7364bd04 129 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
3a065ed0 130 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
5c63c2ab 131 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
d20f3c9e 132 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
a2144546 133 oDeprecated, oUnsupported
8efc0c15 134} OpCodes;
135
136/* Textual representations of the tokens. */
137
5260325f 138static struct {
139 const char *name;
140 OpCodes opcode;
141} keywords[] = {
142 { "forwardagent", oForwardAgent },
143 { "forwardx11", oForwardX11 },
d73a67d7 144 { "forwardx11trusted", oForwardX11Trusted },
42ea6f5e 145 { "exitonforwardfailure", oExitOnForwardFailure },
fa649821 146 { "xauthlocation", oXAuthLocation },
5260325f 147 { "gatewayports", oGatewayPorts },
148 { "useprivilegedport", oUsePrivilegedPort },
0598d99d 149 { "rhostsauthentication", oDeprecated },
5260325f 150 { "passwordauthentication", oPasswordAuthentication },
94ec8c6b 151 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
152 { "kbdinteractivedevices", oKbdInteractiveDevices },
5260325f 153 { "rsaauthentication", oRSAAuthentication },
fa08c86b 154 { "pubkeyauthentication", oPubkeyAuthentication },
d464095c 155 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
8002af61 156 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
0140e66a 157 { "hostbasedauthentication", oHostbasedAuthentication },
d464095c 158 { "challengeresponseauthentication", oChallengeResponseAuthentication },
159 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
160 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
a2144546 161 { "kerberosauthentication", oUnsupported },
162 { "kerberostgtpassing", oUnsupported },
a2144546 163 { "afstokenpassing", oUnsupported },
7364bd04 164#if defined(GSSAPI)
165 { "gssapiauthentication", oGssAuthentication },
7364bd04 166 { "gssapidelegatecredentials", oGssDelegateCreds },
167#else
168 { "gssapiauthentication", oUnsupported },
169 { "gssapidelegatecredentials", oUnsupported },
170#endif
80fcb74e 171 { "fallbacktorsh", oDeprecated },
172 { "usersh", oDeprecated },
5260325f 173 { "identityfile", oIdentityFile },
fa08c86b 174 { "identityfile2", oIdentityFile }, /* alias */
3a065ed0 175 { "identitiesonly", oIdentitiesOnly },
5260325f 176 { "hostname", oHostName },
8abcdba4 177 { "hostkeyalias", oHostKeyAlias },
5260325f 178 { "proxycommand", oProxyCommand },
179 { "port", oPort },
180 { "cipher", oCipher },
a8be9f80 181 { "ciphers", oCiphers },
b2552997 182 { "macs", oMacs },
a8be9f80 183 { "protocol", oProtocol },
5260325f 184 { "remoteforward", oRemoteForward },
185 { "localforward", oLocalForward },
186 { "user", oUser },
187 { "host", oHost },
188 { "escapechar", oEscapeChar },
5260325f 189 { "globalknownhostsfile", oGlobalKnownHostsFile },
f49bc4f7 190 { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */
a306f2dd 191 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
f49bc4f7 192 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
5260325f 193 { "connectionattempts", oConnectionAttempts },
194 { "batchmode", oBatchMode },
195 { "checkhostip", oCheckHostIP },
196 { "stricthostkeychecking", oStrictHostKeyChecking },
197 { "compression", oCompression },
198 { "compressionlevel", oCompressionLevel },
fd573618 199 { "tcpkeepalive", oTCPKeepAlive },
200 { "keepalive", oTCPKeepAlive }, /* obsolete */
5260325f 201 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
5260325f 202 { "loglevel", oLogLevel },
0490e609 203 { "dynamicforward", oDynamicForward },
cab80f75 204 { "preferredauthentications", oPreferredAuthentications },
e961a8f9 205 { "hostkeyalgorithms", oHostKeyAlgorithms },
3435f5a6 206 { "bindaddress", oBindAddress },
a2144546 207#ifdef SMARTCARD
eea098a3 208 { "smartcarddevice", oSmartcardDevice },
a2144546 209#else
210 { "smartcarddevice", oUnsupported },
211#endif
184eed6a 212 { "clearallforwardings", oClearAllForwardings },
cc46e2ee 213 { "enablesshkeysign", oEnableSSHKeysign },
21289cd0 214 { "verifyhostkeydns", oVerifyHostKeyDNS },
184eed6a 215 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
ffd7b36b 216 { "rekeylimit", oRekeyLimit },
09ab3296 217 { "connecttimeout", oConnectTimeout },
f811e52a 218 { "addressfamily", oAddressFamily },
5d8d32a3 219 { "serveraliveinterval", oServerAliveInterval },
220 { "serveralivecountmax", oServerAliveCountMax },
61a2c1da 221 { "sendenv", oSendEnv },
5e96b616 222 { "controlpath", oControlPath },
223 { "controlmaster", oControlMaster },
5c63c2ab 224 { "hashknownhosts", oHashKnownHosts },
d20f3c9e 225 { "tunnel", oTunnel },
226 { "tunneldevice", oTunnelDevice },
227 { "localcommand", oLocalCommand },
228 { "permitlocalcommand", oPermitLocalCommand },
17a3011c 229 { NULL, oBadOption }
6a17f9c2 230};
231
aa3378df 232/*
233 * Adds a local TCP/IP port forward to options. Never returns if there is an
234 * error.
235 */
8efc0c15 236
6ae2364d 237void
3867aa0a 238add_local_forward(Options *options, const Forward *newfwd)
8efc0c15 239{
5260325f 240 Forward *fwd;
e6f15ed1 241#ifndef NO_IPPORT_RESERVED_CONCEPT
5260325f 242 extern uid_t original_real_uid;
3867aa0a 243 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
54b974dc 244 fatal("Privileged ports can only be forwarded by root.");
3c62e7eb 245#endif
5260325f 246 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
247 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
248 fwd = &options->local_forwards[options->num_local_forwards++];
3867aa0a 249
250 fwd->listen_host = (newfwd->listen_host == NULL) ?
251 NULL : xstrdup(newfwd->listen_host);
252 fwd->listen_port = newfwd->listen_port;
253 fwd->connect_host = xstrdup(newfwd->connect_host);
254 fwd->connect_port = newfwd->connect_port;
8efc0c15 255}
256
aa3378df 257/*
258 * Adds a remote TCP/IP port forward to options. Never returns if there is
259 * an error.
260 */
8efc0c15 261
6ae2364d 262void
3867aa0a 263add_remote_forward(Options *options, const Forward *newfwd)
8efc0c15 264{
5260325f 265 Forward *fwd;
266 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
267 fatal("Too many remote forwards (max %d).",
184eed6a 268 SSH_MAX_FORWARDS_PER_DIRECTION);
5260325f 269 fwd = &options->remote_forwards[options->num_remote_forwards++];
3867aa0a 270
271 fwd->listen_host = (newfwd->listen_host == NULL) ?
272 NULL : xstrdup(newfwd->listen_host);
273 fwd->listen_port = newfwd->listen_port;
274 fwd->connect_host = xstrdup(newfwd->connect_host);
275 fwd->connect_port = newfwd->connect_port;
8efc0c15 276}
277
e1c5bfaf 278static void
279clear_forwardings(Options *options)
280{
281 int i;
282
3867aa0a 283 for (i = 0; i < options->num_local_forwards; i++) {
2b74a069 284 if (options->local_forwards[i].listen_host != NULL)
285 xfree(options->local_forwards[i].listen_host);
3867aa0a 286 xfree(options->local_forwards[i].connect_host);
287 }
e1c5bfaf 288 options->num_local_forwards = 0;
3867aa0a 289 for (i = 0; i < options->num_remote_forwards; i++) {
2b74a069 290 if (options->remote_forwards[i].listen_host != NULL)
291 xfree(options->remote_forwards[i].listen_host);
3867aa0a 292 xfree(options->remote_forwards[i].connect_host);
293 }
e1c5bfaf 294 options->num_remote_forwards = 0;
a4f24bf8 295 options->tun_open = SSH_TUNMODE_NO;
e1c5bfaf 296}
297
aa3378df 298/*
6be9a5e8 299 * Returns the number of the token pointed to by cp or oBadOption.
aa3378df 300 */
8efc0c15 301
6ae2364d 302static OpCodes
5260325f 303parse_token(const char *cp, const char *filename, int linenum)
8efc0c15 304{
1e3b8b07 305 u_int i;
8efc0c15 306
5260325f 307 for (i = 0; keywords[i].name; i++)
aa3378df 308 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 309 return keywords[i].opcode;
8efc0c15 310
b7c70970 311 error("%s: line %d: Bad configuration option: %s",
312 filename, linenum, cp);
5260325f 313 return oBadOption;
8efc0c15 314}
315
aa3378df 316/*
317 * Processes a single option line as used in the configuration files. This
318 * only sets those values that have not already been set.
319 */
d718e75d 320#define WHITESPACE " \t\r\n"
8efc0c15 321
e7c0f9d5 322int
323process_config_line(Options *options, const char *host,
5260325f 324 char *line, const char *filename, int linenum,
325 int *activep)
8efc0c15 326{
3867aa0a 327 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
129d5252 328 int opcode, *intptr, value, value2, scale;
2a72bc03 329 LogLevel *log_level_ptr;
129d5252 330 long long orig, val64;
d718e75d 331 size_t len;
3867aa0a 332 Forward fwd;
5260325f 333
204fde99 334 /* Strip trailing whitespace */
f8cc7664 335 for (len = strlen(line) - 1; len > 0; len--) {
204fde99 336 if (strchr(WHITESPACE, line[len]) == NULL)
337 break;
338 line[len] = '\0';
339 }
340
704b1659 341 s = line;
342 /* Get the keyword. (Each line is supposed to begin with a keyword). */
88299971 343 if ((keyword = strdelim(&s)) == NULL)
344 return 0;
704b1659 345 /* Ignore leading whitespace. */
346 if (*keyword == '\0')
347 keyword = strdelim(&s);
42f11eb2 348 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 349 return 0;
350
089fbbd2 351 opcode = parse_token(keyword, filename, linenum);
5260325f 352
353 switch (opcode) {
354 case oBadOption:
aa3378df 355 /* don't panic, but count bad options */
356 return -1;
5260325f 357 /* NOTREACHED */
09ab3296 358 case oConnectTimeout:
359 intptr = &options->connection_timeout;
5d8d32a3 360parse_time:
09ab3296 361 arg = strdelim(&s);
362 if (!arg || *arg == '\0')
363 fatal("%s line %d: missing time value.",
364 filename, linenum);
365 if ((value = convtime(arg)) == -1)
366 fatal("%s line %d: invalid time value.",
367 filename, linenum);
7f650171 368 if (*activep && *intptr == -1)
09ab3296 369 *intptr = value;
370 break;
371
5260325f 372 case oForwardAgent:
373 intptr = &options->forward_agent;
374parse_flag:
704b1659 375 arg = strdelim(&s);
089fbbd2 376 if (!arg || *arg == '\0')
5260325f 377 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
378 value = 0; /* To avoid compiler warning... */
089fbbd2 379 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 380 value = 1;
089fbbd2 381 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 382 value = 0;
383 else
384 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
385 if (*activep && *intptr == -1)
386 *intptr = value;
387 break;
388
389 case oForwardX11:
390 intptr = &options->forward_x11;
391 goto parse_flag;
392
d73a67d7 393 case oForwardX11Trusted:
394 intptr = &options->forward_x11_trusted;
395 goto parse_flag;
396
5260325f 397 case oGatewayPorts:
398 intptr = &options->gateway_ports;
399 goto parse_flag;
400
42ea6f5e 401 case oExitOnForwardFailure:
402 intptr = &options->exit_on_forward_failure;
403 goto parse_flag;
404
5260325f 405 case oUsePrivilegedPort:
406 intptr = &options->use_privileged_port;
407 goto parse_flag;
408
5260325f 409 case oPasswordAuthentication:
410 intptr = &options->password_authentication;
411 goto parse_flag;
412
94ec8c6b 413 case oKbdInteractiveAuthentication:
414 intptr = &options->kbd_interactive_authentication;
415 goto parse_flag;
416
417 case oKbdInteractiveDevices:
418 charptr = &options->kbd_interactive_devices;
419 goto parse_string;
420
fa08c86b 421 case oPubkeyAuthentication:
422 intptr = &options->pubkey_authentication;
1d1ffb87 423 goto parse_flag;
424
5260325f 425 case oRSAAuthentication:
426 intptr = &options->rsa_authentication;
427 goto parse_flag;
428
429 case oRhostsRSAAuthentication:
430 intptr = &options->rhosts_rsa_authentication;
431 goto parse_flag;
432
8002af61 433 case oHostbasedAuthentication:
434 intptr = &options->hostbased_authentication;
435 goto parse_flag;
436
d464095c 437 case oChallengeResponseAuthentication:
5ba55ada 438 intptr = &options->challenge_response_authentication;
5260325f 439 goto parse_flag;
d0ec7f42 440
7364bd04 441 case oGssAuthentication:
442 intptr = &options->gss_authentication;
443 goto parse_flag;
444
445 case oGssDelegateCreds:
446 intptr = &options->gss_deleg_creds;
447 goto parse_flag;
448
5260325f 449 case oBatchMode:
450 intptr = &options->batch_mode;
451 goto parse_flag;
452
453 case oCheckHostIP:
454 intptr = &options->check_host_ip;
aff73c5f 455 arg = strdelim(&s);
456 if (!arg || *arg == '\0')
457 fatal("%.200s line %d: Missing CheckHostIP argument.",
458 filename, linenum);
459 value = 0; /* To avoid compiler warning... */
460 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
461 value = SSHCTL_CHECKHOSTIP_YES;
462 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
463 value = SSHCTL_CHECKHOSTIP_NO;
464 else if (strcmp(arg, "fingerprint") == 0)
465 value = SSHCTL_CHECKHOSTIP_FPR;
466 else
467 fatal("%.200s line %d: Bad CheckHostIP argument.",
468 filename, linenum);
469 if (*activep && *intptr == -1)
470 *intptr = value;
471 break;
5260325f 472
21289cd0 473 case oVerifyHostKeyDNS:
474 intptr = &options->verify_host_key_dns;
0161a13d 475 goto parse_yesnoask;
21289cd0 476
5260325f 477 case oStrictHostKeyChecking:
478 intptr = &options->strict_host_key_checking;
0161a13d 479parse_yesnoask:
704b1659 480 arg = strdelim(&s);
089fbbd2 481 if (!arg || *arg == '\0')
c76c8819 482 fatal("%.200s line %d: Missing yes/no/ask argument.",
184eed6a 483 filename, linenum);
5260325f 484 value = 0; /* To avoid compiler warning... */
089fbbd2 485 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 486 value = 1;
089fbbd2 487 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 488 value = 0;
089fbbd2 489 else if (strcmp(arg, "ask") == 0)
5260325f 490 value = 2;
491 else
492 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
493 if (*activep && *intptr == -1)
494 *intptr = value;
495 break;
496
497 case oCompression:
498 intptr = &options->compression;
499 goto parse_flag;
500
fd573618 501 case oTCPKeepAlive:
502 intptr = &options->tcp_keep_alive;
5260325f 503 goto parse_flag;
504
8bbc048a 505 case oNoHostAuthenticationForLocalhost:
506 intptr = &options->no_host_authentication_for_localhost;
507 goto parse_flag;
508
5260325f 509 case oNumberOfPasswordPrompts:
510 intptr = &options->number_of_password_prompts;
511 goto parse_int;
512
513 case oCompressionLevel:
514 intptr = &options->compression_level;
515 goto parse_int;
516
ffd7b36b 517 case oRekeyLimit:
ffd7b36b 518 arg = strdelim(&s);
519 if (!arg || *arg == '\0')
520 fatal("%.200s line %d: Missing argument.", filename, linenum);
521 if (arg[0] < '0' || arg[0] > '9')
522 fatal("%.200s line %d: Bad number.", filename, linenum);
129d5252 523 orig = val64 = strtoll(arg, &endofnumber, 10);
ffd7b36b 524 if (arg == endofnumber)
525 fatal("%.200s line %d: Bad number.", filename, linenum);
526 switch (toupper(*endofnumber)) {
129d5252 527 case '\0':
528 scale = 1;
529 break;
ffd7b36b 530 case 'K':
129d5252 531 scale = 1<<10;
ffd7b36b 532 break;
533 case 'M':
129d5252 534 scale = 1<<20;
ffd7b36b 535 break;
536 case 'G':
129d5252 537 scale = 1<<30;
ffd7b36b 538 break;
129d5252 539 default:
540 fatal("%.200s line %d: Invalid RekeyLimit suffix",
541 filename, linenum);
ffd7b36b 542 }
129d5252 543 val64 *= scale;
544 /* detect integer wrap and too-large limits */
fe771396 545 if ((val64 / scale) != orig || val64 > UINT_MAX)
129d5252 546 fatal("%.200s line %d: RekeyLimit too large",
547 filename, linenum);
548 if (val64 < 16)
549 fatal("%.200s line %d: RekeyLimit too small",
550 filename, linenum);
fe771396 551 if (*activep && options->rekey_limit == -1)
552 options->rekey_limit = (u_int32_t)val64;
ffd7b36b 553 break;
554
5260325f 555 case oIdentityFile:
704b1659 556 arg = strdelim(&s);
089fbbd2 557 if (!arg || *arg == '\0')
5260325f 558 fatal("%.200s line %d: Missing argument.", filename, linenum);
559 if (*activep) {
fa08c86b 560 intptr = &options->num_identity_files;
a306f2dd 561 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 562 fatal("%.200s line %d: Too many identity files specified (max %d).",
184eed6a 563 filename, linenum, SSH_MAX_IDENTITY_FILES);
0cf6a024 564 charptr = &options->identity_files[*intptr];
089fbbd2 565 *charptr = xstrdup(arg);
a306f2dd 566 *intptr = *intptr + 1;
5260325f 567 }
568 break;
569
fa649821 570 case oXAuthLocation:
571 charptr=&options->xauth_location;
572 goto parse_string;
573
5260325f 574 case oUser:
575 charptr = &options->user;
576parse_string:
704b1659 577 arg = strdelim(&s);
089fbbd2 578 if (!arg || *arg == '\0')
5260325f 579 fatal("%.200s line %d: Missing argument.", filename, linenum);
580 if (*activep && *charptr == NULL)
089fbbd2 581 *charptr = xstrdup(arg);
5260325f 582 break;
583
584 case oGlobalKnownHostsFile:
585 charptr = &options->system_hostfile;
586 goto parse_string;
587
588 case oUserKnownHostsFile:
589 charptr = &options->user_hostfile;
590 goto parse_string;
591
a306f2dd 592 case oGlobalKnownHostsFile2:
593 charptr = &options->system_hostfile2;
594 goto parse_string;
595
596 case oUserKnownHostsFile2:
597 charptr = &options->user_hostfile2;
598 goto parse_string;
599
5260325f 600 case oHostName:
601 charptr = &options->hostname;
602 goto parse_string;
603
8abcdba4 604 case oHostKeyAlias:
605 charptr = &options->host_key_alias;
606 goto parse_string;
607
cab80f75 608 case oPreferredAuthentications:
609 charptr = &options->preferred_authentications;
610 goto parse_string;
611
3435f5a6 612 case oBindAddress:
613 charptr = &options->bind_address;
614 goto parse_string;
615
eea098a3 616 case oSmartcardDevice:
9ff6f66f 617 charptr = &options->smartcard_device;
618 goto parse_string;
eea098a3 619
5260325f 620 case oProxyCommand:
d20f3c9e 621 charptr = &options->proxy_command;
622parse_command:
2d9c1828 623 if (s == NULL)
624 fatal("%.200s line %d: Missing argument.", filename, linenum);
d718e75d 625 len = strspn(s, WHITESPACE "=");
5260325f 626 if (*activep && *charptr == NULL)
d718e75d 627 *charptr = xstrdup(s + len);
5260325f 628 return 0;
629
630 case oPort:
631 intptr = &options->port;
632parse_int:
704b1659 633 arg = strdelim(&s);
089fbbd2 634 if (!arg || *arg == '\0')
5260325f 635 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 636 if (arg[0] < '0' || arg[0] > '9')
5260325f 637 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 638
639 /* Octal, decimal, or hex format? */
089fbbd2 640 value = strtol(arg, &endofnumber, 0);
641 if (arg == endofnumber)
aa3378df 642 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 643 if (*activep && *intptr == -1)
644 *intptr = value;
645 break;
646
647 case oConnectionAttempts:
648 intptr = &options->connection_attempts;
649 goto parse_int;
650
651 case oCipher:
652 intptr = &options->cipher;
704b1659 653 arg = strdelim(&s);
089fbbd2 654 if (!arg || *arg == '\0')
71276795 655 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 656 value = cipher_number(arg);
5260325f 657 if (value == -1)
658 fatal("%.200s line %d: Bad cipher '%s'.",
184eed6a 659 filename, linenum, arg ? arg : "<NONE>");
5260325f 660 if (*activep && *intptr == -1)
661 *intptr = value;
662 break;
663
a8be9f80 664 case oCiphers:
704b1659 665 arg = strdelim(&s);
089fbbd2 666 if (!arg || *arg == '\0')
71276795 667 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 668 if (!ciphers_valid(arg))
d0c832f3 669 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
184eed6a 670 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 671 if (*activep && options->ciphers == NULL)
089fbbd2 672 options->ciphers = xstrdup(arg);
a8be9f80 673 break;
674
b2552997 675 case oMacs:
676 arg = strdelim(&s);
677 if (!arg || *arg == '\0')
678 fatal("%.200s line %d: Missing argument.", filename, linenum);
679 if (!mac_valid(arg))
680 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
184eed6a 681 filename, linenum, arg ? arg : "<NONE>");
b2552997 682 if (*activep && options->macs == NULL)
683 options->macs = xstrdup(arg);
684 break;
685
e961a8f9 686 case oHostKeyAlgorithms:
687 arg = strdelim(&s);
688 if (!arg || *arg == '\0')
689 fatal("%.200s line %d: Missing argument.", filename, linenum);
690 if (!key_names_valid2(arg))
691 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
184eed6a 692 filename, linenum, arg ? arg : "<NONE>");
e961a8f9 693 if (*activep && options->hostkeyalgorithms == NULL)
694 options->hostkeyalgorithms = xstrdup(arg);
695 break;
696
a8be9f80 697 case oProtocol:
698 intptr = &options->protocol;
704b1659 699 arg = strdelim(&s);
089fbbd2 700 if (!arg || *arg == '\0')
71276795 701 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 702 value = proto_spec(arg);
a8be9f80 703 if (value == SSH_PROTO_UNKNOWN)
704 fatal("%.200s line %d: Bad protocol spec '%s'.",
184eed6a 705 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 706 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
707 *intptr = value;
708 break;
709
5260325f 710 case oLogLevel:
2a72bc03 711 log_level_ptr = &options->log_level;
704b1659 712 arg = strdelim(&s);
089fbbd2 713 value = log_level_number(arg);
5eaf8578 714 if (value == SYSLOG_LEVEL_NOT_SET)
54b974dc 715 fatal("%.200s line %d: unsupported log level '%s'",
184eed6a 716 filename, linenum, arg ? arg : "<NONE>");
2a72bc03 717 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
718 *log_level_ptr = (LogLevel) value;
5260325f 719 break;
720
5260325f 721 case oLocalForward:
3a8aabf0 722 case oRemoteForward:
704b1659 723 arg = strdelim(&s);
3867aa0a 724 if (arg == NULL || *arg == '\0')
3a8aabf0 725 fatal("%.200s line %d: Missing port argument.",
726 filename, linenum);
3867aa0a 727 arg2 = strdelim(&s);
728 if (arg2 == NULL || *arg2 == '\0')
729 fatal("%.200s line %d: Missing target argument.",
3a8aabf0 730 filename, linenum);
3867aa0a 731
732 /* construct a string for parse_forward */
733 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
734
735 if (parse_forward(&fwd, fwdarg) == 0)
3a8aabf0 736 fatal("%.200s line %d: Bad forwarding specification.",
737 filename, linenum);
3867aa0a 738
3a8aabf0 739 if (*activep) {
740 if (opcode == oLocalForward)
3867aa0a 741 add_local_forward(options, &fwd);
3a8aabf0 742 else if (opcode == oRemoteForward)
3867aa0a 743 add_remote_forward(options, &fwd);
3a8aabf0 744 }
5260325f 745 break;
746
0490e609 747 case oDynamicForward:
748 arg = strdelim(&s);
749 if (!arg || *arg == '\0')
750 fatal("%.200s line %d: Missing port argument.",
751 filename, linenum);
3867aa0a 752 memset(&fwd, '\0', sizeof(fwd));
753 fwd.connect_host = "socks";
754 fwd.listen_host = hpdelim(&arg);
755 if (fwd.listen_host == NULL ||
756 strlen(fwd.listen_host) >= NI_MAXHOST)
757 fatal("%.200s line %d: Bad forwarding specification.",
758 filename, linenum);
759 if (arg) {
760 fwd.listen_port = a2port(arg);
761 fwd.listen_host = cleanhostname(fwd.listen_host);
762 } else {
763 fwd.listen_port = a2port(fwd.listen_host);
4c38e9c6 764 fwd.listen_host = NULL;
3867aa0a 765 }
766 if (fwd.listen_port == 0)
0490e609 767 fatal("%.200s line %d: Badly formatted port number.",
768 filename, linenum);
14e4a15f 769 if (*activep)
3867aa0a 770 add_local_forward(options, &fwd);
8002af61 771 break;
0490e609 772
e1c5bfaf 773 case oClearAllForwardings:
774 intptr = &options->clear_forwardings;
775 goto parse_flag;
776
5260325f 777 case oHost:
778 *activep = 0;
704b1659 779 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 780 if (match_pattern(host, arg)) {
781 debug("Applying options for %.100s", arg);
5260325f 782 *activep = 1;
783 break;
784 }
704b1659 785 /* Avoid garbage check below, as strdelim is done. */
5260325f 786 return 0;
787
788 case oEscapeChar:
789 intptr = &options->escape_char;
704b1659 790 arg = strdelim(&s);
089fbbd2 791 if (!arg || *arg == '\0')
5260325f 792 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 793 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 794 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
795 value = (u_char) arg[1] & 31;
089fbbd2 796 else if (strlen(arg) == 1)
1e3b8b07 797 value = (u_char) arg[0];
089fbbd2 798 else if (strcmp(arg, "none") == 0)
4bf9c10e 799 value = SSH_ESCAPECHAR_NONE;
5260325f 800 else {
801 fatal("%.200s line %d: Bad escape character.",
184eed6a 802 filename, linenum);
5260325f 803 /* NOTREACHED */
804 value = 0; /* Avoid compiler warning. */
805 }
806 if (*activep && *intptr == -1)
807 *intptr = value;
808 break;
809
f811e52a 810 case oAddressFamily:
811 arg = strdelim(&s);
38634ff6 812 if (!arg || *arg == '\0')
813 fatal("%s line %d: missing address family.",
814 filename, linenum);
1572b90f 815 intptr = &options->address_family;
f811e52a 816 if (strcasecmp(arg, "inet") == 0)
1572b90f 817 value = AF_INET;
f811e52a 818 else if (strcasecmp(arg, "inet6") == 0)
1572b90f 819 value = AF_INET6;
f811e52a 820 else if (strcasecmp(arg, "any") == 0)
1572b90f 821 value = AF_UNSPEC;
f811e52a 822 else
823 fatal("Unsupported AddressFamily \"%s\"", arg);
1572b90f 824 if (*activep && *intptr == -1)
825 *intptr = value;
f811e52a 826 break;
827
cc46e2ee 828 case oEnableSSHKeysign:
829 intptr = &options->enable_ssh_keysign;
830 goto parse_flag;
831
3a065ed0 832 case oIdentitiesOnly:
833 intptr = &options->identities_only;
834 goto parse_flag;
835
5d8d32a3 836 case oServerAliveInterval:
837 intptr = &options->server_alive_interval;
838 goto parse_time;
839
840 case oServerAliveCountMax:
841 intptr = &options->server_alive_count_max;
842 goto parse_int;
843
61a2c1da 844 case oSendEnv:
845 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
846 if (strchr(arg, '=') != NULL)
847 fatal("%s line %d: Invalid environment name.",
848 filename, linenum);
c8c99dd5 849 if (!*activep)
850 continue;
61a2c1da 851 if (options->num_send_env >= MAX_SEND_ENV)
852 fatal("%s line %d: too many send env.",
853 filename, linenum);
854 options->send_env[options->num_send_env++] =
855 xstrdup(arg);
856 }
857 break;
858
5e96b616 859 case oControlPath:
860 charptr = &options->control_path;
861 goto parse_string;
862
863 case oControlMaster:
864 intptr = &options->control_master;
9dfd96d6 865 arg = strdelim(&s);
866 if (!arg || *arg == '\0')
867 fatal("%.200s line %d: Missing ControlMaster argument.",
868 filename, linenum);
869 value = 0; /* To avoid compiler warning... */
870 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
871 value = SSHCTL_MASTER_YES;
872 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
873 value = SSHCTL_MASTER_NO;
874 else if (strcmp(arg, "auto") == 0)
875 value = SSHCTL_MASTER_AUTO;
876 else if (strcmp(arg, "ask") == 0)
877 value = SSHCTL_MASTER_ASK;
878 else if (strcmp(arg, "autoask") == 0)
879 value = SSHCTL_MASTER_AUTO_ASK;
880 else
881 fatal("%.200s line %d: Bad ControlMaster argument.",
882 filename, linenum);
883 if (*activep && *intptr == -1)
884 *intptr = value;
885 break;
5e96b616 886
5c63c2ab 887 case oHashKnownHosts:
888 intptr = &options->hash_known_hosts;
889 goto parse_flag;
890
d20f3c9e 891 case oTunnel:
892 intptr = &options->tun_open;
a4f24bf8 893 arg = strdelim(&s);
894 if (!arg || *arg == '\0')
895 fatal("%s line %d: Missing yes/point-to-point/"
896 "ethernet/no argument.", filename, linenum);
897 value = 0; /* silence compiler */
898 if (strcasecmp(arg, "ethernet") == 0)
899 value = SSH_TUNMODE_ETHERNET;
900 else if (strcasecmp(arg, "point-to-point") == 0)
901 value = SSH_TUNMODE_POINTOPOINT;
902 else if (strcasecmp(arg, "yes") == 0)
903 value = SSH_TUNMODE_DEFAULT;
904 else if (strcasecmp(arg, "no") == 0)
905 value = SSH_TUNMODE_NO;
906 else
907 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
908 "no argument: %s", filename, linenum, arg);
909 if (*activep)
910 *intptr = value;
911 break;
d20f3c9e 912
913 case oTunnelDevice:
914 arg = strdelim(&s);
915 if (!arg || *arg == '\0')
916 fatal("%.200s line %d: Missing argument.", filename, linenum);
917 value = a2tun(arg, &value2);
a4f24bf8 918 if (value == SSH_TUNID_ERR)
d20f3c9e 919 fatal("%.200s line %d: Bad tun device.", filename, linenum);
920 if (*activep) {
921 options->tun_local = value;
922 options->tun_remote = value2;
923 }
924 break;
925
926 case oLocalCommand:
927 charptr = &options->local_command;
928 goto parse_command;
929
930 case oPermitLocalCommand:
931 intptr = &options->permit_local_command;
932 goto parse_flag;
933
80fcb74e 934 case oDeprecated:
4feae93d 935 debug("%s line %d: Deprecated option \"%s\"",
80fcb74e 936 filename, linenum, keyword);
4feae93d 937 return 0;
80fcb74e 938
a2144546 939 case oUnsupported:
940 error("%s line %d: Unsupported option \"%s\"",
941 filename, linenum, keyword);
942 return 0;
943
5260325f 944 default:
945 fatal("process_config_line: Unimplemented opcode %d", opcode);
946 }
947
948 /* Check that there is no garbage at end of line. */
42f11eb2 949 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 950 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
4e2e5cfd 951 filename, linenum, arg);
089fbbd2 952 }
5260325f 953 return 0;
8efc0c15 954}
955
956
aa3378df 957/*
958 * Reads the config file and modifies the options accordingly. Options
959 * should already be initialized before this call. This never returns if
93111dfa 960 * there is an error. If the file does not exist, this returns 0.
aa3378df 961 */
8efc0c15 962
93111dfa 963int
f2107e97 964read_config_file(const char *filename, const char *host, Options *options,
9f6cab4b 965 int checkperm)
8efc0c15 966{
5260325f 967 FILE *f;
968 char line[1024];
969 int active, linenum;
970 int bad_options = 0;
971
972 /* Open the file. */
9f6cab4b 973 if ((f = fopen(filename, "r")) == NULL)
93111dfa 974 return 0;
5260325f 975
9f6cab4b 976 if (checkperm) {
977 struct stat sb;
f2107e97 978
f9ee425b 979 if (fstat(fileno(f), &sb) == -1)
9f6cab4b 980 fatal("fstat %s: %s", filename, strerror(errno));
9f6cab4b 981 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
f9ee425b 982 (sb.st_mode & 022) != 0))
9f6cab4b 983 fatal("Bad owner or permissions on %s", filename);
9f6cab4b 984 }
985
5260325f 986 debug("Reading configuration data %.200s", filename);
987
aa3378df 988 /*
989 * Mark that we are now processing the options. This flag is turned
990 * on/off by Host specifications.
991 */
5260325f 992 active = 1;
993 linenum = 0;
994 while (fgets(line, sizeof(line), f)) {
995 /* Update line number counter. */
996 linenum++;
997 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
998 bad_options++;
999 }
1000 fclose(f);
1001 if (bad_options > 0)
54b974dc 1002 fatal("%s: terminating, %d bad configuration options",
184eed6a 1003 filename, bad_options);
93111dfa 1004 return 1;
8efc0c15 1005}
1006
aa3378df 1007/*
1008 * Initializes options to special values that indicate that they have not yet
1009 * been set. Read_config_file will only set options with this value. Options
1010 * are processed in the following order: command line, user config file,
1011 * system config file. Last, fill_default_options is called.
1012 */
8efc0c15 1013
6ae2364d 1014void
5260325f 1015initialize_options(Options * options)
8efc0c15 1016{
5260325f 1017 memset(options, 'X', sizeof(*options));
1018 options->forward_agent = -1;
1019 options->forward_x11 = -1;
d73a67d7 1020 options->forward_x11_trusted = -1;
42ea6f5e 1021 options->exit_on_forward_failure = -1;
fa649821 1022 options->xauth_location = NULL;
5260325f 1023 options->gateway_ports = -1;
1024 options->use_privileged_port = -1;
5260325f 1025 options->rsa_authentication = -1;
fa08c86b 1026 options->pubkey_authentication = -1;
5ba55ada 1027 options->challenge_response_authentication = -1;
7364bd04 1028 options->gss_authentication = -1;
1029 options->gss_deleg_creds = -1;
5260325f 1030 options->password_authentication = -1;
94ec8c6b 1031 options->kbd_interactive_authentication = -1;
1032 options->kbd_interactive_devices = NULL;
5260325f 1033 options->rhosts_rsa_authentication = -1;
8002af61 1034 options->hostbased_authentication = -1;
5260325f 1035 options->batch_mode = -1;
1036 options->check_host_ip = -1;
1037 options->strict_host_key_checking = -1;
1038 options->compression = -1;
fd573618 1039 options->tcp_keep_alive = -1;
5260325f 1040 options->compression_level = -1;
1041 options->port = -1;
1572b90f 1042 options->address_family = -1;
5260325f 1043 options->connection_attempts = -1;
09ab3296 1044 options->connection_timeout = -1;
5260325f 1045 options->number_of_password_prompts = -1;
1046 options->cipher = -1;
a8be9f80 1047 options->ciphers = NULL;
b2552997 1048 options->macs = NULL;
e961a8f9 1049 options->hostkeyalgorithms = NULL;
a8be9f80 1050 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 1051 options->num_identity_files = 0;
1052 options->hostname = NULL;
8abcdba4 1053 options->host_key_alias = NULL;
5260325f 1054 options->proxy_command = NULL;
1055 options->user = NULL;
1056 options->escape_char = -1;
1057 options->system_hostfile = NULL;
1058 options->user_hostfile = NULL;
a306f2dd 1059 options->system_hostfile2 = NULL;
1060 options->user_hostfile2 = NULL;
5260325f 1061 options->num_local_forwards = 0;
1062 options->num_remote_forwards = 0;
e1c5bfaf 1063 options->clear_forwardings = -1;
5eaf8578 1064 options->log_level = SYSLOG_LEVEL_NOT_SET;
cab80f75 1065 options->preferred_authentications = NULL;
3435f5a6 1066 options->bind_address = NULL;
9ff6f66f 1067 options->smartcard_device = NULL;
cc46e2ee 1068 options->enable_ssh_keysign = - 1;
8bbc048a 1069 options->no_host_authentication_for_localhost = - 1;
3a065ed0 1070 options->identities_only = - 1;
ffd7b36b 1071 options->rekey_limit = - 1;
21289cd0 1072 options->verify_host_key_dns = -1;
5d8d32a3 1073 options->server_alive_interval = -1;
1074 options->server_alive_count_max = -1;
61a2c1da 1075 options->num_send_env = 0;
5e96b616 1076 options->control_path = NULL;
1077 options->control_master = -1;
5c63c2ab 1078 options->hash_known_hosts = -1;
d20f3c9e 1079 options->tun_open = -1;
1080 options->tun_local = -1;
1081 options->tun_remote = -1;
1082 options->local_command = NULL;
1083 options->permit_local_command = -1;
8efc0c15 1084}
1085
aa3378df 1086/*
1087 * Called after processing other sources of option data, this fills those
1088 * options for which no value has been specified with their default values.
1089 */
8efc0c15 1090
6ae2364d 1091void
5260325f 1092fill_default_options(Options * options)
8efc0c15 1093{
d2c46e77 1094 int len;
1095
5260325f 1096 if (options->forward_agent == -1)
71276795 1097 options->forward_agent = 0;
5260325f 1098 if (options->forward_x11 == -1)
c8d54615 1099 options->forward_x11 = 0;
d73a67d7 1100 if (options->forward_x11_trusted == -1)
1101 options->forward_x11_trusted = 0;
42ea6f5e 1102 if (options->exit_on_forward_failure == -1)
1103 options->exit_on_forward_failure = 0;
fa649821 1104 if (options->xauth_location == NULL)
fd9ede94 1105 options->xauth_location = _PATH_XAUTH;
5260325f 1106 if (options->gateway_ports == -1)
1107 options->gateway_ports = 0;
1108 if (options->use_privileged_port == -1)
d5ebca2b 1109 options->use_privileged_port = 0;
5260325f 1110 if (options->rsa_authentication == -1)
1111 options->rsa_authentication = 1;
fa08c86b 1112 if (options->pubkey_authentication == -1)
1113 options->pubkey_authentication = 1;
5ba55ada 1114 if (options->challenge_response_authentication == -1)
10a2cbef 1115 options->challenge_response_authentication = 1;
7364bd04 1116 if (options->gss_authentication == -1)
2ecb78df 1117 options->gss_authentication = 0;
7364bd04 1118 if (options->gss_deleg_creds == -1)
1119 options->gss_deleg_creds = 0;
5260325f 1120 if (options->password_authentication == -1)
1121 options->password_authentication = 1;
94ec8c6b 1122 if (options->kbd_interactive_authentication == -1)
d464095c 1123 options->kbd_interactive_authentication = 1;
5260325f 1124 if (options->rhosts_rsa_authentication == -1)
4b3d23b4 1125 options->rhosts_rsa_authentication = 0;
8002af61 1126 if (options->hostbased_authentication == -1)
1127 options->hostbased_authentication = 0;
5260325f 1128 if (options->batch_mode == -1)
1129 options->batch_mode = 0;
1130 if (options->check_host_ip == -1)
1131 options->check_host_ip = 1;
1132 if (options->strict_host_key_checking == -1)
1133 options->strict_host_key_checking = 2; /* 2 is default */
1134 if (options->compression == -1)
1135 options->compression = 0;
fd573618 1136 if (options->tcp_keep_alive == -1)
1137 options->tcp_keep_alive = 1;
5260325f 1138 if (options->compression_level == -1)
1139 options->compression_level = 6;
1140 if (options->port == -1)
1141 options->port = 0; /* Filled in ssh_connect. */
1572b90f 1142 if (options->address_family == -1)
1143 options->address_family = AF_UNSPEC;
5260325f 1144 if (options->connection_attempts == -1)
ce773142 1145 options->connection_attempts = 1;
5260325f 1146 if (options->number_of_password_prompts == -1)
1147 options->number_of_password_prompts = 3;
1148 /* Selected in ssh_login(). */
1149 if (options->cipher == -1)
1150 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 1151 /* options->ciphers, default set in myproposals.h */
b2552997 1152 /* options->macs, default set in myproposals.h */
e961a8f9 1153 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 1154 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 1155 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 1156 if (options->num_identity_files == 0) {
fa08c86b 1157 if (options->protocol & SSH_PROTO_1) {
d2c46e77 1158 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 1159 options->identity_files[options->num_identity_files] =
d2c46e77 1160 xmalloc(len);
1161 snprintf(options->identity_files[options->num_identity_files++],
1162 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 1163 }
1164 if (options->protocol & SSH_PROTO_2) {
ec63b02d 1165 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1166 options->identity_files[options->num_identity_files] =
1167 xmalloc(len);
1168 snprintf(options->identity_files[options->num_identity_files++],
1169 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1170
d2c46e77 1171 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 1172 options->identity_files[options->num_identity_files] =
d2c46e77 1173 xmalloc(len);
1174 snprintf(options->identity_files[options->num_identity_files++],
1175 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 1176 }
a306f2dd 1177 }
5260325f 1178 if (options->escape_char == -1)
1179 options->escape_char = '~';
1180 if (options->system_hostfile == NULL)
42f11eb2 1181 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 1182 if (options->user_hostfile == NULL)
42f11eb2 1183 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 1184 if (options->system_hostfile2 == NULL)
42f11eb2 1185 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 1186 if (options->user_hostfile2 == NULL)
42f11eb2 1187 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5eaf8578 1188 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 1189 options->log_level = SYSLOG_LEVEL_INFO;
e1c5bfaf 1190 if (options->clear_forwardings == 1)
1191 clear_forwardings(options);
8bbc048a 1192 if (options->no_host_authentication_for_localhost == - 1)
1193 options->no_host_authentication_for_localhost = 0;
3a065ed0 1194 if (options->identities_only == -1)
1195 options->identities_only = 0;
cc46e2ee 1196 if (options->enable_ssh_keysign == -1)
1197 options->enable_ssh_keysign = 0;
ffd7b36b 1198 if (options->rekey_limit == -1)
1199 options->rekey_limit = 0;
21289cd0 1200 if (options->verify_host_key_dns == -1)
1201 options->verify_host_key_dns = 0;
5d8d32a3 1202 if (options->server_alive_interval == -1)
1203 options->server_alive_interval = 0;
1204 if (options->server_alive_count_max == -1)
1205 options->server_alive_count_max = 3;
5e96b616 1206 if (options->control_master == -1)
1207 options->control_master = 0;
5c63c2ab 1208 if (options->hash_known_hosts == -1)
1209 options->hash_known_hosts = 0;
d20f3c9e 1210 if (options->tun_open == -1)
a4f24bf8 1211 options->tun_open = SSH_TUNMODE_NO;
1212 if (options->tun_local == -1)
1213 options->tun_local = SSH_TUNID_ANY;
1214 if (options->tun_remote == -1)
1215 options->tun_remote = SSH_TUNID_ANY;
d20f3c9e 1216 if (options->permit_local_command == -1)
1217 options->permit_local_command = 0;
1218 /* options->local_command should not be set by default */
5260325f 1219 /* options->proxy_command should not be set by default */
1220 /* options->user will be set in the main program if appropriate */
1221 /* options->hostname will be set in the main program if appropriate */
8abcdba4 1222 /* options->host_key_alias should not be set by default */
cab80f75 1223 /* options->preferred_authentications will be set in ssh */
8efc0c15 1224}
3867aa0a 1225
1226/*
1227 * parse_forward
1228 * parses a string containing a port forwarding specification of the form:
1229 * [listenhost:]listenport:connecthost:connectport
1230 * returns number of arguments parsed or zero on error
1231 */
1232int
1233parse_forward(Forward *fwd, const char *fwdspec)
1234{
1235 int i;
1236 char *p, *cp, *fwdarg[4];
1237
1238 memset(fwd, '\0', sizeof(*fwd));
1239
1240 cp = p = xstrdup(fwdspec);
1241
1242 /* skip leading spaces */
f48fbab3 1243 while (isspace(*cp))
3867aa0a 1244 cp++;
1245
1246 for (i = 0; i < 4; ++i)
1247 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1248 break;
1249
1250 /* Check for trailing garbage in 4-arg case*/
1251 if (cp != NULL)
1252 i = 0; /* failure */
1253
1254 switch (i) {
1255 case 3:
1256 fwd->listen_host = NULL;
1257 fwd->listen_port = a2port(fwdarg[0]);
1258 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1259 fwd->connect_port = a2port(fwdarg[2]);
1260 break;
1261
1262 case 4:
1263 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1264 fwd->listen_port = a2port(fwdarg[1]);
1265 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1266 fwd->connect_port = a2port(fwdarg[3]);
1267 break;
1268 default:
1269 i = 0; /* failure */
1270 }
1271
1272 xfree(p);
1273
c462cd6f 1274 if (fwd->listen_port == 0 || fwd->connect_port == 0)
3867aa0a 1275 goto fail_free;
1276
1277 if (fwd->connect_host != NULL &&
1278 strlen(fwd->connect_host) >= NI_MAXHOST)
1279 goto fail_free;
1280
1281 return (i);
1282
1283 fail_free:
1284 if (fwd->connect_host != NULL)
1285 xfree(fwd->connect_host);
1286 if (fwd->listen_host != NULL)
1287 xfree(fwd->listen_host);
1288 return (0);
1289}
This page took 0.941943 seconds and 5 git commands to generate.