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