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