readconf.c revision 1.8 1 1.8 christos /* $NetBSD: readconf.c,v 1.8 2012/05/02 02:41:08 christos Exp $ */
2 1.8 christos /* $OpenBSD: readconf.c,v 1.194 2011/09/23 07:45:05 markus Exp $ */
3 1.1 christos /*
4 1.1 christos * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
5 1.1 christos * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
6 1.1 christos * All rights reserved
7 1.1 christos * Functions for reading the configuration files.
8 1.1 christos *
9 1.1 christos * As far as I am concerned, the code I have written for this software
10 1.1 christos * can be used freely for any purpose. Any derived versions of this
11 1.1 christos * software must be clearly marked as such, and if the derived work is
12 1.1 christos * incompatible with the protocol description in the RFC file, it must be
13 1.1 christos * called by a name other than "ssh" or "Secure Shell".
14 1.1 christos */
15 1.1 christos
16 1.2 christos #include "includes.h"
17 1.8 christos __RCSID("$NetBSD: readconf.c,v 1.8 2012/05/02 02:41:08 christos Exp $");
18 1.1 christos #include <sys/types.h>
19 1.1 christos #include <sys/stat.h>
20 1.1 christos #include <sys/socket.h>
21 1.1 christos
22 1.1 christos #include <netinet/in.h>
23 1.5 christos #include <netinet/in_systm.h>
24 1.5 christos #include <netinet/ip.h>
25 1.1 christos
26 1.1 christos #include <ctype.h>
27 1.1 christos #include <errno.h>
28 1.1 christos #include <netdb.h>
29 1.1 christos #include <signal.h>
30 1.1 christos #include <stdio.h>
31 1.1 christos #include <string.h>
32 1.1 christos #include <unistd.h>
33 1.2 christos #include <limits.h>
34 1.1 christos
35 1.1 christos #include "xmalloc.h"
36 1.1 christos #include "ssh.h"
37 1.1 christos #include "compat.h"
38 1.1 christos #include "cipher.h"
39 1.1 christos #include "pathnames.h"
40 1.1 christos #include "log.h"
41 1.1 christos #include "key.h"
42 1.1 christos #include "readconf.h"
43 1.1 christos #include "match.h"
44 1.1 christos #include "misc.h"
45 1.1 christos #include "buffer.h"
46 1.1 christos #include "kex.h"
47 1.1 christos #include "mac.h"
48 1.1 christos
49 1.1 christos /* Format of the configuration file:
50 1.1 christos
51 1.1 christos # Configuration data is parsed as follows:
52 1.1 christos # 1. command line options
53 1.1 christos # 2. user-specific file
54 1.1 christos # 3. system-wide file
55 1.1 christos # Any configuration value is only changed the first time it is set.
56 1.1 christos # Thus, host-specific definitions should be at the beginning of the
57 1.1 christos # configuration file, and defaults at the end.
58 1.1 christos
59 1.1 christos # Host-specific declarations. These may override anything above. A single
60 1.1 christos # host may match multiple declarations; these are processed in the order
61 1.1 christos # that they are given in.
62 1.1 christos
63 1.1 christos Host *.ngs.fi ngs.fi
64 1.1 christos User foo
65 1.1 christos
66 1.1 christos Host fake.com
67 1.1 christos HostName another.host.name.real.org
68 1.1 christos User blaah
69 1.1 christos Port 34289
70 1.1 christos ForwardX11 no
71 1.1 christos ForwardAgent no
72 1.1 christos
73 1.1 christos Host books.com
74 1.1 christos RemoteForward 9999 shadows.cs.hut.fi:9999
75 1.1 christos Cipher 3des
76 1.1 christos
77 1.1 christos Host fascist.blob.com
78 1.1 christos Port 23123
79 1.1 christos User tylonen
80 1.1 christos PasswordAuthentication no
81 1.1 christos
82 1.1 christos Host puukko.hut.fi
83 1.1 christos User t35124p
84 1.1 christos ProxyCommand ssh-proxy %h %p
85 1.1 christos
86 1.1 christos Host *.fr
87 1.1 christos PublicKeyAuthentication no
88 1.1 christos
89 1.1 christos Host *.su
90 1.1 christos Cipher none
91 1.1 christos PasswordAuthentication no
92 1.1 christos
93 1.1 christos Host vpn.fake.com
94 1.1 christos Tunnel yes
95 1.1 christos TunnelDevice 3
96 1.1 christos
97 1.1 christos # Defaults for various options
98 1.1 christos Host *
99 1.1 christos ForwardAgent no
100 1.1 christos ForwardX11 no
101 1.1 christos PasswordAuthentication yes
102 1.1 christos RSAAuthentication yes
103 1.1 christos RhostsRSAAuthentication yes
104 1.1 christos StrictHostKeyChecking yes
105 1.1 christos TcpKeepAlive no
106 1.1 christos IdentityFile ~/.ssh/identity
107 1.1 christos Port 22
108 1.1 christos EscapeChar ~
109 1.1 christos
110 1.1 christos */
111 1.1 christos
112 1.1 christos /* Keyword tokens. */
113 1.1 christos
114 1.1 christos typedef enum {
115 1.1 christos oBadOption,
116 1.4 adam oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
117 1.4 adam oGatewayPorts, oExitOnForwardFailure,
118 1.1 christos oPasswordAuthentication, oRSAAuthentication,
119 1.1 christos oChallengeResponseAuthentication, oXAuthLocation,
120 1.2 christos #if defined(KRB4) || defined(KRB5)
121 1.2 christos oKerberosAuthentication,
122 1.2 christos #endif
123 1.2 christos #if defined(AFS) || defined(KRB5)
124 1.2 christos oKerberosTgtPassing,
125 1.2 christos #endif
126 1.2 christos #ifdef AFS
127 1.2 christos oAFSTokenPassing,
128 1.2 christos #endif
129 1.1 christos oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
130 1.1 christos oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
131 1.1 christos oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
132 1.1 christos oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
133 1.1 christos oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
134 1.1 christos oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
135 1.1 christos oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
136 1.1 christos oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
137 1.1 christos oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
138 1.4 adam oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
139 1.1 christos oClearAllForwardings, oNoHostAuthenticationForLocalhost,
140 1.1 christos oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
141 1.1 christos oAddressFamily, oGssAuthentication, oGssDelegateCreds,
142 1.1 christos oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
143 1.4 adam oSendEnv, oControlPath, oControlMaster, oControlPersist,
144 1.4 adam oHashKnownHosts,
145 1.1 christos oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
146 1.3 christos oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
147 1.6 christos oKexAlgorithms, oIPQoS, oRequestTTY,
148 1.2 christos oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
149 1.2 christos oHPNBufferSize,
150 1.7 tls oSendVersionFirst,
151 1.1 christos oDeprecated, oUnsupported
152 1.1 christos } OpCodes;
153 1.1 christos
154 1.1 christos /* Textual representations of the tokens. */
155 1.1 christos
156 1.1 christos static struct {
157 1.1 christos const char *name;
158 1.1 christos OpCodes opcode;
159 1.1 christos } keywords[] = {
160 1.1 christos { "forwardagent", oForwardAgent },
161 1.1 christos { "forwardx11", oForwardX11 },
162 1.1 christos { "forwardx11trusted", oForwardX11Trusted },
163 1.4 adam { "forwardx11timeout", oForwardX11Timeout },
164 1.1 christos { "exitonforwardfailure", oExitOnForwardFailure },
165 1.1 christos { "xauthlocation", oXAuthLocation },
166 1.1 christos { "gatewayports", oGatewayPorts },
167 1.1 christos { "useprivilegedport", oUsePrivilegedPort },
168 1.1 christos { "rhostsauthentication", oDeprecated },
169 1.1 christos { "passwordauthentication", oPasswordAuthentication },
170 1.1 christos { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
171 1.1 christos { "kbdinteractivedevices", oKbdInteractiveDevices },
172 1.1 christos { "rsaauthentication", oRSAAuthentication },
173 1.1 christos { "pubkeyauthentication", oPubkeyAuthentication },
174 1.1 christos { "dsaauthentication", oPubkeyAuthentication }, /* alias */
175 1.1 christos { "rhostsrsaauthentication", oRhostsRSAAuthentication },
176 1.1 christos { "hostbasedauthentication", oHostbasedAuthentication },
177 1.1 christos { "challengeresponseauthentication", oChallengeResponseAuthentication },
178 1.1 christos { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
179 1.1 christos { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
180 1.2 christos #if defined(KRB4) || defined(KRB5)
181 1.2 christos { "kerberosauthentication", oKerberosAuthentication },
182 1.2 christos #endif
183 1.2 christos #if defined(AFS) || defined(KRB5)
184 1.2 christos { "kerberostgtpassing", oKerberosTgtPassing },
185 1.2 christos { "kerberos5tgtpassing", oKerberosTgtPassing }, /* alias */
186 1.2 christos { "kerberos4tgtpassing", oKerberosTgtPassing }, /* alias */
187 1.2 christos #endif
188 1.2 christos #ifdef AFS
189 1.2 christos { "afstokenpassing", oAFSTokenPassing },
190 1.2 christos #endif
191 1.1 christos #if defined(GSSAPI)
192 1.1 christos { "gssapiauthentication", oGssAuthentication },
193 1.1 christos { "gssapidelegatecredentials", oGssDelegateCreds },
194 1.1 christos #else
195 1.1 christos { "gssapiauthentication", oUnsupported },
196 1.1 christos { "gssapidelegatecredentials", oUnsupported },
197 1.1 christos #endif
198 1.1 christos { "fallbacktorsh", oDeprecated },
199 1.1 christos { "usersh", oDeprecated },
200 1.1 christos { "identityfile", oIdentityFile },
201 1.1 christos { "identityfile2", oIdentityFile }, /* obsolete */
202 1.1 christos { "identitiesonly", oIdentitiesOnly },
203 1.1 christos { "hostname", oHostName },
204 1.1 christos { "hostkeyalias", oHostKeyAlias },
205 1.1 christos { "proxycommand", oProxyCommand },
206 1.1 christos { "port", oPort },
207 1.1 christos { "cipher", oCipher },
208 1.1 christos { "ciphers", oCiphers },
209 1.1 christos { "macs", oMacs },
210 1.1 christos { "protocol", oProtocol },
211 1.1 christos { "remoteforward", oRemoteForward },
212 1.1 christos { "localforward", oLocalForward },
213 1.1 christos { "user", oUser },
214 1.1 christos { "host", oHost },
215 1.1 christos { "escapechar", oEscapeChar },
216 1.1 christos { "globalknownhostsfile", oGlobalKnownHostsFile },
217 1.6 christos { "globalknownhostsfile2", oDeprecated },
218 1.1 christos { "userknownhostsfile", oUserKnownHostsFile },
219 1.6 christos { "userknownhostsfile2", oDeprecated },
220 1.1 christos { "connectionattempts", oConnectionAttempts },
221 1.1 christos { "batchmode", oBatchMode },
222 1.1 christos { "checkhostip", oCheckHostIP },
223 1.1 christos { "stricthostkeychecking", oStrictHostKeyChecking },
224 1.1 christos { "compression", oCompression },
225 1.1 christos { "compressionlevel", oCompressionLevel },
226 1.1 christos { "tcpkeepalive", oTCPKeepAlive },
227 1.1 christos { "keepalive", oTCPKeepAlive }, /* obsolete */
228 1.1 christos { "numberofpasswordprompts", oNumberOfPasswordPrompts },
229 1.1 christos { "loglevel", oLogLevel },
230 1.1 christos { "dynamicforward", oDynamicForward },
231 1.1 christos { "preferredauthentications", oPreferredAuthentications },
232 1.1 christos { "hostkeyalgorithms", oHostKeyAlgorithms },
233 1.1 christos { "bindaddress", oBindAddress },
234 1.4 adam #ifdef ENABLE_PKCS11
235 1.4 adam { "smartcarddevice", oPKCS11Provider },
236 1.4 adam { "pkcs11provider", oPKCS11Provider },
237 1.1 christos #else
238 1.1 christos { "smartcarddevice", oUnsupported },
239 1.4 adam { "pkcs11provider", oUnsupported },
240 1.1 christos #endif
241 1.1 christos { "clearallforwardings", oClearAllForwardings },
242 1.1 christos { "enablesshkeysign", oEnableSSHKeysign },
243 1.1 christos { "verifyhostkeydns", oVerifyHostKeyDNS },
244 1.1 christos { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
245 1.1 christos { "rekeylimit", oRekeyLimit },
246 1.1 christos { "connecttimeout", oConnectTimeout },
247 1.1 christos { "addressfamily", oAddressFamily },
248 1.1 christos { "serveraliveinterval", oServerAliveInterval },
249 1.1 christos { "serveralivecountmax", oServerAliveCountMax },
250 1.1 christos { "sendenv", oSendEnv },
251 1.1 christos { "controlpath", oControlPath },
252 1.1 christos { "controlmaster", oControlMaster },
253 1.4 adam { "controlpersist", oControlPersist },
254 1.1 christos { "hashknownhosts", oHashKnownHosts },
255 1.1 christos { "tunnel", oTunnel },
256 1.1 christos { "tunneldevice", oTunnelDevice },
257 1.1 christos { "localcommand", oLocalCommand },
258 1.1 christos { "permitlocalcommand", oPermitLocalCommand },
259 1.1 christos { "visualhostkey", oVisualHostKey },
260 1.3 christos { "useroaming", oUseRoaming },
261 1.1 christos #ifdef JPAKE
262 1.1 christos { "zeroknowledgepasswordauthentication",
263 1.1 christos oZeroKnowledgePasswordAuthentication },
264 1.1 christos #else
265 1.1 christos { "zeroknowledgepasswordauthentication", oUnsupported },
266 1.1 christos #endif
267 1.5 christos { "kexalgorithms", oKexAlgorithms },
268 1.5 christos { "ipqos", oIPQoS },
269 1.6 christos { "requesttty", oRequestTTY },
270 1.2 christos { "noneenabled", oNoneEnabled },
271 1.2 christos { "tcprcvbufpoll", oTcpRcvBufPoll },
272 1.2 christos { "tcprcvbuf", oTcpRcvBuf },
273 1.2 christos { "noneswitch", oNoneSwitch },
274 1.2 christos { "hpndisabled", oHPNDisabled },
275 1.2 christos { "hpnbuffersize", oHPNBufferSize },
276 1.7 tls { "sendversionfirst", oSendVersionFirst },
277 1.5 christos
278 1.1 christos { NULL, oBadOption }
279 1.1 christos };
280 1.1 christos
281 1.1 christos /*
282 1.1 christos * Adds a local TCP/IP port forward to options. Never returns if there is an
283 1.1 christos * error.
284 1.1 christos */
285 1.1 christos
286 1.1 christos void
287 1.1 christos add_local_forward(Options *options, const Forward *newfwd)
288 1.1 christos {
289 1.1 christos Forward *fwd;
290 1.1 christos extern uid_t original_real_uid;
291 1.4 adam
292 1.1 christos if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
293 1.1 christos fatal("Privileged ports can only be forwarded by root.");
294 1.4 adam options->local_forwards = xrealloc(options->local_forwards,
295 1.4 adam options->num_local_forwards + 1,
296 1.4 adam sizeof(*options->local_forwards));
297 1.1 christos fwd = &options->local_forwards[options->num_local_forwards++];
298 1.1 christos
299 1.1 christos fwd->listen_host = newfwd->listen_host;
300 1.1 christos fwd->listen_port = newfwd->listen_port;
301 1.1 christos fwd->connect_host = newfwd->connect_host;
302 1.1 christos fwd->connect_port = newfwd->connect_port;
303 1.1 christos }
304 1.1 christos
305 1.1 christos /*
306 1.1 christos * Adds a remote TCP/IP port forward to options. Never returns if there is
307 1.1 christos * an error.
308 1.1 christos */
309 1.1 christos
310 1.1 christos void
311 1.1 christos add_remote_forward(Options *options, const Forward *newfwd)
312 1.1 christos {
313 1.1 christos Forward *fwd;
314 1.4 adam
315 1.4 adam options->remote_forwards = xrealloc(options->remote_forwards,
316 1.4 adam options->num_remote_forwards + 1,
317 1.4 adam sizeof(*options->remote_forwards));
318 1.1 christos fwd = &options->remote_forwards[options->num_remote_forwards++];
319 1.1 christos
320 1.1 christos fwd->listen_host = newfwd->listen_host;
321 1.1 christos fwd->listen_port = newfwd->listen_port;
322 1.1 christos fwd->connect_host = newfwd->connect_host;
323 1.1 christos fwd->connect_port = newfwd->connect_port;
324 1.8 christos fwd->handle = newfwd->handle;
325 1.4 adam fwd->allocated_port = 0;
326 1.1 christos }
327 1.1 christos
328 1.1 christos static void
329 1.1 christos clear_forwardings(Options *options)
330 1.1 christos {
331 1.1 christos int i;
332 1.1 christos
333 1.1 christos for (i = 0; i < options->num_local_forwards; i++) {
334 1.1 christos if (options->local_forwards[i].listen_host != NULL)
335 1.1 christos xfree(options->local_forwards[i].listen_host);
336 1.1 christos xfree(options->local_forwards[i].connect_host);
337 1.1 christos }
338 1.4 adam if (options->num_local_forwards > 0) {
339 1.4 adam xfree(options->local_forwards);
340 1.4 adam options->local_forwards = NULL;
341 1.4 adam }
342 1.1 christos options->num_local_forwards = 0;
343 1.1 christos for (i = 0; i < options->num_remote_forwards; i++) {
344 1.1 christos if (options->remote_forwards[i].listen_host != NULL)
345 1.1 christos xfree(options->remote_forwards[i].listen_host);
346 1.1 christos xfree(options->remote_forwards[i].connect_host);
347 1.1 christos }
348 1.4 adam if (options->num_remote_forwards > 0) {
349 1.4 adam xfree(options->remote_forwards);
350 1.4 adam options->remote_forwards = NULL;
351 1.4 adam }
352 1.1 christos options->num_remote_forwards = 0;
353 1.1 christos options->tun_open = SSH_TUNMODE_NO;
354 1.1 christos }
355 1.1 christos
356 1.1 christos /*
357 1.1 christos * Returns the number of the token pointed to by cp or oBadOption.
358 1.1 christos */
359 1.1 christos
360 1.1 christos static OpCodes
361 1.1 christos parse_token(const char *cp, const char *filename, int linenum)
362 1.1 christos {
363 1.1 christos u_int i;
364 1.1 christos
365 1.1 christos for (i = 0; keywords[i].name; i++)
366 1.1 christos if (strcasecmp(cp, keywords[i].name) == 0)
367 1.1 christos return keywords[i].opcode;
368 1.1 christos
369 1.1 christos error("%s: line %d: Bad configuration option: %s",
370 1.1 christos filename, linenum, cp);
371 1.1 christos return oBadOption;
372 1.1 christos }
373 1.1 christos
374 1.1 christos /*
375 1.1 christos * Processes a single option line as used in the configuration files. This
376 1.1 christos * only sets those values that have not already been set.
377 1.1 christos */
378 1.1 christos #define WHITESPACE " \t\r\n"
379 1.1 christos
380 1.1 christos int
381 1.1 christos process_config_line(Options *options, const char *host,
382 1.1 christos char *line, const char *filename, int linenum,
383 1.1 christos int *activep)
384 1.1 christos {
385 1.6 christos char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
386 1.6 christos char **cpptr, fwdarg[256];
387 1.6 christos u_int *uintptr, max_entries = 0;
388 1.6 christos int negated, opcode, *intptr, value, value2, scale;
389 1.1 christos LogLevel *log_level_ptr;
390 1.1 christos long long orig, val64;
391 1.1 christos size_t len;
392 1.1 christos Forward fwd;
393 1.1 christos
394 1.1 christos /* Strip trailing whitespace */
395 1.1 christos for (len = strlen(line) - 1; len > 0; len--) {
396 1.1 christos if (strchr(WHITESPACE, line[len]) == NULL)
397 1.1 christos break;
398 1.1 christos line[len] = '\0';
399 1.1 christos }
400 1.1 christos
401 1.1 christos s = line;
402 1.1 christos /* Get the keyword. (Each line is supposed to begin with a keyword). */
403 1.1 christos if ((keyword = strdelim(&s)) == NULL)
404 1.1 christos return 0;
405 1.1 christos /* Ignore leading whitespace. */
406 1.1 christos if (*keyword == '\0')
407 1.1 christos keyword = strdelim(&s);
408 1.1 christos if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
409 1.1 christos return 0;
410 1.1 christos
411 1.1 christos opcode = parse_token(keyword, filename, linenum);
412 1.1 christos
413 1.1 christos switch (opcode) {
414 1.1 christos case oBadOption:
415 1.1 christos /* don't panic, but count bad options */
416 1.1 christos return -1;
417 1.1 christos /* NOTREACHED */
418 1.1 christos case oConnectTimeout:
419 1.1 christos intptr = &options->connection_timeout;
420 1.1 christos parse_time:
421 1.1 christos arg = strdelim(&s);
422 1.1 christos if (!arg || *arg == '\0')
423 1.1 christos fatal("%s line %d: missing time value.",
424 1.1 christos filename, linenum);
425 1.1 christos if ((value = convtime(arg)) == -1)
426 1.1 christos fatal("%s line %d: invalid time value.",
427 1.1 christos filename, linenum);
428 1.1 christos if (*activep && *intptr == -1)
429 1.1 christos *intptr = value;
430 1.1 christos break;
431 1.1 christos
432 1.1 christos case oForwardAgent:
433 1.1 christos intptr = &options->forward_agent;
434 1.1 christos parse_flag:
435 1.1 christos arg = strdelim(&s);
436 1.1 christos if (!arg || *arg == '\0')
437 1.1 christos fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
438 1.1 christos value = 0; /* To avoid compiler warning... */
439 1.1 christos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
440 1.1 christos value = 1;
441 1.1 christos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
442 1.1 christos value = 0;
443 1.1 christos else
444 1.1 christos fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
445 1.1 christos if (*activep && *intptr == -1)
446 1.1 christos *intptr = value;
447 1.1 christos break;
448 1.1 christos
449 1.1 christos case oForwardX11:
450 1.1 christos intptr = &options->forward_x11;
451 1.1 christos goto parse_flag;
452 1.1 christos
453 1.1 christos case oForwardX11Trusted:
454 1.1 christos intptr = &options->forward_x11_trusted;
455 1.1 christos goto parse_flag;
456 1.4 adam
457 1.4 adam case oForwardX11Timeout:
458 1.4 adam intptr = &options->forward_x11_timeout;
459 1.4 adam goto parse_time;
460 1.1 christos
461 1.1 christos case oGatewayPorts:
462 1.1 christos intptr = &options->gateway_ports;
463 1.1 christos goto parse_flag;
464 1.1 christos
465 1.1 christos case oExitOnForwardFailure:
466 1.1 christos intptr = &options->exit_on_forward_failure;
467 1.1 christos goto parse_flag;
468 1.1 christos
469 1.1 christos case oUsePrivilegedPort:
470 1.1 christos intptr = &options->use_privileged_port;
471 1.1 christos goto parse_flag;
472 1.1 christos
473 1.1 christos case oPasswordAuthentication:
474 1.1 christos intptr = &options->password_authentication;
475 1.1 christos goto parse_flag;
476 1.1 christos
477 1.1 christos case oZeroKnowledgePasswordAuthentication:
478 1.1 christos intptr = &options->zero_knowledge_password_authentication;
479 1.1 christos goto parse_flag;
480 1.1 christos
481 1.1 christos case oKbdInteractiveAuthentication:
482 1.1 christos intptr = &options->kbd_interactive_authentication;
483 1.1 christos goto parse_flag;
484 1.1 christos
485 1.1 christos case oKbdInteractiveDevices:
486 1.1 christos charptr = &options->kbd_interactive_devices;
487 1.1 christos goto parse_string;
488 1.1 christos
489 1.1 christos case oPubkeyAuthentication:
490 1.1 christos intptr = &options->pubkey_authentication;
491 1.1 christos goto parse_flag;
492 1.1 christos
493 1.1 christos case oRSAAuthentication:
494 1.1 christos intptr = &options->rsa_authentication;
495 1.1 christos goto parse_flag;
496 1.1 christos
497 1.1 christos case oRhostsRSAAuthentication:
498 1.1 christos intptr = &options->rhosts_rsa_authentication;
499 1.1 christos goto parse_flag;
500 1.1 christos
501 1.1 christos case oHostbasedAuthentication:
502 1.1 christos intptr = &options->hostbased_authentication;
503 1.1 christos goto parse_flag;
504 1.1 christos
505 1.1 christos case oChallengeResponseAuthentication:
506 1.1 christos intptr = &options->challenge_response_authentication;
507 1.1 christos goto parse_flag;
508 1.1 christos
509 1.2 christos #if defined(KRB4) || defined(KRB5)
510 1.2 christos case oKerberosAuthentication:
511 1.2 christos intptr = &options->kerberos_authentication;
512 1.2 christos goto parse_flag;
513 1.2 christos #endif
514 1.2 christos #if defined(AFS) || defined(KRB5)
515 1.2 christos case oKerberosTgtPassing:
516 1.2 christos intptr = &options->kerberos_tgt_passing;
517 1.2 christos goto parse_flag;
518 1.2 christos #endif
519 1.2 christos
520 1.1 christos case oGssAuthentication:
521 1.1 christos intptr = &options->gss_authentication;
522 1.1 christos goto parse_flag;
523 1.1 christos
524 1.2 christos #ifdef AFS
525 1.2 christos case oAFSTokenPassing:
526 1.2 christos intptr = &options->afs_token_passing;
527 1.2 christos goto parse_flag;
528 1.2 christos #endif
529 1.2 christos
530 1.1 christos case oGssDelegateCreds:
531 1.1 christos intptr = &options->gss_deleg_creds;
532 1.1 christos goto parse_flag;
533 1.1 christos
534 1.1 christos case oBatchMode:
535 1.1 christos intptr = &options->batch_mode;
536 1.1 christos goto parse_flag;
537 1.1 christos
538 1.1 christos case oCheckHostIP:
539 1.1 christos intptr = &options->check_host_ip;
540 1.1 christos goto parse_flag;
541 1.1 christos
542 1.2 christos case oNoneEnabled:
543 1.2 christos intptr = &options->none_enabled;
544 1.2 christos goto parse_flag;
545 1.2 christos
546 1.2 christos /* we check to see if the command comes from the */
547 1.2 christos /* command line or not. If it does then enable it */
548 1.2 christos /* otherwise fail. NONE should never be a default configuration */
549 1.2 christos case oNoneSwitch:
550 1.2 christos if(strcmp(filename,"command-line")==0)
551 1.2 christos {
552 1.2 christos intptr = &options->none_switch;
553 1.2 christos goto parse_flag;
554 1.2 christos } else {
555 1.2 christos error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
556 1.2 christos error("Continuing...");
557 1.2 christos debug("NoneSwitch directive found in %.200s.", filename);
558 1.2 christos return 0;
559 1.2 christos }
560 1.2 christos
561 1.2 christos case oHPNDisabled:
562 1.2 christos intptr = &options->hpn_disabled;
563 1.2 christos goto parse_flag;
564 1.2 christos
565 1.2 christos case oHPNBufferSize:
566 1.2 christos intptr = &options->hpn_buffer_size;
567 1.2 christos goto parse_int;
568 1.2 christos
569 1.2 christos case oTcpRcvBufPoll:
570 1.2 christos intptr = &options->tcp_rcv_buf_poll;
571 1.2 christos goto parse_flag;
572 1.2 christos
573 1.1 christos case oVerifyHostKeyDNS:
574 1.1 christos intptr = &options->verify_host_key_dns;
575 1.1 christos goto parse_yesnoask;
576 1.1 christos
577 1.1 christos case oStrictHostKeyChecking:
578 1.1 christos intptr = &options->strict_host_key_checking;
579 1.1 christos parse_yesnoask:
580 1.1 christos arg = strdelim(&s);
581 1.1 christos if (!arg || *arg == '\0')
582 1.1 christos fatal("%.200s line %d: Missing yes/no/ask argument.",
583 1.1 christos filename, linenum);
584 1.1 christos value = 0; /* To avoid compiler warning... */
585 1.1 christos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
586 1.1 christos value = 1;
587 1.1 christos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
588 1.1 christos value = 0;
589 1.1 christos else if (strcmp(arg, "ask") == 0)
590 1.1 christos value = 2;
591 1.1 christos else
592 1.1 christos fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
593 1.1 christos if (*activep && *intptr == -1)
594 1.1 christos *intptr = value;
595 1.1 christos break;
596 1.1 christos
597 1.1 christos case oCompression:
598 1.1 christos intptr = &options->compression;
599 1.1 christos goto parse_flag;
600 1.1 christos
601 1.1 christos case oTCPKeepAlive:
602 1.1 christos intptr = &options->tcp_keep_alive;
603 1.1 christos goto parse_flag;
604 1.1 christos
605 1.1 christos case oNoHostAuthenticationForLocalhost:
606 1.1 christos intptr = &options->no_host_authentication_for_localhost;
607 1.1 christos goto parse_flag;
608 1.1 christos
609 1.1 christos case oNumberOfPasswordPrompts:
610 1.1 christos intptr = &options->number_of_password_prompts;
611 1.1 christos goto parse_int;
612 1.1 christos
613 1.1 christos case oCompressionLevel:
614 1.1 christos intptr = &options->compression_level;
615 1.1 christos goto parse_int;
616 1.1 christos
617 1.1 christos case oRekeyLimit:
618 1.1 christos arg = strdelim(&s);
619 1.1 christos if (!arg || *arg == '\0')
620 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
621 1.1 christos if (arg[0] < '0' || arg[0] > '9')
622 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
623 1.1 christos orig = val64 = strtoll(arg, &endofnumber, 10);
624 1.1 christos if (arg == endofnumber)
625 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
626 1.2 christos switch (toupper((unsigned char)*endofnumber)) {
627 1.1 christos case '\0':
628 1.1 christos scale = 1;
629 1.1 christos break;
630 1.1 christos case 'K':
631 1.1 christos scale = 1<<10;
632 1.1 christos break;
633 1.1 christos case 'M':
634 1.1 christos scale = 1<<20;
635 1.1 christos break;
636 1.1 christos case 'G':
637 1.1 christos scale = 1<<30;
638 1.1 christos break;
639 1.1 christos default:
640 1.2 christos scale = 0;
641 1.1 christos fatal("%.200s line %d: Invalid RekeyLimit suffix",
642 1.1 christos filename, linenum);
643 1.1 christos }
644 1.1 christos val64 *= scale;
645 1.1 christos /* detect integer wrap and too-large limits */
646 1.1 christos if ((val64 / scale) != orig || val64 > UINT_MAX)
647 1.1 christos fatal("%.200s line %d: RekeyLimit too large",
648 1.1 christos filename, linenum);
649 1.1 christos if (val64 < 16)
650 1.1 christos fatal("%.200s line %d: RekeyLimit too small",
651 1.1 christos filename, linenum);
652 1.1 christos if (*activep && options->rekey_limit == -1)
653 1.1 christos options->rekey_limit = (u_int32_t)val64;
654 1.1 christos break;
655 1.1 christos
656 1.1 christos case oIdentityFile:
657 1.1 christos arg = strdelim(&s);
658 1.1 christos if (!arg || *arg == '\0')
659 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
660 1.1 christos if (*activep) {
661 1.1 christos intptr = &options->num_identity_files;
662 1.1 christos if (*intptr >= SSH_MAX_IDENTITY_FILES)
663 1.1 christos fatal("%.200s line %d: Too many identity files specified (max %d).",
664 1.1 christos filename, linenum, SSH_MAX_IDENTITY_FILES);
665 1.1 christos charptr = &options->identity_files[*intptr];
666 1.1 christos *charptr = xstrdup(arg);
667 1.1 christos *intptr = *intptr + 1;
668 1.1 christos }
669 1.1 christos break;
670 1.1 christos
671 1.1 christos case oXAuthLocation:
672 1.1 christos charptr=&options->xauth_location;
673 1.1 christos goto parse_string;
674 1.1 christos
675 1.1 christos case oUser:
676 1.1 christos charptr = &options->user;
677 1.1 christos parse_string:
678 1.1 christos arg = strdelim(&s);
679 1.1 christos if (!arg || *arg == '\0')
680 1.6 christos fatal("%.200s line %d: Missing argument.",
681 1.6 christos filename, linenum);
682 1.1 christos if (*activep && *charptr == NULL)
683 1.1 christos *charptr = xstrdup(arg);
684 1.1 christos break;
685 1.1 christos
686 1.1 christos case oGlobalKnownHostsFile:
687 1.6 christos cpptr = (char **)&options->system_hostfiles;
688 1.6 christos uintptr = &options->num_system_hostfiles;
689 1.6 christos max_entries = SSH_MAX_HOSTS_FILES;
690 1.6 christos parse_char_array:
691 1.6 christos if (*activep && *uintptr == 0) {
692 1.6 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
693 1.6 christos if ((*uintptr) >= max_entries)
694 1.6 christos fatal("%s line %d: "
695 1.6 christos "too many authorized keys files.",
696 1.6 christos filename, linenum);
697 1.6 christos cpptr[(*uintptr)++] = xstrdup(arg);
698 1.6 christos }
699 1.6 christos }
700 1.6 christos return 0;
701 1.1 christos
702 1.1 christos case oUserKnownHostsFile:
703 1.6 christos cpptr = (char **)&options->user_hostfiles;
704 1.6 christos uintptr = &options->num_user_hostfiles;
705 1.6 christos max_entries = SSH_MAX_HOSTS_FILES;
706 1.6 christos goto parse_char_array;
707 1.1 christos
708 1.1 christos case oHostName:
709 1.1 christos charptr = &options->hostname;
710 1.1 christos goto parse_string;
711 1.1 christos
712 1.1 christos case oHostKeyAlias:
713 1.1 christos charptr = &options->host_key_alias;
714 1.1 christos goto parse_string;
715 1.1 christos
716 1.1 christos case oPreferredAuthentications:
717 1.1 christos charptr = &options->preferred_authentications;
718 1.1 christos goto parse_string;
719 1.1 christos
720 1.1 christos case oBindAddress:
721 1.1 christos charptr = &options->bind_address;
722 1.1 christos goto parse_string;
723 1.1 christos
724 1.4 adam case oPKCS11Provider:
725 1.4 adam charptr = &options->pkcs11_provider;
726 1.1 christos goto parse_string;
727 1.1 christos
728 1.1 christos case oProxyCommand:
729 1.1 christos charptr = &options->proxy_command;
730 1.1 christos parse_command:
731 1.1 christos if (s == NULL)
732 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
733 1.1 christos len = strspn(s, WHITESPACE "=");
734 1.1 christos if (*activep && *charptr == NULL)
735 1.1 christos *charptr = xstrdup(s + len);
736 1.1 christos return 0;
737 1.1 christos
738 1.1 christos case oPort:
739 1.1 christos intptr = &options->port;
740 1.1 christos parse_int:
741 1.1 christos arg = strdelim(&s);
742 1.1 christos if (!arg || *arg == '\0')
743 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
744 1.1 christos if (arg[0] < '0' || arg[0] > '9')
745 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
746 1.1 christos
747 1.1 christos /* Octal, decimal, or hex format? */
748 1.1 christos value = strtol(arg, &endofnumber, 0);
749 1.1 christos if (arg == endofnumber)
750 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
751 1.1 christos if (*activep && *intptr == -1)
752 1.1 christos *intptr = value;
753 1.1 christos break;
754 1.1 christos
755 1.1 christos case oConnectionAttempts:
756 1.1 christos intptr = &options->connection_attempts;
757 1.1 christos goto parse_int;
758 1.1 christos
759 1.2 christos case oTcpRcvBuf:
760 1.2 christos intptr = &options->tcp_rcv_buf;
761 1.2 christos goto parse_int;
762 1.2 christos
763 1.1 christos case oCipher:
764 1.1 christos intptr = &options->cipher;
765 1.1 christos arg = strdelim(&s);
766 1.1 christos if (!arg || *arg == '\0')
767 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
768 1.1 christos value = cipher_number(arg);
769 1.1 christos if (value == -1)
770 1.1 christos fatal("%.200s line %d: Bad cipher '%s'.",
771 1.1 christos filename, linenum, arg ? arg : "<NONE>");
772 1.1 christos if (*activep && *intptr == -1)
773 1.1 christos *intptr = value;
774 1.1 christos break;
775 1.1 christos
776 1.1 christos case oCiphers:
777 1.1 christos arg = strdelim(&s);
778 1.1 christos if (!arg || *arg == '\0')
779 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
780 1.1 christos if (!ciphers_valid(arg))
781 1.1 christos fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
782 1.1 christos filename, linenum, arg ? arg : "<NONE>");
783 1.1 christos if (*activep && options->ciphers == NULL)
784 1.1 christos options->ciphers = xstrdup(arg);
785 1.1 christos break;
786 1.1 christos
787 1.1 christos case oMacs:
788 1.1 christos arg = strdelim(&s);
789 1.1 christos if (!arg || *arg == '\0')
790 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
791 1.1 christos if (!mac_valid(arg))
792 1.1 christos fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
793 1.1 christos filename, linenum, arg ? arg : "<NONE>");
794 1.1 christos if (*activep && options->macs == NULL)
795 1.1 christos options->macs = xstrdup(arg);
796 1.1 christos break;
797 1.1 christos
798 1.5 christos case oKexAlgorithms:
799 1.5 christos arg = strdelim(&s);
800 1.5 christos if (!arg || *arg == '\0')
801 1.5 christos fatal("%.200s line %d: Missing argument.",
802 1.5 christos filename, linenum);
803 1.5 christos if (!kex_names_valid(arg))
804 1.5 christos fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
805 1.5 christos filename, linenum, arg ? arg : "<NONE>");
806 1.5 christos if (*activep && options->kex_algorithms == NULL)
807 1.5 christos options->kex_algorithms = xstrdup(arg);
808 1.5 christos break;
809 1.5 christos
810 1.1 christos case oHostKeyAlgorithms:
811 1.1 christos arg = strdelim(&s);
812 1.1 christos if (!arg || *arg == '\0')
813 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
814 1.1 christos if (!key_names_valid2(arg))
815 1.1 christos fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
816 1.1 christos filename, linenum, arg ? arg : "<NONE>");
817 1.1 christos if (*activep && options->hostkeyalgorithms == NULL)
818 1.1 christos options->hostkeyalgorithms = xstrdup(arg);
819 1.1 christos break;
820 1.1 christos
821 1.1 christos case oProtocol:
822 1.1 christos intptr = &options->protocol;
823 1.1 christos arg = strdelim(&s);
824 1.1 christos if (!arg || *arg == '\0')
825 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
826 1.1 christos value = proto_spec(arg);
827 1.1 christos if (value == SSH_PROTO_UNKNOWN)
828 1.1 christos fatal("%.200s line %d: Bad protocol spec '%s'.",
829 1.1 christos filename, linenum, arg ? arg : "<NONE>");
830 1.1 christos if (*activep && *intptr == SSH_PROTO_UNKNOWN)
831 1.1 christos *intptr = value;
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case oLogLevel:
835 1.1 christos log_level_ptr = &options->log_level;
836 1.1 christos arg = strdelim(&s);
837 1.1 christos value = log_level_number(arg);
838 1.1 christos if (value == SYSLOG_LEVEL_NOT_SET)
839 1.1 christos fatal("%.200s line %d: unsupported log level '%s'",
840 1.1 christos filename, linenum, arg ? arg : "<NONE>");
841 1.1 christos if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
842 1.1 christos *log_level_ptr = (LogLevel) value;
843 1.1 christos break;
844 1.1 christos
845 1.1 christos case oLocalForward:
846 1.1 christos case oRemoteForward:
847 1.1 christos case oDynamicForward:
848 1.1 christos arg = strdelim(&s);
849 1.1 christos if (arg == NULL || *arg == '\0')
850 1.1 christos fatal("%.200s line %d: Missing port argument.",
851 1.1 christos filename, linenum);
852 1.1 christos
853 1.1 christos if (opcode == oLocalForward ||
854 1.1 christos opcode == oRemoteForward) {
855 1.1 christos arg2 = strdelim(&s);
856 1.1 christos if (arg2 == NULL || *arg2 == '\0')
857 1.1 christos fatal("%.200s line %d: Missing target argument.",
858 1.1 christos filename, linenum);
859 1.1 christos
860 1.1 christos /* construct a string for parse_forward */
861 1.1 christos snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
862 1.1 christos } else if (opcode == oDynamicForward) {
863 1.1 christos strlcpy(fwdarg, arg, sizeof(fwdarg));
864 1.1 christos }
865 1.1 christos
866 1.1 christos if (parse_forward(&fwd, fwdarg,
867 1.1 christos opcode == oDynamicForward ? 1 : 0,
868 1.1 christos opcode == oRemoteForward ? 1 : 0) == 0)
869 1.1 christos fatal("%.200s line %d: Bad forwarding specification.",
870 1.1 christos filename, linenum);
871 1.1 christos
872 1.1 christos if (*activep) {
873 1.1 christos if (opcode == oLocalForward ||
874 1.1 christos opcode == oDynamicForward)
875 1.1 christos add_local_forward(options, &fwd);
876 1.1 christos else if (opcode == oRemoteForward)
877 1.1 christos add_remote_forward(options, &fwd);
878 1.1 christos }
879 1.1 christos break;
880 1.1 christos
881 1.1 christos case oClearAllForwardings:
882 1.1 christos intptr = &options->clear_forwardings;
883 1.1 christos goto parse_flag;
884 1.1 christos
885 1.1 christos case oHost:
886 1.1 christos *activep = 0;
887 1.6 christos arg2 = NULL;
888 1.6 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
889 1.6 christos negated = *arg == '!';
890 1.6 christos if (negated)
891 1.6 christos arg++;
892 1.1 christos if (match_pattern(host, arg)) {
893 1.6 christos if (negated) {
894 1.6 christos debug("%.200s line %d: Skipping Host "
895 1.6 christos "block because of negated match "
896 1.6 christos "for %.100s", filename, linenum,
897 1.6 christos arg);
898 1.6 christos *activep = 0;
899 1.6 christos break;
900 1.6 christos }
901 1.6 christos if (!*activep)
902 1.6 christos arg2 = arg; /* logged below */
903 1.1 christos *activep = 1;
904 1.1 christos }
905 1.6 christos }
906 1.6 christos if (*activep)
907 1.6 christos debug("%.200s line %d: Applying options for %.100s",
908 1.6 christos filename, linenum, arg2);
909 1.1 christos /* Avoid garbage check below, as strdelim is done. */
910 1.1 christos return 0;
911 1.1 christos
912 1.1 christos case oEscapeChar:
913 1.1 christos intptr = &options->escape_char;
914 1.1 christos arg = strdelim(&s);
915 1.1 christos if (!arg || *arg == '\0')
916 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
917 1.2 christos value = 0; /* To avoid compiler warning... */
918 1.1 christos if (arg[0] == '^' && arg[2] == 0 &&
919 1.1 christos (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
920 1.1 christos value = (u_char) arg[1] & 31;
921 1.1 christos else if (strlen(arg) == 1)
922 1.1 christos value = (u_char) arg[0];
923 1.1 christos else if (strcmp(arg, "none") == 0)
924 1.1 christos value = SSH_ESCAPECHAR_NONE;
925 1.1 christos else {
926 1.1 christos fatal("%.200s line %d: Bad escape character.",
927 1.1 christos filename, linenum);
928 1.1 christos /* NOTREACHED */
929 1.1 christos value = 0; /* Avoid compiler warning. */
930 1.1 christos }
931 1.1 christos if (*activep && *intptr == -1)
932 1.1 christos *intptr = value;
933 1.1 christos break;
934 1.1 christos
935 1.1 christos case oAddressFamily:
936 1.1 christos arg = strdelim(&s);
937 1.1 christos if (!arg || *arg == '\0')
938 1.1 christos fatal("%s line %d: missing address family.",
939 1.1 christos filename, linenum);
940 1.1 christos intptr = &options->address_family;
941 1.2 christos value = 0; /* To avoid compiler warning... */
942 1.1 christos if (strcasecmp(arg, "inet") == 0)
943 1.1 christos value = AF_INET;
944 1.1 christos else if (strcasecmp(arg, "inet6") == 0)
945 1.1 christos value = AF_INET6;
946 1.1 christos else if (strcasecmp(arg, "any") == 0)
947 1.1 christos value = AF_UNSPEC;
948 1.1 christos else
949 1.1 christos fatal("Unsupported AddressFamily \"%s\"", arg);
950 1.1 christos if (*activep && *intptr == -1)
951 1.1 christos *intptr = value;
952 1.1 christos break;
953 1.1 christos
954 1.1 christos case oEnableSSHKeysign:
955 1.1 christos intptr = &options->enable_ssh_keysign;
956 1.1 christos goto parse_flag;
957 1.1 christos
958 1.1 christos case oIdentitiesOnly:
959 1.1 christos intptr = &options->identities_only;
960 1.1 christos goto parse_flag;
961 1.1 christos
962 1.1 christos case oServerAliveInterval:
963 1.1 christos intptr = &options->server_alive_interval;
964 1.1 christos goto parse_time;
965 1.1 christos
966 1.1 christos case oServerAliveCountMax:
967 1.1 christos intptr = &options->server_alive_count_max;
968 1.1 christos goto parse_int;
969 1.1 christos
970 1.1 christos case oSendEnv:
971 1.1 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
972 1.1 christos if (strchr(arg, '=') != NULL)
973 1.1 christos fatal("%s line %d: Invalid environment name.",
974 1.1 christos filename, linenum);
975 1.1 christos if (!*activep)
976 1.1 christos continue;
977 1.1 christos if (options->num_send_env >= MAX_SEND_ENV)
978 1.1 christos fatal("%s line %d: too many send env.",
979 1.1 christos filename, linenum);
980 1.1 christos options->send_env[options->num_send_env++] =
981 1.1 christos xstrdup(arg);
982 1.1 christos }
983 1.1 christos break;
984 1.1 christos
985 1.1 christos case oControlPath:
986 1.1 christos charptr = &options->control_path;
987 1.1 christos goto parse_string;
988 1.1 christos
989 1.1 christos case oControlMaster:
990 1.1 christos intptr = &options->control_master;
991 1.1 christos arg = strdelim(&s);
992 1.1 christos if (!arg || *arg == '\0')
993 1.1 christos fatal("%.200s line %d: Missing ControlMaster argument.",
994 1.1 christos filename, linenum);
995 1.1 christos value = 0; /* To avoid compiler warning... */
996 1.1 christos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
997 1.1 christos value = SSHCTL_MASTER_YES;
998 1.1 christos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
999 1.1 christos value = SSHCTL_MASTER_NO;
1000 1.1 christos else if (strcmp(arg, "auto") == 0)
1001 1.1 christos value = SSHCTL_MASTER_AUTO;
1002 1.1 christos else if (strcmp(arg, "ask") == 0)
1003 1.1 christos value = SSHCTL_MASTER_ASK;
1004 1.1 christos else if (strcmp(arg, "autoask") == 0)
1005 1.1 christos value = SSHCTL_MASTER_AUTO_ASK;
1006 1.1 christos else
1007 1.1 christos fatal("%.200s line %d: Bad ControlMaster argument.",
1008 1.1 christos filename, linenum);
1009 1.1 christos if (*activep && *intptr == -1)
1010 1.1 christos *intptr = value;
1011 1.1 christos break;
1012 1.1 christos
1013 1.4 adam case oControlPersist:
1014 1.4 adam /* no/false/yes/true, or a time spec */
1015 1.4 adam intptr = &options->control_persist;
1016 1.4 adam arg = strdelim(&s);
1017 1.4 adam if (!arg || *arg == '\0')
1018 1.4 adam fatal("%.200s line %d: Missing ControlPersist"
1019 1.4 adam " argument.", filename, linenum);
1020 1.4 adam value = 0;
1021 1.4 adam value2 = 0; /* timeout */
1022 1.4 adam if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1023 1.4 adam value = 0;
1024 1.4 adam else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1025 1.4 adam value = 1;
1026 1.4 adam else if ((value2 = convtime(arg)) >= 0)
1027 1.4 adam value = 1;
1028 1.4 adam else
1029 1.4 adam fatal("%.200s line %d: Bad ControlPersist argument.",
1030 1.4 adam filename, linenum);
1031 1.4 adam if (*activep && *intptr == -1) {
1032 1.4 adam *intptr = value;
1033 1.4 adam options->control_persist_timeout = value2;
1034 1.4 adam }
1035 1.4 adam break;
1036 1.4 adam
1037 1.1 christos case oHashKnownHosts:
1038 1.1 christos intptr = &options->hash_known_hosts;
1039 1.1 christos goto parse_flag;
1040 1.1 christos
1041 1.1 christos case oTunnel:
1042 1.1 christos intptr = &options->tun_open;
1043 1.1 christos arg = strdelim(&s);
1044 1.1 christos if (!arg || *arg == '\0')
1045 1.1 christos fatal("%s line %d: Missing yes/point-to-point/"
1046 1.1 christos "ethernet/no argument.", filename, linenum);
1047 1.1 christos value = 0; /* silence compiler */
1048 1.1 christos if (strcasecmp(arg, "ethernet") == 0)
1049 1.1 christos value = SSH_TUNMODE_ETHERNET;
1050 1.1 christos else if (strcasecmp(arg, "point-to-point") == 0)
1051 1.1 christos value = SSH_TUNMODE_POINTOPOINT;
1052 1.1 christos else if (strcasecmp(arg, "yes") == 0)
1053 1.1 christos value = SSH_TUNMODE_DEFAULT;
1054 1.1 christos else if (strcasecmp(arg, "no") == 0)
1055 1.1 christos value = SSH_TUNMODE_NO;
1056 1.1 christos else
1057 1.1 christos fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1058 1.1 christos "no argument: %s", filename, linenum, arg);
1059 1.1 christos if (*activep)
1060 1.1 christos *intptr = value;
1061 1.1 christos break;
1062 1.1 christos
1063 1.1 christos case oTunnelDevice:
1064 1.1 christos arg = strdelim(&s);
1065 1.1 christos if (!arg || *arg == '\0')
1066 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1067 1.1 christos value = a2tun(arg, &value2);
1068 1.1 christos if (value == SSH_TUNID_ERR)
1069 1.1 christos fatal("%.200s line %d: Bad tun device.", filename, linenum);
1070 1.1 christos if (*activep) {
1071 1.1 christos options->tun_local = value;
1072 1.1 christos options->tun_remote = value2;
1073 1.1 christos }
1074 1.1 christos break;
1075 1.1 christos
1076 1.1 christos case oLocalCommand:
1077 1.1 christos charptr = &options->local_command;
1078 1.1 christos goto parse_command;
1079 1.1 christos
1080 1.1 christos case oPermitLocalCommand:
1081 1.1 christos intptr = &options->permit_local_command;
1082 1.1 christos goto parse_flag;
1083 1.1 christos
1084 1.1 christos case oVisualHostKey:
1085 1.1 christos intptr = &options->visual_host_key;
1086 1.1 christos goto parse_flag;
1087 1.1 christos
1088 1.5 christos case oIPQoS:
1089 1.5 christos arg = strdelim(&s);
1090 1.5 christos if ((value = parse_ipqos(arg)) == -1)
1091 1.5 christos fatal("%s line %d: Bad IPQoS value: %s",
1092 1.5 christos filename, linenum, arg);
1093 1.5 christos arg = strdelim(&s);
1094 1.5 christos if (arg == NULL)
1095 1.5 christos value2 = value;
1096 1.5 christos else if ((value2 = parse_ipqos(arg)) == -1)
1097 1.5 christos fatal("%s line %d: Bad IPQoS value: %s",
1098 1.5 christos filename, linenum, arg);
1099 1.5 christos if (*activep) {
1100 1.5 christos options->ip_qos_interactive = value;
1101 1.5 christos options->ip_qos_bulk = value2;
1102 1.5 christos }
1103 1.5 christos break;
1104 1.5 christos
1105 1.3 christos case oUseRoaming:
1106 1.3 christos intptr = &options->use_roaming;
1107 1.3 christos goto parse_flag;
1108 1.3 christos
1109 1.6 christos case oRequestTTY:
1110 1.6 christos arg = strdelim(&s);
1111 1.6 christos if (!arg || *arg == '\0')
1112 1.6 christos fatal("%s line %d: missing argument.",
1113 1.6 christos filename, linenum);
1114 1.6 christos intptr = &options->request_tty;
1115 1.6 christos if (strcasecmp(arg, "yes") == 0)
1116 1.6 christos value = REQUEST_TTY_YES;
1117 1.6 christos else if (strcasecmp(arg, "no") == 0)
1118 1.6 christos value = REQUEST_TTY_NO;
1119 1.6 christos else if (strcasecmp(arg, "force") == 0)
1120 1.6 christos value = REQUEST_TTY_FORCE;
1121 1.6 christos else if (strcasecmp(arg, "auto") == 0)
1122 1.6 christos value = REQUEST_TTY_AUTO;
1123 1.6 christos else
1124 1.6 christos fatal("Unsupported RequestTTY \"%s\"", arg);
1125 1.6 christos if (*activep && *intptr == -1)
1126 1.6 christos *intptr = value;
1127 1.6 christos break;
1128 1.6 christos
1129 1.7 tls case oSendVersionFirst:
1130 1.7 tls intptr = &options->send_version_first;
1131 1.7 tls goto parse_flag;
1132 1.7 tls
1133 1.1 christos case oDeprecated:
1134 1.1 christos debug("%s line %d: Deprecated option \"%s\"",
1135 1.1 christos filename, linenum, keyword);
1136 1.1 christos return 0;
1137 1.1 christos
1138 1.1 christos case oUnsupported:
1139 1.1 christos error("%s line %d: Unsupported option \"%s\"",
1140 1.1 christos filename, linenum, keyword);
1141 1.1 christos return 0;
1142 1.1 christos
1143 1.1 christos default:
1144 1.1 christos fatal("process_config_line: Unimplemented opcode %d", opcode);
1145 1.1 christos }
1146 1.1 christos
1147 1.1 christos /* Check that there is no garbage at end of line. */
1148 1.1 christos if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1149 1.1 christos fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1150 1.1 christos filename, linenum, arg);
1151 1.1 christos }
1152 1.1 christos return 0;
1153 1.1 christos }
1154 1.1 christos
1155 1.1 christos
1156 1.1 christos /*
1157 1.1 christos * Reads the config file and modifies the options accordingly. Options
1158 1.1 christos * should already be initialized before this call. This never returns if
1159 1.1 christos * there is an error. If the file does not exist, this returns 0.
1160 1.1 christos */
1161 1.1 christos
1162 1.1 christos int
1163 1.1 christos read_config_file(const char *filename, const char *host, Options *options,
1164 1.1 christos int checkperm)
1165 1.1 christos {
1166 1.1 christos FILE *f;
1167 1.1 christos char line[1024];
1168 1.1 christos int active, linenum;
1169 1.1 christos int bad_options = 0;
1170 1.1 christos
1171 1.1 christos if ((f = fopen(filename, "r")) == NULL)
1172 1.1 christos return 0;
1173 1.1 christos
1174 1.1 christos if (checkperm) {
1175 1.1 christos struct stat sb;
1176 1.1 christos
1177 1.1 christos if (fstat(fileno(f), &sb) == -1)
1178 1.1 christos fatal("fstat %s: %s", filename, strerror(errno));
1179 1.1 christos if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1180 1.1 christos (sb.st_mode & 022) != 0))
1181 1.1 christos fatal("Bad owner or permissions on %s", filename);
1182 1.1 christos }
1183 1.1 christos
1184 1.1 christos debug("Reading configuration data %.200s", filename);
1185 1.1 christos
1186 1.1 christos /*
1187 1.1 christos * Mark that we are now processing the options. This flag is turned
1188 1.1 christos * on/off by Host specifications.
1189 1.1 christos */
1190 1.1 christos active = 1;
1191 1.1 christos linenum = 0;
1192 1.1 christos while (fgets(line, sizeof(line), f)) {
1193 1.1 christos /* Update line number counter. */
1194 1.1 christos linenum++;
1195 1.1 christos if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1196 1.1 christos bad_options++;
1197 1.1 christos }
1198 1.1 christos fclose(f);
1199 1.1 christos if (bad_options > 0)
1200 1.1 christos fatal("%s: terminating, %d bad configuration options",
1201 1.1 christos filename, bad_options);
1202 1.1 christos return 1;
1203 1.1 christos }
1204 1.1 christos
1205 1.1 christos /*
1206 1.1 christos * Initializes options to special values that indicate that they have not yet
1207 1.1 christos * been set. Read_config_file will only set options with this value. Options
1208 1.1 christos * are processed in the following order: command line, user config file,
1209 1.1 christos * system config file. Last, fill_default_options is called.
1210 1.1 christos */
1211 1.1 christos
1212 1.1 christos void
1213 1.1 christos initialize_options(Options * options)
1214 1.1 christos {
1215 1.1 christos memset(options, 'X', sizeof(*options));
1216 1.1 christos options->forward_agent = -1;
1217 1.1 christos options->forward_x11 = -1;
1218 1.1 christos options->forward_x11_trusted = -1;
1219 1.4 adam options->forward_x11_timeout = -1;
1220 1.1 christos options->exit_on_forward_failure = -1;
1221 1.1 christos options->xauth_location = NULL;
1222 1.1 christos options->gateway_ports = -1;
1223 1.1 christos options->use_privileged_port = -1;
1224 1.1 christos options->rsa_authentication = -1;
1225 1.1 christos options->pubkey_authentication = -1;
1226 1.1 christos options->challenge_response_authentication = -1;
1227 1.2 christos #if defined(KRB4) || defined(KRB5)
1228 1.2 christos options->kerberos_authentication = -1;
1229 1.2 christos #endif
1230 1.2 christos #if defined(AFS) || defined(KRB5)
1231 1.2 christos options->kerberos_tgt_passing = -1;
1232 1.2 christos #endif
1233 1.2 christos #ifdef AFS
1234 1.2 christos options->afs_token_passing = -1;
1235 1.2 christos #endif
1236 1.1 christos options->gss_authentication = -1;
1237 1.1 christos options->gss_deleg_creds = -1;
1238 1.1 christos options->password_authentication = -1;
1239 1.1 christos options->kbd_interactive_authentication = -1;
1240 1.1 christos options->kbd_interactive_devices = NULL;
1241 1.1 christos options->rhosts_rsa_authentication = -1;
1242 1.1 christos options->hostbased_authentication = -1;
1243 1.1 christos options->batch_mode = -1;
1244 1.1 christos options->check_host_ip = -1;
1245 1.1 christos options->strict_host_key_checking = -1;
1246 1.1 christos options->compression = -1;
1247 1.1 christos options->tcp_keep_alive = -1;
1248 1.1 christos options->compression_level = -1;
1249 1.1 christos options->port = -1;
1250 1.1 christos options->address_family = -1;
1251 1.1 christos options->connection_attempts = -1;
1252 1.1 christos options->connection_timeout = -1;
1253 1.1 christos options->number_of_password_prompts = -1;
1254 1.1 christos options->cipher = -1;
1255 1.1 christos options->ciphers = NULL;
1256 1.1 christos options->macs = NULL;
1257 1.5 christos options->kex_algorithms = NULL;
1258 1.1 christos options->hostkeyalgorithms = NULL;
1259 1.1 christos options->protocol = SSH_PROTO_UNKNOWN;
1260 1.1 christos options->num_identity_files = 0;
1261 1.1 christos options->hostname = NULL;
1262 1.1 christos options->host_key_alias = NULL;
1263 1.1 christos options->proxy_command = NULL;
1264 1.1 christos options->user = NULL;
1265 1.1 christos options->escape_char = -1;
1266 1.6 christos options->num_system_hostfiles = 0;
1267 1.6 christos options->num_user_hostfiles = 0;
1268 1.4 adam options->local_forwards = NULL;
1269 1.1 christos options->num_local_forwards = 0;
1270 1.4 adam options->remote_forwards = NULL;
1271 1.1 christos options->num_remote_forwards = 0;
1272 1.1 christos options->clear_forwardings = -1;
1273 1.1 christos options->log_level = SYSLOG_LEVEL_NOT_SET;
1274 1.1 christos options->preferred_authentications = NULL;
1275 1.1 christos options->bind_address = NULL;
1276 1.4 adam options->pkcs11_provider = NULL;
1277 1.1 christos options->enable_ssh_keysign = - 1;
1278 1.1 christos options->no_host_authentication_for_localhost = - 1;
1279 1.1 christos options->identities_only = - 1;
1280 1.1 christos options->rekey_limit = - 1;
1281 1.1 christos options->verify_host_key_dns = -1;
1282 1.1 christos options->server_alive_interval = -1;
1283 1.1 christos options->server_alive_count_max = -1;
1284 1.1 christos options->num_send_env = 0;
1285 1.1 christos options->control_path = NULL;
1286 1.1 christos options->control_master = -1;
1287 1.4 adam options->control_persist = -1;
1288 1.4 adam options->control_persist_timeout = 0;
1289 1.1 christos options->hash_known_hosts = -1;
1290 1.1 christos options->tun_open = -1;
1291 1.1 christos options->tun_local = -1;
1292 1.1 christos options->tun_remote = -1;
1293 1.1 christos options->local_command = NULL;
1294 1.1 christos options->permit_local_command = -1;
1295 1.3 christos options->use_roaming = -1;
1296 1.1 christos options->visual_host_key = -1;
1297 1.1 christos options->zero_knowledge_password_authentication = -1;
1298 1.5 christos options->ip_qos_interactive = -1;
1299 1.5 christos options->ip_qos_bulk = -1;
1300 1.6 christos options->request_tty = -1;
1301 1.2 christos options->none_switch = -1;
1302 1.2 christos options->none_enabled = -1;
1303 1.2 christos options->hpn_disabled = -1;
1304 1.2 christos options->hpn_buffer_size = -1;
1305 1.2 christos options->tcp_rcv_buf_poll = -1;
1306 1.2 christos options->tcp_rcv_buf = -1;
1307 1.7 tls options->send_version_first = -1;
1308 1.1 christos }
1309 1.1 christos
1310 1.1 christos /*
1311 1.1 christos * Called after processing other sources of option data, this fills those
1312 1.1 christos * options for which no value has been specified with their default values.
1313 1.1 christos */
1314 1.1 christos
1315 1.1 christos void
1316 1.1 christos fill_default_options(Options * options)
1317 1.1 christos {
1318 1.1 christos int len;
1319 1.1 christos
1320 1.1 christos if (options->forward_agent == -1)
1321 1.1 christos options->forward_agent = 0;
1322 1.1 christos if (options->forward_x11 == -1)
1323 1.1 christos options->forward_x11 = 0;
1324 1.1 christos if (options->forward_x11_trusted == -1)
1325 1.1 christos options->forward_x11_trusted = 0;
1326 1.4 adam if (options->forward_x11_timeout == -1)
1327 1.4 adam options->forward_x11_timeout = 1200;
1328 1.1 christos if (options->exit_on_forward_failure == -1)
1329 1.1 christos options->exit_on_forward_failure = 0;
1330 1.1 christos if (options->xauth_location == NULL)
1331 1.5 christos options->xauth_location = __UNCONST(_PATH_XAUTH);
1332 1.1 christos if (options->gateway_ports == -1)
1333 1.1 christos options->gateway_ports = 0;
1334 1.1 christos if (options->use_privileged_port == -1)
1335 1.1 christos options->use_privileged_port = 0;
1336 1.1 christos if (options->rsa_authentication == -1)
1337 1.1 christos options->rsa_authentication = 1;
1338 1.1 christos if (options->pubkey_authentication == -1)
1339 1.1 christos options->pubkey_authentication = 1;
1340 1.1 christos if (options->challenge_response_authentication == -1)
1341 1.1 christos options->challenge_response_authentication = 1;
1342 1.2 christos #if defined(KRB4) || defined(KRB5)
1343 1.2 christos if (options->kerberos_authentication == -1)
1344 1.2 christos options->kerberos_authentication = 1;
1345 1.2 christos #endif
1346 1.2 christos #if defined(AFS) || defined(KRB5)
1347 1.2 christos if (options->kerberos_tgt_passing == -1)
1348 1.2 christos options->kerberos_tgt_passing = 1;
1349 1.2 christos #endif
1350 1.2 christos #ifdef AFS
1351 1.2 christos if (options->afs_token_passing == -1)
1352 1.2 christos options->afs_token_passing = 1;
1353 1.2 christos #endif
1354 1.1 christos if (options->gss_authentication == -1)
1355 1.1 christos options->gss_authentication = 0;
1356 1.1 christos if (options->gss_deleg_creds == -1)
1357 1.1 christos options->gss_deleg_creds = 0;
1358 1.1 christos if (options->password_authentication == -1)
1359 1.1 christos options->password_authentication = 1;
1360 1.1 christos if (options->kbd_interactive_authentication == -1)
1361 1.1 christos options->kbd_interactive_authentication = 1;
1362 1.1 christos if (options->rhosts_rsa_authentication == -1)
1363 1.1 christos options->rhosts_rsa_authentication = 0;
1364 1.1 christos if (options->hostbased_authentication == -1)
1365 1.1 christos options->hostbased_authentication = 0;
1366 1.1 christos if (options->batch_mode == -1)
1367 1.1 christos options->batch_mode = 0;
1368 1.1 christos if (options->check_host_ip == -1)
1369 1.1 christos options->check_host_ip = 1;
1370 1.1 christos if (options->strict_host_key_checking == -1)
1371 1.1 christos options->strict_host_key_checking = 2; /* 2 is default */
1372 1.1 christos if (options->compression == -1)
1373 1.1 christos options->compression = 0;
1374 1.1 christos if (options->tcp_keep_alive == -1)
1375 1.1 christos options->tcp_keep_alive = 1;
1376 1.1 christos if (options->compression_level == -1)
1377 1.1 christos options->compression_level = 6;
1378 1.1 christos if (options->port == -1)
1379 1.1 christos options->port = 0; /* Filled in ssh_connect. */
1380 1.1 christos if (options->address_family == -1)
1381 1.1 christos options->address_family = AF_UNSPEC;
1382 1.1 christos if (options->connection_attempts == -1)
1383 1.1 christos options->connection_attempts = 1;
1384 1.1 christos if (options->number_of_password_prompts == -1)
1385 1.1 christos options->number_of_password_prompts = 3;
1386 1.1 christos /* Selected in ssh_login(). */
1387 1.1 christos if (options->cipher == -1)
1388 1.1 christos options->cipher = SSH_CIPHER_NOT_SET;
1389 1.1 christos /* options->ciphers, default set in myproposals.h */
1390 1.1 christos /* options->macs, default set in myproposals.h */
1391 1.5 christos /* options->kex_algorithms, default set in myproposals.h */
1392 1.1 christos /* options->hostkeyalgorithms, default set in myproposals.h */
1393 1.1 christos if (options->protocol == SSH_PROTO_UNKNOWN)
1394 1.4 adam options->protocol = SSH_PROTO_2;
1395 1.1 christos if (options->num_identity_files == 0) {
1396 1.1 christos if (options->protocol & SSH_PROTO_1) {
1397 1.1 christos len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1398 1.1 christos options->identity_files[options->num_identity_files] =
1399 1.1 christos xmalloc(len);
1400 1.1 christos snprintf(options->identity_files[options->num_identity_files++],
1401 1.1 christos len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1402 1.1 christos }
1403 1.1 christos if (options->protocol & SSH_PROTO_2) {
1404 1.1 christos len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1405 1.1 christos options->identity_files[options->num_identity_files] =
1406 1.1 christos xmalloc(len);
1407 1.1 christos snprintf(options->identity_files[options->num_identity_files++],
1408 1.1 christos len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1409 1.1 christos
1410 1.1 christos len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1411 1.1 christos options->identity_files[options->num_identity_files] =
1412 1.1 christos xmalloc(len);
1413 1.1 christos snprintf(options->identity_files[options->num_identity_files++],
1414 1.1 christos len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1415 1.5 christos
1416 1.5 christos len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
1417 1.5 christos options->identity_files[options->num_identity_files] =
1418 1.5 christos xmalloc(len);
1419 1.5 christos snprintf(options->identity_files[options->num_identity_files++],
1420 1.5 christos len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
1421 1.1 christos }
1422 1.1 christos }
1423 1.1 christos if (options->escape_char == -1)
1424 1.1 christos options->escape_char = '~';
1425 1.6 christos if (options->num_system_hostfiles == 0) {
1426 1.6 christos options->system_hostfiles[options->num_system_hostfiles++] =
1427 1.6 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1428 1.6 christos options->system_hostfiles[options->num_system_hostfiles++] =
1429 1.6 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1430 1.6 christos }
1431 1.6 christos if (options->num_user_hostfiles == 0) {
1432 1.6 christos options->user_hostfiles[options->num_user_hostfiles++] =
1433 1.6 christos xstrdup(_PATH_SSH_USER_HOSTFILE);
1434 1.6 christos options->user_hostfiles[options->num_user_hostfiles++] =
1435 1.6 christos xstrdup(_PATH_SSH_USER_HOSTFILE2);
1436 1.6 christos }
1437 1.1 christos if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1438 1.1 christos options->log_level = SYSLOG_LEVEL_INFO;
1439 1.1 christos if (options->clear_forwardings == 1)
1440 1.1 christos clear_forwardings(options);
1441 1.1 christos if (options->no_host_authentication_for_localhost == - 1)
1442 1.1 christos options->no_host_authentication_for_localhost = 0;
1443 1.1 christos if (options->identities_only == -1)
1444 1.1 christos options->identities_only = 0;
1445 1.1 christos if (options->enable_ssh_keysign == -1)
1446 1.1 christos options->enable_ssh_keysign = 0;
1447 1.1 christos if (options->rekey_limit == -1)
1448 1.1 christos options->rekey_limit = 0;
1449 1.1 christos if (options->verify_host_key_dns == -1)
1450 1.1 christos options->verify_host_key_dns = 0;
1451 1.1 christos if (options->server_alive_interval == -1)
1452 1.1 christos options->server_alive_interval = 0;
1453 1.1 christos if (options->server_alive_count_max == -1)
1454 1.1 christos options->server_alive_count_max = 3;
1455 1.2 christos if (options->none_switch == -1)
1456 1.2 christos options->none_switch = 0;
1457 1.2 christos if (options->hpn_disabled == -1)
1458 1.2 christos options->hpn_disabled = 0;
1459 1.2 christos if (options->hpn_buffer_size > -1)
1460 1.2 christos {
1461 1.2 christos /* if a user tries to set the size to 0 set it to 1KB */
1462 1.2 christos if (options->hpn_buffer_size == 0)
1463 1.2 christos options->hpn_buffer_size = 1024;
1464 1.2 christos /*limit the buffer to 64MB*/
1465 1.2 christos if (options->hpn_buffer_size > 65536)
1466 1.2 christos {
1467 1.2 christos options->hpn_buffer_size = 65536*1024;
1468 1.2 christos debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1469 1.2 christos }
1470 1.2 christos debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1471 1.2 christos }
1472 1.2 christos if (options->tcp_rcv_buf == 0)
1473 1.2 christos options->tcp_rcv_buf = 1;
1474 1.2 christos if (options->tcp_rcv_buf > -1)
1475 1.2 christos options->tcp_rcv_buf *=1024;
1476 1.2 christos if (options->tcp_rcv_buf_poll == -1)
1477 1.2 christos options->tcp_rcv_buf_poll = 1;
1478 1.1 christos if (options->control_master == -1)
1479 1.1 christos options->control_master = 0;
1480 1.4 adam if (options->control_persist == -1) {
1481 1.4 adam options->control_persist = 0;
1482 1.4 adam options->control_persist_timeout = 0;
1483 1.4 adam }
1484 1.1 christos if (options->hash_known_hosts == -1)
1485 1.1 christos options->hash_known_hosts = 0;
1486 1.1 christos if (options->tun_open == -1)
1487 1.1 christos options->tun_open = SSH_TUNMODE_NO;
1488 1.1 christos if (options->tun_local == -1)
1489 1.1 christos options->tun_local = SSH_TUNID_ANY;
1490 1.1 christos if (options->tun_remote == -1)
1491 1.1 christos options->tun_remote = SSH_TUNID_ANY;
1492 1.1 christos if (options->permit_local_command == -1)
1493 1.1 christos options->permit_local_command = 0;
1494 1.3 christos if (options->use_roaming == -1)
1495 1.3 christos options->use_roaming = 1;
1496 1.1 christos if (options->visual_host_key == -1)
1497 1.1 christos options->visual_host_key = 0;
1498 1.1 christos if (options->zero_knowledge_password_authentication == -1)
1499 1.1 christos options->zero_knowledge_password_authentication = 0;
1500 1.5 christos if (options->ip_qos_interactive == -1)
1501 1.5 christos options->ip_qos_interactive = IPTOS_LOWDELAY;
1502 1.5 christos if (options->ip_qos_bulk == -1)
1503 1.5 christos options->ip_qos_bulk = IPTOS_THROUGHPUT;
1504 1.6 christos if (options->request_tty == -1)
1505 1.6 christos options->request_tty = REQUEST_TTY_AUTO;
1506 1.7 tls if (options->send_version_first == -1)
1507 1.7 tls options->send_version_first = 1;
1508 1.1 christos /* options->local_command should not be set by default */
1509 1.1 christos /* options->proxy_command should not be set by default */
1510 1.1 christos /* options->user will be set in the main program if appropriate */
1511 1.1 christos /* options->hostname will be set in the main program if appropriate */
1512 1.1 christos /* options->host_key_alias should not be set by default */
1513 1.1 christos /* options->preferred_authentications will be set in ssh */
1514 1.1 christos }
1515 1.1 christos
1516 1.1 christos /*
1517 1.1 christos * parse_forward
1518 1.1 christos * parses a string containing a port forwarding specification of the form:
1519 1.1 christos * dynamicfwd == 0
1520 1.1 christos * [listenhost:]listenport:connecthost:connectport
1521 1.1 christos * dynamicfwd == 1
1522 1.1 christos * [listenhost:]listenport
1523 1.1 christos * returns number of arguments parsed or zero on error
1524 1.1 christos */
1525 1.1 christos int
1526 1.1 christos parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1527 1.1 christos {
1528 1.1 christos int i;
1529 1.1 christos char *p, *cp, *fwdarg[4];
1530 1.1 christos
1531 1.1 christos memset(fwd, '\0', sizeof(*fwd));
1532 1.1 christos
1533 1.1 christos cp = p = xstrdup(fwdspec);
1534 1.1 christos
1535 1.1 christos /* skip leading spaces */
1536 1.2 christos while (isspace((unsigned char)*cp))
1537 1.1 christos cp++;
1538 1.1 christos
1539 1.1 christos for (i = 0; i < 4; ++i)
1540 1.1 christos if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1541 1.1 christos break;
1542 1.1 christos
1543 1.1 christos /* Check for trailing garbage */
1544 1.1 christos if (cp != NULL)
1545 1.1 christos i = 0; /* failure */
1546 1.1 christos
1547 1.1 christos switch (i) {
1548 1.1 christos case 1:
1549 1.1 christos fwd->listen_host = NULL;
1550 1.1 christos fwd->listen_port = a2port(fwdarg[0]);
1551 1.1 christos fwd->connect_host = xstrdup("socks");
1552 1.1 christos break;
1553 1.1 christos
1554 1.1 christos case 2:
1555 1.1 christos fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1556 1.1 christos fwd->listen_port = a2port(fwdarg[1]);
1557 1.1 christos fwd->connect_host = xstrdup("socks");
1558 1.1 christos break;
1559 1.1 christos
1560 1.1 christos case 3:
1561 1.1 christos fwd->listen_host = NULL;
1562 1.1 christos fwd->listen_port = a2port(fwdarg[0]);
1563 1.1 christos fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1564 1.1 christos fwd->connect_port = a2port(fwdarg[2]);
1565 1.1 christos break;
1566 1.1 christos
1567 1.1 christos case 4:
1568 1.1 christos fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1569 1.1 christos fwd->listen_port = a2port(fwdarg[1]);
1570 1.1 christos fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1571 1.1 christos fwd->connect_port = a2port(fwdarg[3]);
1572 1.1 christos break;
1573 1.1 christos default:
1574 1.1 christos i = 0; /* failure */
1575 1.1 christos }
1576 1.1 christos
1577 1.1 christos xfree(p);
1578 1.1 christos
1579 1.1 christos if (dynamicfwd) {
1580 1.1 christos if (!(i == 1 || i == 2))
1581 1.1 christos goto fail_free;
1582 1.1 christos } else {
1583 1.1 christos if (!(i == 3 || i == 4))
1584 1.1 christos goto fail_free;
1585 1.1 christos if (fwd->connect_port <= 0)
1586 1.1 christos goto fail_free;
1587 1.1 christos }
1588 1.1 christos
1589 1.1 christos if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1590 1.1 christos goto fail_free;
1591 1.1 christos
1592 1.1 christos if (fwd->connect_host != NULL &&
1593 1.1 christos strlen(fwd->connect_host) >= NI_MAXHOST)
1594 1.1 christos goto fail_free;
1595 1.1 christos if (fwd->listen_host != NULL &&
1596 1.1 christos strlen(fwd->listen_host) >= NI_MAXHOST)
1597 1.1 christos goto fail_free;
1598 1.1 christos
1599 1.1 christos
1600 1.1 christos return (i);
1601 1.1 christos
1602 1.1 christos fail_free:
1603 1.1 christos if (fwd->connect_host != NULL) {
1604 1.1 christos xfree(fwd->connect_host);
1605 1.1 christos fwd->connect_host = NULL;
1606 1.1 christos }
1607 1.1 christos if (fwd->listen_host != NULL) {
1608 1.1 christos xfree(fwd->listen_host);
1609 1.1 christos fwd->listen_host = NULL;
1610 1.1 christos }
1611 1.1 christos return (0);
1612 1.1 christos }
1613