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