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