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