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