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