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