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