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