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