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