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