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