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