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