]> andersk Git - openssh.git/blame - readconf.c
- jmc@cvs.openbsd.org 2007/01/12 20:20:41
[openssh.git] / readconf.c
CommitLineData
31652869 1/* $OpenBSD: readconf.c,v 1.159 2006/08/03 03:34:42 deraadt 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;
329 long long orig, val64;
d718e75d 330 size_t len;
3867aa0a 331 Forward fwd;
5260325f 332
204fde99 333 /* Strip trailing whitespace */
f8cc7664 334 for (len = strlen(line) - 1; len > 0; len--) {
204fde99 335 if (strchr(WHITESPACE, line[len]) == NULL)
336 break;
337 line[len] = '\0';
338 }
339
704b1659 340 s = line;
341 /* Get the keyword. (Each line is supposed to begin with a keyword). */
88299971 342 if ((keyword = strdelim(&s)) == NULL)
343 return 0;
704b1659 344 /* Ignore leading whitespace. */
345 if (*keyword == '\0')
346 keyword = strdelim(&s);
42f11eb2 347 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 348 return 0;
349
089fbbd2 350 opcode = parse_token(keyword, filename, linenum);
5260325f 351
352 switch (opcode) {
353 case oBadOption:
aa3378df 354 /* don't panic, but count bad options */
355 return -1;
5260325f 356 /* NOTREACHED */
09ab3296 357 case oConnectTimeout:
358 intptr = &options->connection_timeout;
5d8d32a3 359parse_time:
09ab3296 360 arg = strdelim(&s);
361 if (!arg || *arg == '\0')
362 fatal("%s line %d: missing time value.",
363 filename, linenum);
364 if ((value = convtime(arg)) == -1)
365 fatal("%s line %d: invalid time value.",
366 filename, linenum);
367 if (*intptr == -1)
368 *intptr = value;
369 break;
370
5260325f 371 case oForwardAgent:
372 intptr = &options->forward_agent;
373parse_flag:
704b1659 374 arg = strdelim(&s);
089fbbd2 375 if (!arg || *arg == '\0')
5260325f 376 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
377 value = 0; /* To avoid compiler warning... */
089fbbd2 378 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 379 value = 1;
089fbbd2 380 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 381 value = 0;
382 else
383 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
384 if (*activep && *intptr == -1)
385 *intptr = value;
386 break;
387
388 case oForwardX11:
389 intptr = &options->forward_x11;
390 goto parse_flag;
391
d73a67d7 392 case oForwardX11Trusted:
393 intptr = &options->forward_x11_trusted;
394 goto parse_flag;
395
5260325f 396 case oGatewayPorts:
397 intptr = &options->gateway_ports;
398 goto parse_flag;
399
42ea6f5e 400 case oExitOnForwardFailure:
401 intptr = &options->exit_on_forward_failure;
402 goto parse_flag;
403
5260325f 404 case oUsePrivilegedPort:
405 intptr = &options->use_privileged_port;
406 goto parse_flag;
407
5260325f 408 case oPasswordAuthentication:
409 intptr = &options->password_authentication;
410 goto parse_flag;
411
94ec8c6b 412 case oKbdInteractiveAuthentication:
413 intptr = &options->kbd_interactive_authentication;
414 goto parse_flag;
415
416 case oKbdInteractiveDevices:
417 charptr = &options->kbd_interactive_devices;
418 goto parse_string;
419
fa08c86b 420 case oPubkeyAuthentication:
421 intptr = &options->pubkey_authentication;
1d1ffb87 422 goto parse_flag;
423
5260325f 424 case oRSAAuthentication:
425 intptr = &options->rsa_authentication;
426 goto parse_flag;
427
428 case oRhostsRSAAuthentication:
429 intptr = &options->rhosts_rsa_authentication;
430 goto parse_flag;
431
8002af61 432 case oHostbasedAuthentication:
433 intptr = &options->hostbased_authentication;
434 goto parse_flag;
435
d464095c 436 case oChallengeResponseAuthentication:
5ba55ada 437 intptr = &options->challenge_response_authentication;
5260325f 438 goto parse_flag;
d0ec7f42 439
7364bd04 440 case oGssAuthentication:
441 intptr = &options->gss_authentication;
442 goto parse_flag;
443
444 case oGssDelegateCreds:
445 intptr = &options->gss_deleg_creds;
446 goto parse_flag;
447
5260325f 448 case oBatchMode:
449 intptr = &options->batch_mode;
450 goto parse_flag;
451
452 case oCheckHostIP:
453 intptr = &options->check_host_ip;
454 goto parse_flag;
455
21289cd0 456 case oVerifyHostKeyDNS:
457 intptr = &options->verify_host_key_dns;
0161a13d 458 goto parse_yesnoask;
21289cd0 459
5260325f 460 case oStrictHostKeyChecking:
461 intptr = &options->strict_host_key_checking;
0161a13d 462parse_yesnoask:
704b1659 463 arg = strdelim(&s);
089fbbd2 464 if (!arg || *arg == '\0')
c76c8819 465 fatal("%.200s line %d: Missing yes/no/ask argument.",
184eed6a 466 filename, linenum);
5260325f 467 value = 0; /* To avoid compiler warning... */
089fbbd2 468 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 469 value = 1;
089fbbd2 470 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 471 value = 0;
089fbbd2 472 else if (strcmp(arg, "ask") == 0)
5260325f 473 value = 2;
474 else
475 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
476 if (*activep && *intptr == -1)
477 *intptr = value;
478 break;
479
480 case oCompression:
481 intptr = &options->compression;
482 goto parse_flag;
483
fd573618 484 case oTCPKeepAlive:
485 intptr = &options->tcp_keep_alive;
5260325f 486 goto parse_flag;
487
8bbc048a 488 case oNoHostAuthenticationForLocalhost:
489 intptr = &options->no_host_authentication_for_localhost;
490 goto parse_flag;
491
5260325f 492 case oNumberOfPasswordPrompts:
493 intptr = &options->number_of_password_prompts;
494 goto parse_int;
495
496 case oCompressionLevel:
497 intptr = &options->compression_level;
498 goto parse_int;
499
ffd7b36b 500 case oRekeyLimit:
501 intptr = &options->rekey_limit;
502 arg = strdelim(&s);
503 if (!arg || *arg == '\0')
504 fatal("%.200s line %d: Missing argument.", filename, linenum);
505 if (arg[0] < '0' || arg[0] > '9')
506 fatal("%.200s line %d: Bad number.", filename, linenum);
129d5252 507 orig = val64 = strtoll(arg, &endofnumber, 10);
ffd7b36b 508 if (arg == endofnumber)
509 fatal("%.200s line %d: Bad number.", filename, linenum);
510 switch (toupper(*endofnumber)) {
129d5252 511 case '\0':
512 scale = 1;
513 break;
ffd7b36b 514 case 'K':
129d5252 515 scale = 1<<10;
ffd7b36b 516 break;
517 case 'M':
129d5252 518 scale = 1<<20;
ffd7b36b 519 break;
520 case 'G':
129d5252 521 scale = 1<<30;
ffd7b36b 522 break;
129d5252 523 default:
524 fatal("%.200s line %d: Invalid RekeyLimit suffix",
525 filename, linenum);
ffd7b36b 526 }
129d5252 527 val64 *= scale;
528 /* detect integer wrap and too-large limits */
529 if ((val64 / scale) != orig || val64 > INT_MAX)
530 fatal("%.200s line %d: RekeyLimit too large",
531 filename, linenum);
532 if (val64 < 16)
533 fatal("%.200s line %d: RekeyLimit too small",
534 filename, linenum);
ffd7b36b 535 if (*activep && *intptr == -1)
129d5252 536 *intptr = (int)val64;
ffd7b36b 537 break;
538
5260325f 539 case oIdentityFile:
704b1659 540 arg = strdelim(&s);
089fbbd2 541 if (!arg || *arg == '\0')
5260325f 542 fatal("%.200s line %d: Missing argument.", filename, linenum);
543 if (*activep) {
fa08c86b 544 intptr = &options->num_identity_files;
a306f2dd 545 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 546 fatal("%.200s line %d: Too many identity files specified (max %d).",
184eed6a 547 filename, linenum, SSH_MAX_IDENTITY_FILES);
fa08c86b 548 charptr = &options->identity_files[*intptr];
089fbbd2 549 *charptr = xstrdup(arg);
a306f2dd 550 *intptr = *intptr + 1;
5260325f 551 }
552 break;
553
fa649821 554 case oXAuthLocation:
555 charptr=&options->xauth_location;
556 goto parse_string;
557
5260325f 558 case oUser:
559 charptr = &options->user;
560parse_string:
704b1659 561 arg = strdelim(&s);
089fbbd2 562 if (!arg || *arg == '\0')
5260325f 563 fatal("%.200s line %d: Missing argument.", filename, linenum);
564 if (*activep && *charptr == NULL)
089fbbd2 565 *charptr = xstrdup(arg);
5260325f 566 break;
567
568 case oGlobalKnownHostsFile:
569 charptr = &options->system_hostfile;
570 goto parse_string;
571
572 case oUserKnownHostsFile:
573 charptr = &options->user_hostfile;
574 goto parse_string;
575
a306f2dd 576 case oGlobalKnownHostsFile2:
577 charptr = &options->system_hostfile2;
578 goto parse_string;
579
580 case oUserKnownHostsFile2:
581 charptr = &options->user_hostfile2;
582 goto parse_string;
583
5260325f 584 case oHostName:
585 charptr = &options->hostname;
586 goto parse_string;
587
8abcdba4 588 case oHostKeyAlias:
589 charptr = &options->host_key_alias;
590 goto parse_string;
591
cab80f75 592 case oPreferredAuthentications:
593 charptr = &options->preferred_authentications;
594 goto parse_string;
595
3435f5a6 596 case oBindAddress:
597 charptr = &options->bind_address;
598 goto parse_string;
599
eea098a3 600 case oSmartcardDevice:
9ff6f66f 601 charptr = &options->smartcard_device;
602 goto parse_string;
eea098a3 603
5260325f 604 case oProxyCommand:
d20f3c9e 605 charptr = &options->proxy_command;
606parse_command:
2d9c1828 607 if (s == NULL)
608 fatal("%.200s line %d: Missing argument.", filename, linenum);
d718e75d 609 len = strspn(s, WHITESPACE "=");
5260325f 610 if (*activep && *charptr == NULL)
d718e75d 611 *charptr = xstrdup(s + len);
5260325f 612 return 0;
613
614 case oPort:
615 intptr = &options->port;
616parse_int:
704b1659 617 arg = strdelim(&s);
089fbbd2 618 if (!arg || *arg == '\0')
5260325f 619 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 620 if (arg[0] < '0' || arg[0] > '9')
5260325f 621 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 622
623 /* Octal, decimal, or hex format? */
089fbbd2 624 value = strtol(arg, &endofnumber, 0);
625 if (arg == endofnumber)
aa3378df 626 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 627 if (*activep && *intptr == -1)
628 *intptr = value;
629 break;
630
631 case oConnectionAttempts:
632 intptr = &options->connection_attempts;
633 goto parse_int;
634
635 case oCipher:
636 intptr = &options->cipher;
704b1659 637 arg = strdelim(&s);
089fbbd2 638 if (!arg || *arg == '\0')
71276795 639 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 640 value = cipher_number(arg);
5260325f 641 if (value == -1)
642 fatal("%.200s line %d: Bad cipher '%s'.",
184eed6a 643 filename, linenum, arg ? arg : "<NONE>");
5260325f 644 if (*activep && *intptr == -1)
645 *intptr = value;
646 break;
647
a8be9f80 648 case oCiphers:
704b1659 649 arg = strdelim(&s);
089fbbd2 650 if (!arg || *arg == '\0')
71276795 651 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 652 if (!ciphers_valid(arg))
d0c832f3 653 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
184eed6a 654 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 655 if (*activep && options->ciphers == NULL)
089fbbd2 656 options->ciphers = xstrdup(arg);
a8be9f80 657 break;
658
b2552997 659 case oMacs:
660 arg = strdelim(&s);
661 if (!arg || *arg == '\0')
662 fatal("%.200s line %d: Missing argument.", filename, linenum);
663 if (!mac_valid(arg))
664 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
184eed6a 665 filename, linenum, arg ? arg : "<NONE>");
b2552997 666 if (*activep && options->macs == NULL)
667 options->macs = xstrdup(arg);
668 break;
669
e961a8f9 670 case oHostKeyAlgorithms:
671 arg = strdelim(&s);
672 if (!arg || *arg == '\0')
673 fatal("%.200s line %d: Missing argument.", filename, linenum);
674 if (!key_names_valid2(arg))
675 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
184eed6a 676 filename, linenum, arg ? arg : "<NONE>");
e961a8f9 677 if (*activep && options->hostkeyalgorithms == NULL)
678 options->hostkeyalgorithms = xstrdup(arg);
679 break;
680
a8be9f80 681 case oProtocol:
682 intptr = &options->protocol;
704b1659 683 arg = strdelim(&s);
089fbbd2 684 if (!arg || *arg == '\0')
71276795 685 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 686 value = proto_spec(arg);
a8be9f80 687 if (value == SSH_PROTO_UNKNOWN)
688 fatal("%.200s line %d: Bad protocol spec '%s'.",
184eed6a 689 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 690 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
691 *intptr = value;
692 break;
693
5260325f 694 case oLogLevel:
695 intptr = (int *) &options->log_level;
704b1659 696 arg = strdelim(&s);
089fbbd2 697 value = log_level_number(arg);
5eaf8578 698 if (value == SYSLOG_LEVEL_NOT_SET)
54b974dc 699 fatal("%.200s line %d: unsupported log level '%s'",
184eed6a 700 filename, linenum, arg ? arg : "<NONE>");
5eaf8578 701 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
5260325f 702 *intptr = (LogLevel) value;
703 break;
704
5260325f 705 case oLocalForward:
3a8aabf0 706 case oRemoteForward:
704b1659 707 arg = strdelim(&s);
3867aa0a 708 if (arg == NULL || *arg == '\0')
3a8aabf0 709 fatal("%.200s line %d: Missing port argument.",
710 filename, linenum);
3867aa0a 711 arg2 = strdelim(&s);
712 if (arg2 == NULL || *arg2 == '\0')
713 fatal("%.200s line %d: Missing target argument.",
3a8aabf0 714 filename, linenum);
3867aa0a 715
716 /* construct a string for parse_forward */
717 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
718
719 if (parse_forward(&fwd, fwdarg) == 0)
3a8aabf0 720 fatal("%.200s line %d: Bad forwarding specification.",
721 filename, linenum);
3867aa0a 722
3a8aabf0 723 if (*activep) {
724 if (opcode == oLocalForward)
3867aa0a 725 add_local_forward(options, &fwd);
3a8aabf0 726 else if (opcode == oRemoteForward)
3867aa0a 727 add_remote_forward(options, &fwd);
3a8aabf0 728 }
5260325f 729 break;
730
0490e609 731 case oDynamicForward:
732 arg = strdelim(&s);
733 if (!arg || *arg == '\0')
734 fatal("%.200s line %d: Missing port argument.",
735 filename, linenum);
3867aa0a 736 memset(&fwd, '\0', sizeof(fwd));
737 fwd.connect_host = "socks";
738 fwd.listen_host = hpdelim(&arg);
739 if (fwd.listen_host == NULL ||
740 strlen(fwd.listen_host) >= NI_MAXHOST)
741 fatal("%.200s line %d: Bad forwarding specification.",
742 filename, linenum);
743 if (arg) {
744 fwd.listen_port = a2port(arg);
745 fwd.listen_host = cleanhostname(fwd.listen_host);
746 } else {
747 fwd.listen_port = a2port(fwd.listen_host);
4c38e9c6 748 fwd.listen_host = NULL;
3867aa0a 749 }
750 if (fwd.listen_port == 0)
0490e609 751 fatal("%.200s line %d: Badly formatted port number.",
752 filename, linenum);
14e4a15f 753 if (*activep)
3867aa0a 754 add_local_forward(options, &fwd);
8002af61 755 break;
0490e609 756
e1c5bfaf 757 case oClearAllForwardings:
758 intptr = &options->clear_forwardings;
759 goto parse_flag;
760
5260325f 761 case oHost:
762 *activep = 0;
704b1659 763 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 764 if (match_pattern(host, arg)) {
765 debug("Applying options for %.100s", arg);
5260325f 766 *activep = 1;
767 break;
768 }
704b1659 769 /* Avoid garbage check below, as strdelim is done. */
5260325f 770 return 0;
771
772 case oEscapeChar:
773 intptr = &options->escape_char;
704b1659 774 arg = strdelim(&s);
089fbbd2 775 if (!arg || *arg == '\0')
5260325f 776 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 777 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 778 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
779 value = (u_char) arg[1] & 31;
089fbbd2 780 else if (strlen(arg) == 1)
1e3b8b07 781 value = (u_char) arg[0];
089fbbd2 782 else if (strcmp(arg, "none") == 0)
4bf9c10e 783 value = SSH_ESCAPECHAR_NONE;
5260325f 784 else {
785 fatal("%.200s line %d: Bad escape character.",
184eed6a 786 filename, linenum);
5260325f 787 /* NOTREACHED */
788 value = 0; /* Avoid compiler warning. */
789 }
790 if (*activep && *intptr == -1)
791 *intptr = value;
792 break;
793
f811e52a 794 case oAddressFamily:
795 arg = strdelim(&s);
38634ff6 796 if (!arg || *arg == '\0')
797 fatal("%s line %d: missing address family.",
798 filename, linenum);
1572b90f 799 intptr = &options->address_family;
f811e52a 800 if (strcasecmp(arg, "inet") == 0)
1572b90f 801 value = AF_INET;
f811e52a 802 else if (strcasecmp(arg, "inet6") == 0)
1572b90f 803 value = AF_INET6;
f811e52a 804 else if (strcasecmp(arg, "any") == 0)
1572b90f 805 value = AF_UNSPEC;
f811e52a 806 else
807 fatal("Unsupported AddressFamily \"%s\"", arg);
1572b90f 808 if (*activep && *intptr == -1)
809 *intptr = value;
f811e52a 810 break;
811
cc46e2ee 812 case oEnableSSHKeysign:
813 intptr = &options->enable_ssh_keysign;
814 goto parse_flag;
815
3a065ed0 816 case oIdentitiesOnly:
817 intptr = &options->identities_only;
818 goto parse_flag;
819
5d8d32a3 820 case oServerAliveInterval:
821 intptr = &options->server_alive_interval;
822 goto parse_time;
823
824 case oServerAliveCountMax:
825 intptr = &options->server_alive_count_max;
826 goto parse_int;
827
61a2c1da 828 case oSendEnv:
829 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
830 if (strchr(arg, '=') != NULL)
831 fatal("%s line %d: Invalid environment name.",
832 filename, linenum);
c8c99dd5 833 if (!*activep)
834 continue;
61a2c1da 835 if (options->num_send_env >= MAX_SEND_ENV)
836 fatal("%s line %d: too many send env.",
837 filename, linenum);
838 options->send_env[options->num_send_env++] =
839 xstrdup(arg);
840 }
841 break;
842
5e96b616 843 case oControlPath:
844 charptr = &options->control_path;
845 goto parse_string;
846
847 case oControlMaster:
848 intptr = &options->control_master;
9dfd96d6 849 arg = strdelim(&s);
850 if (!arg || *arg == '\0')
851 fatal("%.200s line %d: Missing ControlMaster argument.",
852 filename, linenum);
853 value = 0; /* To avoid compiler warning... */
854 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
855 value = SSHCTL_MASTER_YES;
856 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
857 value = SSHCTL_MASTER_NO;
858 else if (strcmp(arg, "auto") == 0)
859 value = SSHCTL_MASTER_AUTO;
860 else if (strcmp(arg, "ask") == 0)
861 value = SSHCTL_MASTER_ASK;
862 else if (strcmp(arg, "autoask") == 0)
863 value = SSHCTL_MASTER_AUTO_ASK;
864 else
865 fatal("%.200s line %d: Bad ControlMaster argument.",
866 filename, linenum);
867 if (*activep && *intptr == -1)
868 *intptr = value;
869 break;
5e96b616 870
5c63c2ab 871 case oHashKnownHosts:
872 intptr = &options->hash_known_hosts;
873 goto parse_flag;
874
d20f3c9e 875 case oTunnel:
876 intptr = &options->tun_open;
a4f24bf8 877 arg = strdelim(&s);
878 if (!arg || *arg == '\0')
879 fatal("%s line %d: Missing yes/point-to-point/"
880 "ethernet/no argument.", filename, linenum);
881 value = 0; /* silence compiler */
882 if (strcasecmp(arg, "ethernet") == 0)
883 value = SSH_TUNMODE_ETHERNET;
884 else if (strcasecmp(arg, "point-to-point") == 0)
885 value = SSH_TUNMODE_POINTOPOINT;
886 else if (strcasecmp(arg, "yes") == 0)
887 value = SSH_TUNMODE_DEFAULT;
888 else if (strcasecmp(arg, "no") == 0)
889 value = SSH_TUNMODE_NO;
890 else
891 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
892 "no argument: %s", filename, linenum, arg);
893 if (*activep)
894 *intptr = value;
895 break;
d20f3c9e 896
897 case oTunnelDevice:
898 arg = strdelim(&s);
899 if (!arg || *arg == '\0')
900 fatal("%.200s line %d: Missing argument.", filename, linenum);
901 value = a2tun(arg, &value2);
a4f24bf8 902 if (value == SSH_TUNID_ERR)
d20f3c9e 903 fatal("%.200s line %d: Bad tun device.", filename, linenum);
904 if (*activep) {
905 options->tun_local = value;
906 options->tun_remote = value2;
907 }
908 break;
909
910 case oLocalCommand:
911 charptr = &options->local_command;
912 goto parse_command;
913
914 case oPermitLocalCommand:
915 intptr = &options->permit_local_command;
916 goto parse_flag;
917
80fcb74e 918 case oDeprecated:
4feae93d 919 debug("%s line %d: Deprecated option \"%s\"",
80fcb74e 920 filename, linenum, keyword);
4feae93d 921 return 0;
80fcb74e 922
a2144546 923 case oUnsupported:
924 error("%s line %d: Unsupported option \"%s\"",
925 filename, linenum, keyword);
926 return 0;
927
5260325f 928 default:
929 fatal("process_config_line: Unimplemented opcode %d", opcode);
930 }
931
932 /* Check that there is no garbage at end of line. */
42f11eb2 933 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 934 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
4e2e5cfd 935 filename, linenum, arg);
089fbbd2 936 }
5260325f 937 return 0;
8efc0c15 938}
939
940
aa3378df 941/*
942 * Reads the config file and modifies the options accordingly. Options
943 * should already be initialized before this call. This never returns if
93111dfa 944 * there is an error. If the file does not exist, this returns 0.
aa3378df 945 */
8efc0c15 946
93111dfa 947int
f2107e97 948read_config_file(const char *filename, const char *host, Options *options,
9f6cab4b 949 int checkperm)
8efc0c15 950{
5260325f 951 FILE *f;
952 char line[1024];
953 int active, linenum;
954 int bad_options = 0;
955
956 /* Open the file. */
9f6cab4b 957 if ((f = fopen(filename, "r")) == NULL)
93111dfa 958 return 0;
5260325f 959
9f6cab4b 960 if (checkperm) {
961 struct stat sb;
f2107e97 962
f9ee425b 963 if (fstat(fileno(f), &sb) == -1)
9f6cab4b 964 fatal("fstat %s: %s", filename, strerror(errno));
9f6cab4b 965 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
f9ee425b 966 (sb.st_mode & 022) != 0))
9f6cab4b 967 fatal("Bad owner or permissions on %s", filename);
9f6cab4b 968 }
969
5260325f 970 debug("Reading configuration data %.200s", filename);
971
aa3378df 972 /*
973 * Mark that we are now processing the options. This flag is turned
974 * on/off by Host specifications.
975 */
5260325f 976 active = 1;
977 linenum = 0;
978 while (fgets(line, sizeof(line), f)) {
979 /* Update line number counter. */
980 linenum++;
981 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
982 bad_options++;
983 }
984 fclose(f);
985 if (bad_options > 0)
54b974dc 986 fatal("%s: terminating, %d bad configuration options",
184eed6a 987 filename, bad_options);
93111dfa 988 return 1;
8efc0c15 989}
990
aa3378df 991/*
992 * Initializes options to special values that indicate that they have not yet
993 * been set. Read_config_file will only set options with this value. Options
994 * are processed in the following order: command line, user config file,
995 * system config file. Last, fill_default_options is called.
996 */
8efc0c15 997
6ae2364d 998void
5260325f 999initialize_options(Options * options)
8efc0c15 1000{
5260325f 1001 memset(options, 'X', sizeof(*options));
1002 options->forward_agent = -1;
1003 options->forward_x11 = -1;
d73a67d7 1004 options->forward_x11_trusted = -1;
42ea6f5e 1005 options->exit_on_forward_failure = -1;
fa649821 1006 options->xauth_location = NULL;
5260325f 1007 options->gateway_ports = -1;
1008 options->use_privileged_port = -1;
5260325f 1009 options->rsa_authentication = -1;
fa08c86b 1010 options->pubkey_authentication = -1;
5ba55ada 1011 options->challenge_response_authentication = -1;
7364bd04 1012 options->gss_authentication = -1;
1013 options->gss_deleg_creds = -1;
5260325f 1014 options->password_authentication = -1;
94ec8c6b 1015 options->kbd_interactive_authentication = -1;
1016 options->kbd_interactive_devices = NULL;
5260325f 1017 options->rhosts_rsa_authentication = -1;
8002af61 1018 options->hostbased_authentication = -1;
5260325f 1019 options->batch_mode = -1;
1020 options->check_host_ip = -1;
1021 options->strict_host_key_checking = -1;
1022 options->compression = -1;
fd573618 1023 options->tcp_keep_alive = -1;
5260325f 1024 options->compression_level = -1;
1025 options->port = -1;
1572b90f 1026 options->address_family = -1;
5260325f 1027 options->connection_attempts = -1;
09ab3296 1028 options->connection_timeout = -1;
5260325f 1029 options->number_of_password_prompts = -1;
1030 options->cipher = -1;
a8be9f80 1031 options->ciphers = NULL;
b2552997 1032 options->macs = NULL;
e961a8f9 1033 options->hostkeyalgorithms = NULL;
a8be9f80 1034 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 1035 options->num_identity_files = 0;
1036 options->hostname = NULL;
8abcdba4 1037 options->host_key_alias = NULL;
5260325f 1038 options->proxy_command = NULL;
1039 options->user = NULL;
1040 options->escape_char = -1;
1041 options->system_hostfile = NULL;
1042 options->user_hostfile = NULL;
a306f2dd 1043 options->system_hostfile2 = NULL;
1044 options->user_hostfile2 = NULL;
5260325f 1045 options->num_local_forwards = 0;
1046 options->num_remote_forwards = 0;
e1c5bfaf 1047 options->clear_forwardings = -1;
5eaf8578 1048 options->log_level = SYSLOG_LEVEL_NOT_SET;
cab80f75 1049 options->preferred_authentications = NULL;
3435f5a6 1050 options->bind_address = NULL;
9ff6f66f 1051 options->smartcard_device = NULL;
cc46e2ee 1052 options->enable_ssh_keysign = - 1;
8bbc048a 1053 options->no_host_authentication_for_localhost = - 1;
3a065ed0 1054 options->identities_only = - 1;
ffd7b36b 1055 options->rekey_limit = - 1;
21289cd0 1056 options->verify_host_key_dns = -1;
5d8d32a3 1057 options->server_alive_interval = -1;
1058 options->server_alive_count_max = -1;
61a2c1da 1059 options->num_send_env = 0;
5e96b616 1060 options->control_path = NULL;
1061 options->control_master = -1;
5c63c2ab 1062 options->hash_known_hosts = -1;
d20f3c9e 1063 options->tun_open = -1;
1064 options->tun_local = -1;
1065 options->tun_remote = -1;
1066 options->local_command = NULL;
1067 options->permit_local_command = -1;
8efc0c15 1068}
1069
aa3378df 1070/*
1071 * Called after processing other sources of option data, this fills those
1072 * options for which no value has been specified with their default values.
1073 */
8efc0c15 1074
6ae2364d 1075void
5260325f 1076fill_default_options(Options * options)
8efc0c15 1077{
d2c46e77 1078 int len;
1079
5260325f 1080 if (options->forward_agent == -1)
71276795 1081 options->forward_agent = 0;
5260325f 1082 if (options->forward_x11 == -1)
c8d54615 1083 options->forward_x11 = 0;
d73a67d7 1084 if (options->forward_x11_trusted == -1)
1085 options->forward_x11_trusted = 0;
42ea6f5e 1086 if (options->exit_on_forward_failure == -1)
1087 options->exit_on_forward_failure = 0;
fa649821 1088 if (options->xauth_location == NULL)
fd9ede94 1089 options->xauth_location = _PATH_XAUTH;
5260325f 1090 if (options->gateway_ports == -1)
1091 options->gateway_ports = 0;
1092 if (options->use_privileged_port == -1)
d5ebca2b 1093 options->use_privileged_port = 0;
5260325f 1094 if (options->rsa_authentication == -1)
1095 options->rsa_authentication = 1;
fa08c86b 1096 if (options->pubkey_authentication == -1)
1097 options->pubkey_authentication = 1;
5ba55ada 1098 if (options->challenge_response_authentication == -1)
10a2cbef 1099 options->challenge_response_authentication = 1;
7364bd04 1100 if (options->gss_authentication == -1)
2ecb78df 1101 options->gss_authentication = 0;
7364bd04 1102 if (options->gss_deleg_creds == -1)
1103 options->gss_deleg_creds = 0;
5260325f 1104 if (options->password_authentication == -1)
1105 options->password_authentication = 1;
94ec8c6b 1106 if (options->kbd_interactive_authentication == -1)
d464095c 1107 options->kbd_interactive_authentication = 1;
5260325f 1108 if (options->rhosts_rsa_authentication == -1)
4b3d23b4 1109 options->rhosts_rsa_authentication = 0;
8002af61 1110 if (options->hostbased_authentication == -1)
1111 options->hostbased_authentication = 0;
5260325f 1112 if (options->batch_mode == -1)
1113 options->batch_mode = 0;
1114 if (options->check_host_ip == -1)
1115 options->check_host_ip = 1;
1116 if (options->strict_host_key_checking == -1)
1117 options->strict_host_key_checking = 2; /* 2 is default */
1118 if (options->compression == -1)
1119 options->compression = 0;
fd573618 1120 if (options->tcp_keep_alive == -1)
1121 options->tcp_keep_alive = 1;
5260325f 1122 if (options->compression_level == -1)
1123 options->compression_level = 6;
1124 if (options->port == -1)
1125 options->port = 0; /* Filled in ssh_connect. */
1572b90f 1126 if (options->address_family == -1)
1127 options->address_family = AF_UNSPEC;
5260325f 1128 if (options->connection_attempts == -1)
ce773142 1129 options->connection_attempts = 1;
5260325f 1130 if (options->number_of_password_prompts == -1)
1131 options->number_of_password_prompts = 3;
1132 /* Selected in ssh_login(). */
1133 if (options->cipher == -1)
1134 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 1135 /* options->ciphers, default set in myproposals.h */
b2552997 1136 /* options->macs, default set in myproposals.h */
e961a8f9 1137 /* options->hostkeyalgorithms, default set in myproposals.h */
a8be9f80 1138 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 1139 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 1140 if (options->num_identity_files == 0) {
fa08c86b 1141 if (options->protocol & SSH_PROTO_1) {
d2c46e77 1142 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 1143 options->identity_files[options->num_identity_files] =
d2c46e77 1144 xmalloc(len);
1145 snprintf(options->identity_files[options->num_identity_files++],
1146 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 1147 }
1148 if (options->protocol & SSH_PROTO_2) {
ec63b02d 1149 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1150 options->identity_files[options->num_identity_files] =
1151 xmalloc(len);
1152 snprintf(options->identity_files[options->num_identity_files++],
1153 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1154
d2c46e77 1155 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 1156 options->identity_files[options->num_identity_files] =
d2c46e77 1157 xmalloc(len);
1158 snprintf(options->identity_files[options->num_identity_files++],
1159 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 1160 }
a306f2dd 1161 }
5260325f 1162 if (options->escape_char == -1)
1163 options->escape_char = '~';
1164 if (options->system_hostfile == NULL)
42f11eb2 1165 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 1166 if (options->user_hostfile == NULL)
42f11eb2 1167 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 1168 if (options->system_hostfile2 == NULL)
42f11eb2 1169 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 1170 if (options->user_hostfile2 == NULL)
42f11eb2 1171 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5eaf8578 1172 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
59c97189 1173 options->log_level = SYSLOG_LEVEL_INFO;
e1c5bfaf 1174 if (options->clear_forwardings == 1)
1175 clear_forwardings(options);
8bbc048a 1176 if (options->no_host_authentication_for_localhost == - 1)
1177 options->no_host_authentication_for_localhost = 0;
3a065ed0 1178 if (options->identities_only == -1)
1179 options->identities_only = 0;
cc46e2ee 1180 if (options->enable_ssh_keysign == -1)
1181 options->enable_ssh_keysign = 0;
ffd7b36b 1182 if (options->rekey_limit == -1)
1183 options->rekey_limit = 0;
21289cd0 1184 if (options->verify_host_key_dns == -1)
1185 options->verify_host_key_dns = 0;
5d8d32a3 1186 if (options->server_alive_interval == -1)
1187 options->server_alive_interval = 0;
1188 if (options->server_alive_count_max == -1)
1189 options->server_alive_count_max = 3;
5e96b616 1190 if (options->control_master == -1)
1191 options->control_master = 0;
5c63c2ab 1192 if (options->hash_known_hosts == -1)
1193 options->hash_known_hosts = 0;
d20f3c9e 1194 if (options->tun_open == -1)
a4f24bf8 1195 options->tun_open = SSH_TUNMODE_NO;
1196 if (options->tun_local == -1)
1197 options->tun_local = SSH_TUNID_ANY;
1198 if (options->tun_remote == -1)
1199 options->tun_remote = SSH_TUNID_ANY;
d20f3c9e 1200 if (options->permit_local_command == -1)
1201 options->permit_local_command = 0;
1202 /* options->local_command should not be set by default */
5260325f 1203 /* options->proxy_command should not be set by default */
1204 /* options->user will be set in the main program if appropriate */
1205 /* options->hostname will be set in the main program if appropriate */
8abcdba4 1206 /* options->host_key_alias should not be set by default */
cab80f75 1207 /* options->preferred_authentications will be set in ssh */
8efc0c15 1208}
3867aa0a 1209
1210/*
1211 * parse_forward
1212 * parses a string containing a port forwarding specification of the form:
1213 * [listenhost:]listenport:connecthost:connectport
1214 * returns number of arguments parsed or zero on error
1215 */
1216int
1217parse_forward(Forward *fwd, const char *fwdspec)
1218{
1219 int i;
1220 char *p, *cp, *fwdarg[4];
1221
1222 memset(fwd, '\0', sizeof(*fwd));
1223
1224 cp = p = xstrdup(fwdspec);
1225
1226 /* skip leading spaces */
1227 while (*cp && isspace(*cp))
1228 cp++;
1229
1230 for (i = 0; i < 4; ++i)
1231 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1232 break;
1233
1234 /* Check for trailing garbage in 4-arg case*/
1235 if (cp != NULL)
1236 i = 0; /* failure */
1237
1238 switch (i) {
1239 case 3:
1240 fwd->listen_host = NULL;
1241 fwd->listen_port = a2port(fwdarg[0]);
1242 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1243 fwd->connect_port = a2port(fwdarg[2]);
1244 break;
1245
1246 case 4:
1247 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1248 fwd->listen_port = a2port(fwdarg[1]);
1249 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1250 fwd->connect_port = a2port(fwdarg[3]);
1251 break;
1252 default:
1253 i = 0; /* failure */
1254 }
1255
1256 xfree(p);
1257
1258 if (fwd->listen_port == 0 && fwd->connect_port == 0)
1259 goto fail_free;
1260
1261 if (fwd->connect_host != NULL &&
1262 strlen(fwd->connect_host) >= NI_MAXHOST)
1263 goto fail_free;
1264
1265 return (i);
1266
1267 fail_free:
1268 if (fwd->connect_host != NULL)
1269 xfree(fwd->connect_host);
1270 if (fwd->listen_host != NULL)
1271 xfree(fwd->listen_host);
1272 return (0);
1273}
This page took 3.011683 seconds and 5 git commands to generate.