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