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