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