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