readconf.c revision 1.1.1.12 1 1.1.1.12 christos /* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 djm Exp $ */
2 1.1 christos /*
3 1.1 christos * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
4 1.1 christos * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
5 1.1 christos * All rights reserved
6 1.1 christos * Functions for reading the configuration files.
7 1.1 christos *
8 1.1 christos * As far as I am concerned, the code I have written for this software
9 1.1 christos * can be used freely for any purpose. Any derived versions of this
10 1.1 christos * software must be clearly marked as such, and if the derived work is
11 1.1 christos * incompatible with the protocol description in the RFC file, it must be
12 1.1 christos * called by a name other than "ssh" or "Secure Shell".
13 1.1 christos */
14 1.1 christos
15 1.1 christos #include <sys/types.h>
16 1.1 christos #include <sys/stat.h>
17 1.1 christos #include <sys/socket.h>
18 1.1.1.8 christos #include <sys/wait.h>
19 1.1.1.8 christos #include <sys/un.h>
20 1.1 christos
21 1.1 christos #include <netinet/in.h>
22 1.1.1.4 christos #include <netinet/ip.h>
23 1.1 christos
24 1.1 christos #include <ctype.h>
25 1.1 christos #include <errno.h>
26 1.1.1.8 christos #include <fcntl.h>
27 1.1 christos #include <netdb.h>
28 1.1.1.8 christos #include <paths.h>
29 1.1.1.8 christos #include <pwd.h>
30 1.1 christos #include <signal.h>
31 1.1 christos #include <stdio.h>
32 1.1 christos #include <string.h>
33 1.1 christos #include <unistd.h>
34 1.1.1.9 christos #include <limits.h>
35 1.1.1.7 christos #include <util.h>
36 1.1.1.9 christos #include <vis.h>
37 1.1 christos
38 1.1 christos #include "xmalloc.h"
39 1.1 christos #include "ssh.h"
40 1.1 christos #include "compat.h"
41 1.1 christos #include "cipher.h"
42 1.1 christos #include "pathnames.h"
43 1.1 christos #include "log.h"
44 1.1.1.9 christos #include "sshkey.h"
45 1.1.1.8 christos #include "misc.h"
46 1.1 christos #include "readconf.h"
47 1.1 christos #include "match.h"
48 1.1 christos #include "kex.h"
49 1.1 christos #include "mac.h"
50 1.1.1.8 christos #include "uidswap.h"
51 1.1.1.9 christos #include "myproposal.h"
52 1.1.1.9 christos #include "digest.h"
53 1.1 christos
54 1.1 christos /* Format of the configuration file:
55 1.1 christos
56 1.1 christos # Configuration data is parsed as follows:
57 1.1 christos # 1. command line options
58 1.1 christos # 2. user-specific file
59 1.1 christos # 3. system-wide file
60 1.1 christos # Any configuration value is only changed the first time it is set.
61 1.1 christos # Thus, host-specific definitions should be at the beginning of the
62 1.1 christos # configuration file, and defaults at the end.
63 1.1 christos
64 1.1 christos # Host-specific declarations. These may override anything above. A single
65 1.1 christos # host may match multiple declarations; these are processed in the order
66 1.1 christos # that they are given in.
67 1.1 christos
68 1.1 christos Host *.ngs.fi ngs.fi
69 1.1 christos User foo
70 1.1 christos
71 1.1 christos Host fake.com
72 1.1 christos HostName another.host.name.real.org
73 1.1 christos User blaah
74 1.1 christos Port 34289
75 1.1 christos ForwardX11 no
76 1.1 christos ForwardAgent no
77 1.1 christos
78 1.1 christos Host books.com
79 1.1 christos RemoteForward 9999 shadows.cs.hut.fi:9999
80 1.1 christos Cipher 3des
81 1.1 christos
82 1.1 christos Host fascist.blob.com
83 1.1 christos Port 23123
84 1.1 christos User tylonen
85 1.1 christos PasswordAuthentication no
86 1.1 christos
87 1.1 christos Host puukko.hut.fi
88 1.1 christos User t35124p
89 1.1 christos ProxyCommand ssh-proxy %h %p
90 1.1 christos
91 1.1 christos Host *.fr
92 1.1 christos PublicKeyAuthentication no
93 1.1 christos
94 1.1 christos Host *.su
95 1.1 christos Cipher none
96 1.1 christos PasswordAuthentication no
97 1.1 christos
98 1.1 christos Host vpn.fake.com
99 1.1 christos Tunnel yes
100 1.1 christos TunnelDevice 3
101 1.1 christos
102 1.1 christos # Defaults for various options
103 1.1 christos Host *
104 1.1 christos ForwardAgent no
105 1.1 christos ForwardX11 no
106 1.1 christos PasswordAuthentication yes
107 1.1 christos RSAAuthentication yes
108 1.1 christos RhostsRSAAuthentication yes
109 1.1 christos StrictHostKeyChecking yes
110 1.1 christos TcpKeepAlive no
111 1.1 christos IdentityFile ~/.ssh/identity
112 1.1 christos Port 22
113 1.1 christos EscapeChar ~
114 1.1 christos
115 1.1 christos */
116 1.1 christos
117 1.1 christos /* Keyword tokens. */
118 1.1 christos
119 1.1 christos typedef enum {
120 1.1 christos oBadOption,
121 1.1.1.8 christos oHost, oMatch,
122 1.1.1.3 adam oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
123 1.1.1.3 adam oGatewayPorts, oExitOnForwardFailure,
124 1.1 christos oPasswordAuthentication, oRSAAuthentication,
125 1.1 christos oChallengeResponseAuthentication, oXAuthLocation,
126 1.1 christos oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
127 1.1.1.12 christos oCertificateFile, oAddKeysToAgent,
128 1.1.1.8 christos oUser, 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.1.9 christos oPubkeyAuthentication,
134 1.1 christos oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
135 1.1 christos oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
136 1.1.1.3 adam oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
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.1.3 adam oSendEnv, oControlPath, oControlMaster, oControlPersist,
142 1.1.1.3 adam oHashKnownHosts,
143 1.1 christos oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
144 1.1.1.12 christos oVisualHostKey,
145 1.1.1.8 christos oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
146 1.1.1.8 christos oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
147 1.1.1.8 christos oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
148 1.1.1.9 christos oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
149 1.1.1.9 christos oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
150 1.1.1.11 christos oPubkeyAcceptedKeyTypes,
151 1.1.1.7 christos oIgnoredUnknownOption, oDeprecated, oUnsupported
152 1.1 christos } OpCodes;
153 1.1 christos
154 1.1 christos /* Textual representations of the tokens. */
155 1.1 christos
156 1.1 christos static struct {
157 1.1 christos const char *name;
158 1.1 christos OpCodes opcode;
159 1.1 christos } keywords[] = {
160 1.1 christos { "forwardagent", oForwardAgent },
161 1.1 christos { "forwardx11", oForwardX11 },
162 1.1 christos { "forwardx11trusted", oForwardX11Trusted },
163 1.1.1.3 adam { "forwardx11timeout", oForwardX11Timeout },
164 1.1 christos { "exitonforwardfailure", oExitOnForwardFailure },
165 1.1 christos { "xauthlocation", oXAuthLocation },
166 1.1 christos { "gatewayports", oGatewayPorts },
167 1.1 christos { "useprivilegedport", oUsePrivilegedPort },
168 1.1 christos { "rhostsauthentication", oDeprecated },
169 1.1 christos { "passwordauthentication", oPasswordAuthentication },
170 1.1 christos { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
171 1.1 christos { "kbdinteractivedevices", oKbdInteractiveDevices },
172 1.1 christos { "rsaauthentication", oRSAAuthentication },
173 1.1 christos { "pubkeyauthentication", oPubkeyAuthentication },
174 1.1 christos { "dsaauthentication", oPubkeyAuthentication }, /* alias */
175 1.1 christos { "rhostsrsaauthentication", oRhostsRSAAuthentication },
176 1.1 christos { "hostbasedauthentication", oHostbasedAuthentication },
177 1.1 christos { "challengeresponseauthentication", oChallengeResponseAuthentication },
178 1.1 christos { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
179 1.1 christos { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
180 1.1 christos { "kerberosauthentication", oUnsupported },
181 1.1 christos { "kerberostgtpassing", oUnsupported },
182 1.1 christos { "afstokenpassing", oUnsupported },
183 1.1 christos #if defined(GSSAPI)
184 1.1 christos { "gssapiauthentication", oGssAuthentication },
185 1.1 christos { "gssapidelegatecredentials", oGssDelegateCreds },
186 1.1 christos #else
187 1.1 christos { "gssapiauthentication", oUnsupported },
188 1.1 christos { "gssapidelegatecredentials", oUnsupported },
189 1.1 christos #endif
190 1.1 christos { "fallbacktorsh", oDeprecated },
191 1.1 christos { "usersh", oDeprecated },
192 1.1 christos { "identityfile", oIdentityFile },
193 1.1 christos { "identityfile2", oIdentityFile }, /* obsolete */
194 1.1 christos { "identitiesonly", oIdentitiesOnly },
195 1.1.1.12 christos { "certificatefile", oCertificateFile },
196 1.1.1.12 christos { "addkeystoagent", oAddKeysToAgent },
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.1.8 christos { "match", oMatch },
210 1.1 christos { "escapechar", oEscapeChar },
211 1.1 christos { "globalknownhostsfile", oGlobalKnownHostsFile },
212 1.1.1.5 christos { "globalknownhostsfile2", oDeprecated },
213 1.1 christos { "userknownhostsfile", oUserKnownHostsFile },
214 1.1.1.9 christos { "userknownhostsfile2", oDeprecated },
215 1.1 christos { "connectionattempts", oConnectionAttempts },
216 1.1 christos { "batchmode", oBatchMode },
217 1.1 christos { "checkhostip", oCheckHostIP },
218 1.1 christos { "stricthostkeychecking", oStrictHostKeyChecking },
219 1.1 christos { "compression", oCompression },
220 1.1 christos { "compressionlevel", oCompressionLevel },
221 1.1 christos { "tcpkeepalive", oTCPKeepAlive },
222 1.1 christos { "keepalive", oTCPKeepAlive }, /* obsolete */
223 1.1 christos { "numberofpasswordprompts", oNumberOfPasswordPrompts },
224 1.1 christos { "loglevel", oLogLevel },
225 1.1 christos { "dynamicforward", oDynamicForward },
226 1.1 christos { "preferredauthentications", oPreferredAuthentications },
227 1.1 christos { "hostkeyalgorithms", oHostKeyAlgorithms },
228 1.1 christos { "bindaddress", oBindAddress },
229 1.1.1.3 adam #ifdef ENABLE_PKCS11
230 1.1.1.3 adam { "smartcarddevice", oPKCS11Provider },
231 1.1.1.3 adam { "pkcs11provider", oPKCS11Provider },
232 1.1 christos #else
233 1.1 christos { "smartcarddevice", oUnsupported },
234 1.1.1.3 adam { "pkcs11provider", oUnsupported },
235 1.1 christos #endif
236 1.1 christos { "clearallforwardings", oClearAllForwardings },
237 1.1 christos { "enablesshkeysign", oEnableSSHKeysign },
238 1.1 christos { "verifyhostkeydns", oVerifyHostKeyDNS },
239 1.1 christos { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
240 1.1 christos { "rekeylimit", oRekeyLimit },
241 1.1 christos { "connecttimeout", oConnectTimeout },
242 1.1 christos { "addressfamily", oAddressFamily },
243 1.1 christos { "serveraliveinterval", oServerAliveInterval },
244 1.1 christos { "serveralivecountmax", oServerAliveCountMax },
245 1.1 christos { "sendenv", oSendEnv },
246 1.1 christos { "controlpath", oControlPath },
247 1.1 christos { "controlmaster", oControlMaster },
248 1.1.1.3 adam { "controlpersist", oControlPersist },
249 1.1 christos { "hashknownhosts", oHashKnownHosts },
250 1.1 christos { "tunnel", oTunnel },
251 1.1 christos { "tunneldevice", oTunnelDevice },
252 1.1 christos { "localcommand", oLocalCommand },
253 1.1 christos { "permitlocalcommand", oPermitLocalCommand },
254 1.1 christos { "visualhostkey", oVisualHostKey },
255 1.1.1.12 christos { "useroaming", oDeprecated },
256 1.1.1.4 christos { "kexalgorithms", oKexAlgorithms },
257 1.1.1.4 christos { "ipqos", oIPQoS },
258 1.1.1.5 christos { "requesttty", oRequestTTY },
259 1.1.1.8 christos { "proxyusefdpass", oProxyUseFdpass },
260 1.1.1.8 christos { "canonicaldomains", oCanonicalDomains },
261 1.1.1.8 christos { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
262 1.1.1.8 christos { "canonicalizehostname", oCanonicalizeHostname },
263 1.1.1.8 christos { "canonicalizemaxdots", oCanonicalizeMaxDots },
264 1.1.1.8 christos { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
265 1.1.1.8 christos { "streamlocalbindmask", oStreamLocalBindMask },
266 1.1.1.8 christos { "streamlocalbindunlink", oStreamLocalBindUnlink },
267 1.1.1.9 christos { "revokedhostkeys", oRevokedHostKeys },
268 1.1.1.9 christos { "fingerprinthash", oFingerprintHash },
269 1.1.1.9 christos { "updatehostkeys", oUpdateHostkeys },
270 1.1.1.9 christos { "hostbasedkeytypes", oHostbasedKeyTypes },
271 1.1.1.11 christos { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
272 1.1.1.7 christos { "ignoreunknown", oIgnoreUnknown },
273 1.1 christos
274 1.1 christos { NULL, oBadOption }
275 1.1 christos };
276 1.1 christos
277 1.1 christos /*
278 1.1 christos * Adds a local TCP/IP port forward to options. Never returns if there is an
279 1.1 christos * error.
280 1.1 christos */
281 1.1 christos
282 1.1 christos void
283 1.1.1.8 christos add_local_forward(Options *options, const struct Forward *newfwd)
284 1.1 christos {
285 1.1.1.8 christos struct Forward *fwd;
286 1.1 christos extern uid_t original_real_uid;
287 1.1.1.3 adam
288 1.1.1.8 christos if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
289 1.1.1.8 christos newfwd->listen_path == NULL)
290 1.1 christos fatal("Privileged ports can only be forwarded by root.");
291 1.1.1.10 christos options->local_forwards = xreallocarray(options->local_forwards,
292 1.1.1.3 adam options->num_local_forwards + 1,
293 1.1.1.3 adam sizeof(*options->local_forwards));
294 1.1 christos fwd = &options->local_forwards[options->num_local_forwards++];
295 1.1 christos
296 1.1 christos fwd->listen_host = newfwd->listen_host;
297 1.1 christos fwd->listen_port = newfwd->listen_port;
298 1.1.1.8 christos fwd->listen_path = newfwd->listen_path;
299 1.1 christos fwd->connect_host = newfwd->connect_host;
300 1.1 christos fwd->connect_port = newfwd->connect_port;
301 1.1.1.8 christos fwd->connect_path = newfwd->connect_path;
302 1.1 christos }
303 1.1 christos
304 1.1 christos /*
305 1.1 christos * Adds a remote TCP/IP port forward to options. Never returns if there is
306 1.1 christos * an error.
307 1.1 christos */
308 1.1 christos
309 1.1 christos void
310 1.1.1.8 christos add_remote_forward(Options *options, const struct Forward *newfwd)
311 1.1 christos {
312 1.1.1.8 christos struct Forward *fwd;
313 1.1.1.3 adam
314 1.1.1.10 christos options->remote_forwards = xreallocarray(options->remote_forwards,
315 1.1.1.3 adam options->num_remote_forwards + 1,
316 1.1.1.3 adam sizeof(*options->remote_forwards));
317 1.1 christos fwd = &options->remote_forwards[options->num_remote_forwards++];
318 1.1 christos
319 1.1 christos fwd->listen_host = newfwd->listen_host;
320 1.1 christos fwd->listen_port = newfwd->listen_port;
321 1.1.1.8 christos fwd->listen_path = newfwd->listen_path;
322 1.1 christos fwd->connect_host = newfwd->connect_host;
323 1.1 christos fwd->connect_port = newfwd->connect_port;
324 1.1.1.8 christos fwd->connect_path = newfwd->connect_path;
325 1.1.1.6 christos fwd->handle = newfwd->handle;
326 1.1.1.3 adam fwd->allocated_port = 0;
327 1.1 christos }
328 1.1 christos
329 1.1 christos static void
330 1.1 christos clear_forwardings(Options *options)
331 1.1 christos {
332 1.1 christos int i;
333 1.1 christos
334 1.1 christos for (i = 0; i < options->num_local_forwards; i++) {
335 1.1.1.7 christos free(options->local_forwards[i].listen_host);
336 1.1.1.8 christos free(options->local_forwards[i].listen_path);
337 1.1.1.7 christos free(options->local_forwards[i].connect_host);
338 1.1.1.8 christos free(options->local_forwards[i].connect_path);
339 1.1 christos }
340 1.1.1.3 adam if (options->num_local_forwards > 0) {
341 1.1.1.7 christos free(options->local_forwards);
342 1.1.1.3 adam options->local_forwards = NULL;
343 1.1.1.3 adam }
344 1.1 christos options->num_local_forwards = 0;
345 1.1 christos for (i = 0; i < options->num_remote_forwards; i++) {
346 1.1.1.7 christos free(options->remote_forwards[i].listen_host);
347 1.1.1.8 christos free(options->remote_forwards[i].listen_path);
348 1.1.1.7 christos free(options->remote_forwards[i].connect_host);
349 1.1.1.8 christos free(options->remote_forwards[i].connect_path);
350 1.1 christos }
351 1.1.1.3 adam if (options->num_remote_forwards > 0) {
352 1.1.1.7 christos free(options->remote_forwards);
353 1.1.1.3 adam options->remote_forwards = NULL;
354 1.1.1.3 adam }
355 1.1 christos options->num_remote_forwards = 0;
356 1.1 christos options->tun_open = SSH_TUNMODE_NO;
357 1.1 christos }
358 1.1 christos
359 1.1.1.7 christos void
360 1.1.1.12 christos add_certificate_file(Options *options, const char *path, int userprovided)
361 1.1.1.12 christos {
362 1.1.1.12 christos int i;
363 1.1.1.12 christos
364 1.1.1.12 christos if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
365 1.1.1.12 christos fatal("Too many certificate files specified (max %d)",
366 1.1.1.12 christos SSH_MAX_CERTIFICATE_FILES);
367 1.1.1.12 christos
368 1.1.1.12 christos /* Avoid registering duplicates */
369 1.1.1.12 christos for (i = 0; i < options->num_certificate_files; i++) {
370 1.1.1.12 christos if (options->certificate_file_userprovided[i] == userprovided &&
371 1.1.1.12 christos strcmp(options->certificate_files[i], path) == 0) {
372 1.1.1.12 christos debug2("%s: ignoring duplicate key %s", __func__, path);
373 1.1.1.12 christos return;
374 1.1.1.12 christos }
375 1.1.1.12 christos }
376 1.1.1.12 christos
377 1.1.1.12 christos options->certificate_file_userprovided[options->num_certificate_files] =
378 1.1.1.12 christos userprovided;
379 1.1.1.12 christos options->certificate_files[options->num_certificate_files++] =
380 1.1.1.12 christos xstrdup(path);
381 1.1.1.12 christos }
382 1.1.1.12 christos
383 1.1.1.12 christos void
384 1.1.1.7 christos add_identity_file(Options *options, const char *dir, const char *filename,
385 1.1.1.7 christos int userprovided)
386 1.1.1.7 christos {
387 1.1.1.7 christos char *path;
388 1.1.1.8 christos int i;
389 1.1.1.7 christos
390 1.1.1.7 christos if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
391 1.1.1.7 christos fatal("Too many identity files specified (max %d)",
392 1.1.1.7 christos SSH_MAX_IDENTITY_FILES);
393 1.1.1.7 christos
394 1.1.1.7 christos if (dir == NULL) /* no dir, filename is absolute */
395 1.1.1.7 christos path = xstrdup(filename);
396 1.1.1.7 christos else
397 1.1.1.7 christos (void)xasprintf(&path, "%.100s%.100s", dir, filename);
398 1.1.1.7 christos
399 1.1.1.8 christos /* Avoid registering duplicates */
400 1.1.1.8 christos for (i = 0; i < options->num_identity_files; i++) {
401 1.1.1.8 christos if (options->identity_file_userprovided[i] == userprovided &&
402 1.1.1.8 christos strcmp(options->identity_files[i], path) == 0) {
403 1.1.1.8 christos debug2("%s: ignoring duplicate key %s", __func__, path);
404 1.1.1.8 christos free(path);
405 1.1.1.8 christos return;
406 1.1.1.8 christos }
407 1.1.1.8 christos }
408 1.1.1.8 christos
409 1.1.1.7 christos options->identity_file_userprovided[options->num_identity_files] =
410 1.1.1.7 christos userprovided;
411 1.1.1.7 christos options->identity_files[options->num_identity_files++] = path;
412 1.1.1.7 christos }
413 1.1.1.7 christos
414 1.1.1.8 christos int
415 1.1.1.8 christos default_ssh_port(void)
416 1.1.1.8 christos {
417 1.1.1.8 christos static int port;
418 1.1.1.8 christos struct servent *sp;
419 1.1.1.8 christos
420 1.1.1.8 christos if (port == 0) {
421 1.1.1.8 christos sp = getservbyname(SSH_SERVICE_NAME, "tcp");
422 1.1.1.8 christos port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
423 1.1.1.8 christos }
424 1.1.1.8 christos return port;
425 1.1.1.8 christos }
426 1.1.1.8 christos
427 1.1 christos /*
428 1.1.1.8 christos * Execute a command in a shell.
429 1.1.1.8 christos * Return its exit status or -1 on abnormal exit.
430 1.1 christos */
431 1.1.1.8 christos static int
432 1.1.1.8 christos execute_in_shell(const char *cmd)
433 1.1.1.8 christos {
434 1.1.1.12 christos char *shell;
435 1.1.1.8 christos pid_t pid;
436 1.1.1.8 christos int devnull, status;
437 1.1.1.8 christos extern uid_t original_real_uid;
438 1.1.1.8 christos
439 1.1.1.8 christos if ((shell = getenv("SHELL")) == NULL)
440 1.1.1.8 christos shell = _PATH_BSHELL;
441 1.1.1.8 christos
442 1.1.1.8 christos /* Need this to redirect subprocess stdin/out */
443 1.1.1.8 christos if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
444 1.1.1.8 christos fatal("open(/dev/null): %s", strerror(errno));
445 1.1.1.8 christos
446 1.1.1.8 christos debug("Executing command: '%.500s'", cmd);
447 1.1.1.8 christos
448 1.1.1.8 christos /* Fork and execute the command. */
449 1.1.1.8 christos if ((pid = fork()) == 0) {
450 1.1.1.8 christos char *argv[4];
451 1.1.1.8 christos
452 1.1.1.8 christos /* Child. Permanently give up superuser privileges. */
453 1.1.1.8 christos permanently_drop_suid(original_real_uid);
454 1.1.1.8 christos
455 1.1.1.8 christos /* Redirect child stdin and stdout. Leave stderr */
456 1.1.1.8 christos if (dup2(devnull, STDIN_FILENO) == -1)
457 1.1.1.8 christos fatal("dup2: %s", strerror(errno));
458 1.1.1.8 christos if (dup2(devnull, STDOUT_FILENO) == -1)
459 1.1.1.8 christos fatal("dup2: %s", strerror(errno));
460 1.1.1.8 christos if (devnull > STDERR_FILENO)
461 1.1.1.8 christos close(devnull);
462 1.1.1.8 christos closefrom(STDERR_FILENO + 1);
463 1.1.1.8 christos
464 1.1.1.8 christos argv[0] = shell;
465 1.1.1.8 christos argv[1] = "-c";
466 1.1.1.12 christos argv[2] = xstrdup(cmd);
467 1.1.1.8 christos argv[3] = NULL;
468 1.1.1.8 christos
469 1.1.1.8 christos execv(argv[0], argv);
470 1.1.1.8 christos error("Unable to execute '%.100s': %s", cmd, strerror(errno));
471 1.1.1.8 christos /* Die with signal to make this error apparent to parent. */
472 1.1.1.8 christos signal(SIGTERM, SIG_DFL);
473 1.1.1.8 christos kill(getpid(), SIGTERM);
474 1.1.1.8 christos _exit(1);
475 1.1.1.8 christos }
476 1.1.1.8 christos /* Parent. */
477 1.1.1.8 christos if (pid < 0)
478 1.1.1.8 christos fatal("%s: fork: %.100s", __func__, strerror(errno));
479 1.1.1.8 christos
480 1.1.1.8 christos close(devnull);
481 1.1.1.8 christos
482 1.1.1.8 christos while (waitpid(pid, &status, 0) == -1) {
483 1.1.1.8 christos if (errno != EINTR && errno != EAGAIN)
484 1.1.1.8 christos fatal("%s: waitpid: %s", __func__, strerror(errno));
485 1.1.1.8 christos }
486 1.1.1.8 christos if (!WIFEXITED(status)) {
487 1.1.1.8 christos error("command '%.100s' exited abnormally", cmd);
488 1.1.1.8 christos return -1;
489 1.1.1.9 christos }
490 1.1.1.8 christos debug3("command returned status %d", WEXITSTATUS(status));
491 1.1.1.8 christos return WEXITSTATUS(status);
492 1.1.1.8 christos }
493 1.1.1.8 christos
494 1.1.1.8 christos /*
495 1.1.1.8 christos * Parse and execute a Match directive.
496 1.1.1.8 christos */
497 1.1.1.8 christos static int
498 1.1.1.8 christos match_cfg_line(Options *options, char **condition, struct passwd *pw,
499 1.1.1.9 christos const char *host_arg, const char *original_host, int post_canon,
500 1.1.1.9 christos const char *filename, int linenum)
501 1.1.1.8 christos {
502 1.1.1.9 christos char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
503 1.1.1.8 christos const char *ruser;
504 1.1.1.9 christos int r, port, this_result, result = 1, attributes = 0, negate;
505 1.1.1.8 christos char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
506 1.1.1.8 christos
507 1.1.1.8 christos /*
508 1.1.1.8 christos * Configuration is likely to be incomplete at this point so we
509 1.1.1.8 christos * must be prepared to use default values.
510 1.1.1.8 christos */
511 1.1.1.8 christos port = options->port <= 0 ? default_ssh_port() : options->port;
512 1.1.1.8 christos ruser = options->user == NULL ? pw->pw_name : options->user;
513 1.1.1.12 christos if (post_canon) {
514 1.1.1.12 christos host = xstrdup(options->hostname);
515 1.1.1.12 christos } else if (options->hostname != NULL) {
516 1.1.1.8 christos /* NB. Please keep in sync with ssh.c:main() */
517 1.1.1.8 christos host = percent_expand(options->hostname,
518 1.1.1.8 christos "h", host_arg, (char *)NULL);
519 1.1.1.12 christos } else {
520 1.1.1.8 christos host = xstrdup(host_arg);
521 1.1.1.12 christos }
522 1.1.1.8 christos
523 1.1.1.9 christos debug2("checking match for '%s' host %s originally %s",
524 1.1.1.9 christos cp, host, original_host);
525 1.1.1.9 christos while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
526 1.1.1.9 christos criteria = NULL;
527 1.1.1.9 christos this_result = 1;
528 1.1.1.9 christos if ((negate = attrib[0] == '!'))
529 1.1.1.9 christos attrib++;
530 1.1.1.9 christos /* criteria "all" and "canonical" have no argument */
531 1.1.1.8 christos if (strcasecmp(attrib, "all") == 0) {
532 1.1.1.9 christos if (attributes > 1 ||
533 1.1.1.8 christos ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
534 1.1.1.9 christos error("%.200s line %d: '%s' cannot be combined "
535 1.1.1.9 christos "with other Match attributes",
536 1.1.1.9 christos filename, linenum, oattrib);
537 1.1.1.8 christos result = -1;
538 1.1.1.8 christos goto out;
539 1.1.1.8 christos }
540 1.1.1.9 christos if (result)
541 1.1.1.9 christos result = negate ? 0 : 1;
542 1.1.1.8 christos goto out;
543 1.1.1.8 christos }
544 1.1.1.9 christos attributes++;
545 1.1.1.9 christos if (strcasecmp(attrib, "canonical") == 0) {
546 1.1.1.9 christos r = !!post_canon; /* force bitmask member to boolean */
547 1.1.1.9 christos if (r == (negate ? 1 : 0))
548 1.1.1.9 christos this_result = result = 0;
549 1.1.1.9 christos debug3("%.200s line %d: %smatched '%s'",
550 1.1.1.9 christos filename, linenum,
551 1.1.1.9 christos this_result ? "" : "not ", oattrib);
552 1.1.1.9 christos continue;
553 1.1.1.9 christos }
554 1.1.1.9 christos /* All other criteria require an argument */
555 1.1.1.8 christos if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
556 1.1.1.8 christos error("Missing Match criteria for %s", attrib);
557 1.1.1.8 christos result = -1;
558 1.1.1.8 christos goto out;
559 1.1.1.8 christos }
560 1.1.1.8 christos if (strcasecmp(attrib, "host") == 0) {
561 1.1.1.9 christos criteria = xstrdup(host);
562 1.1.1.10 christos r = match_hostname(host, arg) == 1;
563 1.1.1.9 christos if (r == (negate ? 1 : 0))
564 1.1.1.9 christos this_result = result = 0;
565 1.1.1.8 christos } else if (strcasecmp(attrib, "originalhost") == 0) {
566 1.1.1.9 christos criteria = xstrdup(original_host);
567 1.1.1.10 christos r = match_hostname(original_host, arg) == 1;
568 1.1.1.9 christos if (r == (negate ? 1 : 0))
569 1.1.1.9 christos this_result = result = 0;
570 1.1.1.8 christos } else if (strcasecmp(attrib, "user") == 0) {
571 1.1.1.9 christos criteria = xstrdup(ruser);
572 1.1.1.10 christos r = match_pattern_list(ruser, arg, 0) == 1;
573 1.1.1.9 christos if (r == (negate ? 1 : 0))
574 1.1.1.9 christos this_result = result = 0;
575 1.1.1.8 christos } else if (strcasecmp(attrib, "localuser") == 0) {
576 1.1.1.9 christos criteria = xstrdup(pw->pw_name);
577 1.1.1.10 christos r = match_pattern_list(pw->pw_name, arg, 0) == 1;
578 1.1.1.9 christos if (r == (negate ? 1 : 0))
579 1.1.1.9 christos this_result = result = 0;
580 1.1.1.8 christos } else if (strcasecmp(attrib, "exec") == 0) {
581 1.1.1.8 christos if (gethostname(thishost, sizeof(thishost)) == -1)
582 1.1.1.8 christos fatal("gethostname: %s", strerror(errno));
583 1.1.1.8 christos strlcpy(shorthost, thishost, sizeof(shorthost));
584 1.1.1.8 christos shorthost[strcspn(thishost, ".")] = '\0';
585 1.1.1.8 christos snprintf(portstr, sizeof(portstr), "%d", port);
586 1.1.1.8 christos
587 1.1.1.8 christos cmd = percent_expand(arg,
588 1.1.1.8 christos "L", shorthost,
589 1.1.1.8 christos "d", pw->pw_dir,
590 1.1.1.8 christos "h", host,
591 1.1.1.8 christos "l", thishost,
592 1.1.1.9 christos "n", original_host,
593 1.1.1.8 christos "p", portstr,
594 1.1.1.8 christos "r", ruser,
595 1.1.1.8 christos "u", pw->pw_name,
596 1.1.1.8 christos (char *)NULL);
597 1.1.1.8 christos if (result != 1) {
598 1.1.1.8 christos /* skip execution if prior predicate failed */
599 1.1.1.9 christos debug3("%.200s line %d: skipped exec "
600 1.1.1.9 christos "\"%.100s\"", filename, linenum, cmd);
601 1.1.1.9 christos free(cmd);
602 1.1.1.9 christos continue;
603 1.1.1.9 christos }
604 1.1.1.9 christos r = execute_in_shell(cmd);
605 1.1.1.9 christos if (r == -1) {
606 1.1.1.9 christos fatal("%.200s line %d: match exec "
607 1.1.1.9 christos "'%.100s' error", filename,
608 1.1.1.9 christos linenum, cmd);
609 1.1.1.8 christos }
610 1.1.1.9 christos criteria = xstrdup(cmd);
611 1.1.1.8 christos free(cmd);
612 1.1.1.9 christos /* Force exit status to boolean */
613 1.1.1.9 christos r = r == 0;
614 1.1.1.9 christos if (r == (negate ? 1 : 0))
615 1.1.1.9 christos this_result = result = 0;
616 1.1.1.8 christos } else {
617 1.1.1.8 christos error("Unsupported Match attribute %s", attrib);
618 1.1.1.8 christos result = -1;
619 1.1.1.8 christos goto out;
620 1.1.1.8 christos }
621 1.1.1.9 christos debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
622 1.1.1.9 christos filename, linenum, this_result ? "": "not ",
623 1.1.1.9 christos oattrib, criteria);
624 1.1.1.9 christos free(criteria);
625 1.1.1.8 christos }
626 1.1.1.8 christos if (attributes == 0) {
627 1.1.1.8 christos error("One or more attributes required for Match");
628 1.1.1.8 christos result = -1;
629 1.1.1.8 christos goto out;
630 1.1.1.8 christos }
631 1.1.1.8 christos out:
632 1.1.1.9 christos if (result != -1)
633 1.1.1.9 christos debug2("match %sfound", result ? "" : "not ");
634 1.1.1.9 christos *condition = cp;
635 1.1.1.8 christos free(host);
636 1.1.1.8 christos return result;
637 1.1.1.8 christos }
638 1.1.1.8 christos
639 1.1.1.8 christos /* Check and prepare a domain name: removes trailing '.' and lowercases */
640 1.1.1.8 christos static void
641 1.1.1.8 christos valid_domain(char *name, const char *filename, int linenum)
642 1.1.1.8 christos {
643 1.1.1.8 christos size_t i, l = strlen(name);
644 1.1.1.8 christos u_char c, last = '\0';
645 1.1.1.8 christos
646 1.1.1.8 christos if (l == 0)
647 1.1.1.8 christos fatal("%s line %d: empty hostname suffix", filename, linenum);
648 1.1.1.8 christos if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
649 1.1.1.8 christos fatal("%s line %d: hostname suffix \"%.100s\" "
650 1.1.1.8 christos "starts with invalid character", filename, linenum, name);
651 1.1.1.8 christos for (i = 0; i < l; i++) {
652 1.1.1.8 christos c = tolower((u_char)name[i]);
653 1.1.1.8 christos name[i] = (char)c;
654 1.1.1.8 christos if (last == '.' && c == '.')
655 1.1.1.8 christos fatal("%s line %d: hostname suffix \"%.100s\" contains "
656 1.1.1.8 christos "consecutive separators", filename, linenum, name);
657 1.1.1.8 christos if (c != '.' && c != '-' && !isalnum(c) &&
658 1.1.1.8 christos c != '_') /* technically invalid, but common */
659 1.1.1.8 christos fatal("%s line %d: hostname suffix \"%.100s\" contains "
660 1.1.1.8 christos "invalid characters", filename, linenum, name);
661 1.1.1.8 christos last = c;
662 1.1.1.8 christos }
663 1.1.1.8 christos if (name[l - 1] == '.')
664 1.1.1.8 christos name[l - 1] = '\0';
665 1.1.1.8 christos }
666 1.1.1.8 christos
667 1.1.1.8 christos /*
668 1.1.1.8 christos * Returns the number of the token pointed to by cp or oBadOption.
669 1.1.1.8 christos */
670 1.1 christos static OpCodes
671 1.1.1.7 christos parse_token(const char *cp, const char *filename, int linenum,
672 1.1.1.7 christos const char *ignored_unknown)
673 1.1 christos {
674 1.1.1.7 christos int i;
675 1.1 christos
676 1.1 christos for (i = 0; keywords[i].name; i++)
677 1.1.1.7 christos if (strcmp(cp, keywords[i].name) == 0)
678 1.1 christos return keywords[i].opcode;
679 1.1.1.10 christos if (ignored_unknown != NULL &&
680 1.1.1.10 christos match_pattern_list(cp, ignored_unknown, 1) == 1)
681 1.1.1.7 christos return oIgnoredUnknownOption;
682 1.1 christos error("%s: line %d: Bad configuration option: %s",
683 1.1 christos filename, linenum, cp);
684 1.1 christos return oBadOption;
685 1.1 christos }
686 1.1 christos
687 1.1.1.8 christos /* Multistate option parsing */
688 1.1.1.8 christos struct multistate {
689 1.1.1.8 christos char *key;
690 1.1.1.8 christos int value;
691 1.1.1.8 christos };
692 1.1.1.8 christos static const struct multistate multistate_flag[] = {
693 1.1.1.8 christos { "true", 1 },
694 1.1.1.8 christos { "false", 0 },
695 1.1.1.8 christos { "yes", 1 },
696 1.1.1.8 christos { "no", 0 },
697 1.1.1.8 christos { NULL, -1 }
698 1.1.1.8 christos };
699 1.1.1.8 christos static const struct multistate multistate_yesnoask[] = {
700 1.1.1.8 christos { "true", 1 },
701 1.1.1.8 christos { "false", 0 },
702 1.1.1.8 christos { "yes", 1 },
703 1.1.1.8 christos { "no", 0 },
704 1.1.1.8 christos { "ask", 2 },
705 1.1.1.8 christos { NULL, -1 }
706 1.1.1.8 christos };
707 1.1.1.12 christos static const struct multistate multistate_yesnoaskconfirm[] = {
708 1.1.1.12 christos { "true", 1 },
709 1.1.1.12 christos { "false", 0 },
710 1.1.1.12 christos { "yes", 1 },
711 1.1.1.12 christos { "no", 0 },
712 1.1.1.12 christos { "ask", 2 },
713 1.1.1.12 christos { "confirm", 3 },
714 1.1.1.12 christos { NULL, -1 }
715 1.1.1.12 christos };
716 1.1.1.8 christos static const struct multistate multistate_addressfamily[] = {
717 1.1.1.8 christos { "inet", AF_INET },
718 1.1.1.8 christos { "inet6", AF_INET6 },
719 1.1.1.8 christos { "any", AF_UNSPEC },
720 1.1.1.8 christos { NULL, -1 }
721 1.1.1.8 christos };
722 1.1.1.8 christos static const struct multistate multistate_controlmaster[] = {
723 1.1.1.8 christos { "true", SSHCTL_MASTER_YES },
724 1.1.1.8 christos { "yes", SSHCTL_MASTER_YES },
725 1.1.1.8 christos { "false", SSHCTL_MASTER_NO },
726 1.1.1.8 christos { "no", SSHCTL_MASTER_NO },
727 1.1.1.8 christos { "auto", SSHCTL_MASTER_AUTO },
728 1.1.1.8 christos { "ask", SSHCTL_MASTER_ASK },
729 1.1.1.8 christos { "autoask", SSHCTL_MASTER_AUTO_ASK },
730 1.1.1.8 christos { NULL, -1 }
731 1.1.1.8 christos };
732 1.1.1.8 christos static const struct multistate multistate_tunnel[] = {
733 1.1.1.8 christos { "ethernet", SSH_TUNMODE_ETHERNET },
734 1.1.1.8 christos { "point-to-point", SSH_TUNMODE_POINTOPOINT },
735 1.1.1.8 christos { "true", SSH_TUNMODE_DEFAULT },
736 1.1.1.8 christos { "yes", SSH_TUNMODE_DEFAULT },
737 1.1.1.8 christos { "false", SSH_TUNMODE_NO },
738 1.1.1.8 christos { "no", SSH_TUNMODE_NO },
739 1.1.1.8 christos { NULL, -1 }
740 1.1.1.8 christos };
741 1.1.1.8 christos static const struct multistate multistate_requesttty[] = {
742 1.1.1.8 christos { "true", REQUEST_TTY_YES },
743 1.1.1.8 christos { "yes", REQUEST_TTY_YES },
744 1.1.1.8 christos { "false", REQUEST_TTY_NO },
745 1.1.1.8 christos { "no", REQUEST_TTY_NO },
746 1.1.1.8 christos { "force", REQUEST_TTY_FORCE },
747 1.1.1.8 christos { "auto", REQUEST_TTY_AUTO },
748 1.1.1.8 christos { NULL, -1 }
749 1.1.1.8 christos };
750 1.1.1.8 christos static const struct multistate multistate_canonicalizehostname[] = {
751 1.1.1.8 christos { "true", SSH_CANONICALISE_YES },
752 1.1.1.8 christos { "false", SSH_CANONICALISE_NO },
753 1.1.1.8 christos { "yes", SSH_CANONICALISE_YES },
754 1.1.1.8 christos { "no", SSH_CANONICALISE_NO },
755 1.1.1.8 christos { "always", SSH_CANONICALISE_ALWAYS },
756 1.1.1.8 christos { NULL, -1 }
757 1.1.1.8 christos };
758 1.1.1.8 christos
759 1.1 christos /*
760 1.1 christos * Processes a single option line as used in the configuration files. This
761 1.1 christos * only sets those values that have not already been set.
762 1.1 christos */
763 1.1 christos #define WHITESPACE " \t\r\n"
764 1.1 christos int
765 1.1.1.8 christos process_config_line(Options *options, struct passwd *pw, const char *host,
766 1.1.1.9 christos const char *original_host, char *line, const char *filename,
767 1.1.1.9 christos int linenum, int *activep, int flags)
768 1.1 christos {
769 1.1.1.5 christos char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
770 1.1.1.5 christos char **cpptr, fwdarg[256];
771 1.1.1.7 christos u_int i, *uintptr, max_entries = 0;
772 1.1.1.8 christos int negated, opcode, *intptr, value, value2, cmdline = 0;
773 1.1 christos LogLevel *log_level_ptr;
774 1.1.1.7 christos long long val64;
775 1.1 christos size_t len;
776 1.1.1.8 christos struct Forward fwd;
777 1.1.1.8 christos const struct multistate *multistate_ptr;
778 1.1.1.8 christos struct allowed_cname *cname;
779 1.1.1.8 christos
780 1.1.1.8 christos if (activep == NULL) { /* We are processing a command line directive */
781 1.1.1.8 christos cmdline = 1;
782 1.1.1.8 christos activep = &cmdline;
783 1.1.1.8 christos }
784 1.1 christos
785 1.1 christos /* Strip trailing whitespace */
786 1.1.1.10 christos if ((len = strlen(line)) == 0)
787 1.1.1.10 christos return 0;
788 1.1.1.10 christos for (len--; len > 0; len--) {
789 1.1 christos if (strchr(WHITESPACE, line[len]) == NULL)
790 1.1 christos break;
791 1.1 christos line[len] = '\0';
792 1.1 christos }
793 1.1 christos
794 1.1 christos s = line;
795 1.1 christos /* Get the keyword. (Each line is supposed to begin with a keyword). */
796 1.1 christos if ((keyword = strdelim(&s)) == NULL)
797 1.1 christos return 0;
798 1.1 christos /* Ignore leading whitespace. */
799 1.1 christos if (*keyword == '\0')
800 1.1 christos keyword = strdelim(&s);
801 1.1 christos if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
802 1.1 christos return 0;
803 1.1.1.7 christos /* Match lowercase keyword */
804 1.1.1.8 christos lowercase(keyword);
805 1.1 christos
806 1.1.1.7 christos opcode = parse_token(keyword, filename, linenum,
807 1.1.1.7 christos options->ignored_unknown);
808 1.1 christos
809 1.1 christos switch (opcode) {
810 1.1 christos case oBadOption:
811 1.1 christos /* don't panic, but count bad options */
812 1.1 christos return -1;
813 1.1 christos /* NOTREACHED */
814 1.1.1.7 christos case oIgnoredUnknownOption:
815 1.1.1.7 christos debug("%s line %d: Ignored unknown option \"%s\"",
816 1.1.1.7 christos filename, linenum, keyword);
817 1.1.1.7 christos return 0;
818 1.1 christos case oConnectTimeout:
819 1.1 christos intptr = &options->connection_timeout;
820 1.1 christos parse_time:
821 1.1 christos arg = strdelim(&s);
822 1.1 christos if (!arg || *arg == '\0')
823 1.1 christos fatal("%s line %d: missing time value.",
824 1.1 christos filename, linenum);
825 1.1.1.9 christos if (strcmp(arg, "none") == 0)
826 1.1.1.9 christos value = -1;
827 1.1.1.9 christos else if ((value = convtime(arg)) == -1)
828 1.1 christos fatal("%s line %d: invalid time value.",
829 1.1 christos filename, linenum);
830 1.1 christos if (*activep && *intptr == -1)
831 1.1 christos *intptr = value;
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case oForwardAgent:
835 1.1 christos intptr = &options->forward_agent;
836 1.1.1.8 christos parse_flag:
837 1.1.1.8 christos multistate_ptr = multistate_flag;
838 1.1.1.8 christos parse_multistate:
839 1.1 christos arg = strdelim(&s);
840 1.1 christos if (!arg || *arg == '\0')
841 1.1.1.8 christos fatal("%s line %d: missing argument.",
842 1.1.1.8 christos filename, linenum);
843 1.1.1.8 christos value = -1;
844 1.1.1.8 christos for (i = 0; multistate_ptr[i].key != NULL; i++) {
845 1.1.1.8 christos if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
846 1.1.1.8 christos value = multistate_ptr[i].value;
847 1.1.1.8 christos break;
848 1.1.1.8 christos }
849 1.1.1.8 christos }
850 1.1.1.8 christos if (value == -1)
851 1.1.1.8 christos fatal("%s line %d: unsupported option \"%s\".",
852 1.1.1.8 christos filename, linenum, arg);
853 1.1 christos if (*activep && *intptr == -1)
854 1.1 christos *intptr = value;
855 1.1 christos break;
856 1.1 christos
857 1.1 christos case oForwardX11:
858 1.1 christos intptr = &options->forward_x11;
859 1.1 christos goto parse_flag;
860 1.1 christos
861 1.1 christos case oForwardX11Trusted:
862 1.1 christos intptr = &options->forward_x11_trusted;
863 1.1 christos goto parse_flag;
864 1.1.1.9 christos
865 1.1.1.3 adam case oForwardX11Timeout:
866 1.1.1.3 adam intptr = &options->forward_x11_timeout;
867 1.1.1.3 adam goto parse_time;
868 1.1 christos
869 1.1 christos case oGatewayPorts:
870 1.1.1.8 christos intptr = &options->fwd_opts.gateway_ports;
871 1.1 christos goto parse_flag;
872 1.1 christos
873 1.1 christos case oExitOnForwardFailure:
874 1.1 christos intptr = &options->exit_on_forward_failure;
875 1.1 christos goto parse_flag;
876 1.1 christos
877 1.1 christos case oUsePrivilegedPort:
878 1.1 christos intptr = &options->use_privileged_port;
879 1.1 christos goto parse_flag;
880 1.1 christos
881 1.1 christos case oPasswordAuthentication:
882 1.1 christos intptr = &options->password_authentication;
883 1.1 christos goto parse_flag;
884 1.1 christos
885 1.1 christos case oKbdInteractiveAuthentication:
886 1.1 christos intptr = &options->kbd_interactive_authentication;
887 1.1 christos goto parse_flag;
888 1.1 christos
889 1.1 christos case oKbdInteractiveDevices:
890 1.1 christos charptr = &options->kbd_interactive_devices;
891 1.1 christos goto parse_string;
892 1.1 christos
893 1.1 christos case oPubkeyAuthentication:
894 1.1 christos intptr = &options->pubkey_authentication;
895 1.1 christos goto parse_flag;
896 1.1 christos
897 1.1 christos case oRSAAuthentication:
898 1.1 christos intptr = &options->rsa_authentication;
899 1.1 christos goto parse_flag;
900 1.1 christos
901 1.1 christos case oRhostsRSAAuthentication:
902 1.1 christos intptr = &options->rhosts_rsa_authentication;
903 1.1 christos goto parse_flag;
904 1.1 christos
905 1.1 christos case oHostbasedAuthentication:
906 1.1 christos intptr = &options->hostbased_authentication;
907 1.1 christos goto parse_flag;
908 1.1 christos
909 1.1 christos case oChallengeResponseAuthentication:
910 1.1 christos intptr = &options->challenge_response_authentication;
911 1.1 christos goto parse_flag;
912 1.1 christos
913 1.1 christos case oGssAuthentication:
914 1.1 christos intptr = &options->gss_authentication;
915 1.1 christos goto parse_flag;
916 1.1 christos
917 1.1 christos case oGssDelegateCreds:
918 1.1 christos intptr = &options->gss_deleg_creds;
919 1.1 christos goto parse_flag;
920 1.1 christos
921 1.1 christos case oBatchMode:
922 1.1 christos intptr = &options->batch_mode;
923 1.1 christos goto parse_flag;
924 1.1 christos
925 1.1 christos case oCheckHostIP:
926 1.1 christos intptr = &options->check_host_ip;
927 1.1 christos goto parse_flag;
928 1.1 christos
929 1.1 christos case oVerifyHostKeyDNS:
930 1.1 christos intptr = &options->verify_host_key_dns;
931 1.1.1.8 christos multistate_ptr = multistate_yesnoask;
932 1.1.1.8 christos goto parse_multistate;
933 1.1 christos
934 1.1 christos case oStrictHostKeyChecking:
935 1.1 christos intptr = &options->strict_host_key_checking;
936 1.1.1.8 christos multistate_ptr = multistate_yesnoask;
937 1.1.1.8 christos goto parse_multistate;
938 1.1 christos
939 1.1 christos case oCompression:
940 1.1 christos intptr = &options->compression;
941 1.1 christos goto parse_flag;
942 1.1 christos
943 1.1 christos case oTCPKeepAlive:
944 1.1 christos intptr = &options->tcp_keep_alive;
945 1.1 christos goto parse_flag;
946 1.1 christos
947 1.1 christos case oNoHostAuthenticationForLocalhost:
948 1.1 christos intptr = &options->no_host_authentication_for_localhost;
949 1.1 christos goto parse_flag;
950 1.1 christos
951 1.1 christos case oNumberOfPasswordPrompts:
952 1.1 christos intptr = &options->number_of_password_prompts;
953 1.1 christos goto parse_int;
954 1.1 christos
955 1.1 christos case oCompressionLevel:
956 1.1 christos intptr = &options->compression_level;
957 1.1 christos goto parse_int;
958 1.1 christos
959 1.1 christos case oRekeyLimit:
960 1.1 christos arg = strdelim(&s);
961 1.1 christos if (!arg || *arg == '\0')
962 1.1.1.7 christos fatal("%.200s line %d: Missing argument.", filename,
963 1.1.1.7 christos linenum);
964 1.1.1.7 christos if (strcmp(arg, "default") == 0) {
965 1.1.1.7 christos val64 = 0;
966 1.1.1.7 christos } else {
967 1.1.1.7 christos if (scan_scaled(arg, &val64) == -1)
968 1.1.1.7 christos fatal("%.200s line %d: Bad number '%s': %s",
969 1.1.1.7 christos filename, linenum, arg, strerror(errno));
970 1.1.1.7 christos if (val64 != 0 && val64 < 16)
971 1.1.1.7 christos fatal("%.200s line %d: RekeyLimit too small",
972 1.1.1.7 christos filename, linenum);
973 1.1 christos }
974 1.1 christos if (*activep && options->rekey_limit == -1)
975 1.1.1.12 christos options->rekey_limit = val64;
976 1.1.1.7 christos if (s != NULL) { /* optional rekey interval present */
977 1.1.1.7 christos if (strcmp(s, "none") == 0) {
978 1.1.1.7 christos (void)strdelim(&s); /* discard */
979 1.1.1.7 christos break;
980 1.1.1.7 christos }
981 1.1.1.7 christos intptr = &options->rekey_interval;
982 1.1.1.7 christos goto parse_time;
983 1.1.1.7 christos }
984 1.1 christos break;
985 1.1 christos
986 1.1 christos case oIdentityFile:
987 1.1 christos arg = strdelim(&s);
988 1.1 christos if (!arg || *arg == '\0')
989 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
990 1.1 christos if (*activep) {
991 1.1 christos intptr = &options->num_identity_files;
992 1.1 christos if (*intptr >= SSH_MAX_IDENTITY_FILES)
993 1.1 christos fatal("%.200s line %d: Too many identity files specified (max %d).",
994 1.1 christos filename, linenum, SSH_MAX_IDENTITY_FILES);
995 1.1.1.9 christos add_identity_file(options, NULL,
996 1.1.1.9 christos arg, flags & SSHCONF_USERCONF);
997 1.1 christos }
998 1.1 christos break;
999 1.1 christos
1000 1.1.1.12 christos case oCertificateFile:
1001 1.1.1.12 christos arg = strdelim(&s);
1002 1.1.1.12 christos if (!arg || *arg == '\0')
1003 1.1.1.12 christos fatal("%.200s line %d: Missing argument.",
1004 1.1.1.12 christos filename, linenum);
1005 1.1.1.12 christos if (*activep) {
1006 1.1.1.12 christos intptr = &options->num_certificate_files;
1007 1.1.1.12 christos if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1008 1.1.1.12 christos fatal("%.200s line %d: Too many certificate "
1009 1.1.1.12 christos "files specified (max %d).",
1010 1.1.1.12 christos filename, linenum,
1011 1.1.1.12 christos SSH_MAX_CERTIFICATE_FILES);
1012 1.1.1.12 christos }
1013 1.1.1.12 christos add_certificate_file(options, arg,
1014 1.1.1.12 christos flags & SSHCONF_USERCONF);
1015 1.1.1.12 christos }
1016 1.1.1.12 christos break;
1017 1.1.1.12 christos
1018 1.1 christos case oXAuthLocation:
1019 1.1 christos charptr=&options->xauth_location;
1020 1.1 christos goto parse_string;
1021 1.1 christos
1022 1.1 christos case oUser:
1023 1.1 christos charptr = &options->user;
1024 1.1 christos parse_string:
1025 1.1 christos arg = strdelim(&s);
1026 1.1 christos if (!arg || *arg == '\0')
1027 1.1.1.5 christos fatal("%.200s line %d: Missing argument.",
1028 1.1.1.5 christos filename, linenum);
1029 1.1 christos if (*activep && *charptr == NULL)
1030 1.1 christos *charptr = xstrdup(arg);
1031 1.1 christos break;
1032 1.1 christos
1033 1.1 christos case oGlobalKnownHostsFile:
1034 1.1.1.5 christos cpptr = (char **)&options->system_hostfiles;
1035 1.1.1.5 christos uintptr = &options->num_system_hostfiles;
1036 1.1.1.5 christos max_entries = SSH_MAX_HOSTS_FILES;
1037 1.1.1.5 christos parse_char_array:
1038 1.1.1.5 christos if (*activep && *uintptr == 0) {
1039 1.1.1.5 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1040 1.1.1.5 christos if ((*uintptr) >= max_entries)
1041 1.1.1.5 christos fatal("%s line %d: "
1042 1.1.1.5 christos "too many authorized keys files.",
1043 1.1.1.5 christos filename, linenum);
1044 1.1.1.5 christos cpptr[(*uintptr)++] = xstrdup(arg);
1045 1.1.1.5 christos }
1046 1.1.1.5 christos }
1047 1.1.1.5 christos return 0;
1048 1.1 christos
1049 1.1 christos case oUserKnownHostsFile:
1050 1.1.1.5 christos cpptr = (char **)&options->user_hostfiles;
1051 1.1.1.5 christos uintptr = &options->num_user_hostfiles;
1052 1.1.1.5 christos max_entries = SSH_MAX_HOSTS_FILES;
1053 1.1.1.5 christos goto parse_char_array;
1054 1.1 christos
1055 1.1 christos case oHostName:
1056 1.1 christos charptr = &options->hostname;
1057 1.1 christos goto parse_string;
1058 1.1 christos
1059 1.1 christos case oHostKeyAlias:
1060 1.1 christos charptr = &options->host_key_alias;
1061 1.1 christos goto parse_string;
1062 1.1 christos
1063 1.1 christos case oPreferredAuthentications:
1064 1.1 christos charptr = &options->preferred_authentications;
1065 1.1 christos goto parse_string;
1066 1.1 christos
1067 1.1 christos case oBindAddress:
1068 1.1 christos charptr = &options->bind_address;
1069 1.1 christos goto parse_string;
1070 1.1 christos
1071 1.1.1.3 adam case oPKCS11Provider:
1072 1.1.1.3 adam charptr = &options->pkcs11_provider;
1073 1.1 christos goto parse_string;
1074 1.1 christos
1075 1.1 christos case oProxyCommand:
1076 1.1 christos charptr = &options->proxy_command;
1077 1.1 christos parse_command:
1078 1.1 christos if (s == NULL)
1079 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1080 1.1 christos len = strspn(s, WHITESPACE "=");
1081 1.1 christos if (*activep && *charptr == NULL)
1082 1.1 christos *charptr = xstrdup(s + len);
1083 1.1 christos return 0;
1084 1.1 christos
1085 1.1 christos case oPort:
1086 1.1 christos intptr = &options->port;
1087 1.1 christos parse_int:
1088 1.1 christos arg = strdelim(&s);
1089 1.1 christos if (!arg || *arg == '\0')
1090 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1091 1.1 christos if (arg[0] < '0' || arg[0] > '9')
1092 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
1093 1.1 christos
1094 1.1 christos /* Octal, decimal, or hex format? */
1095 1.1 christos value = strtol(arg, &endofnumber, 0);
1096 1.1 christos if (arg == endofnumber)
1097 1.1 christos fatal("%.200s line %d: Bad number.", filename, linenum);
1098 1.1 christos if (*activep && *intptr == -1)
1099 1.1 christos *intptr = value;
1100 1.1 christos break;
1101 1.1 christos
1102 1.1 christos case oConnectionAttempts:
1103 1.1 christos intptr = &options->connection_attempts;
1104 1.1 christos goto parse_int;
1105 1.1 christos
1106 1.1 christos case oCipher:
1107 1.1 christos intptr = &options->cipher;
1108 1.1 christos arg = strdelim(&s);
1109 1.1 christos if (!arg || *arg == '\0')
1110 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1111 1.1 christos value = cipher_number(arg);
1112 1.1 christos if (value == -1)
1113 1.1 christos fatal("%.200s line %d: Bad cipher '%s'.",
1114 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1115 1.1 christos if (*activep && *intptr == -1)
1116 1.1 christos *intptr = value;
1117 1.1 christos break;
1118 1.1 christos
1119 1.1 christos case oCiphers:
1120 1.1 christos arg = strdelim(&s);
1121 1.1 christos if (!arg || *arg == '\0')
1122 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1123 1.1.1.11 christos if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1124 1.1 christos fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1125 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1126 1.1 christos if (*activep && options->ciphers == NULL)
1127 1.1 christos options->ciphers = xstrdup(arg);
1128 1.1 christos break;
1129 1.1 christos
1130 1.1 christos case oMacs:
1131 1.1 christos arg = strdelim(&s);
1132 1.1 christos if (!arg || *arg == '\0')
1133 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1134 1.1.1.11 christos if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1135 1.1 christos fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1136 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1137 1.1 christos if (*activep && options->macs == NULL)
1138 1.1 christos options->macs = xstrdup(arg);
1139 1.1 christos break;
1140 1.1 christos
1141 1.1.1.4 christos case oKexAlgorithms:
1142 1.1.1.4 christos arg = strdelim(&s);
1143 1.1.1.4 christos if (!arg || *arg == '\0')
1144 1.1.1.4 christos fatal("%.200s line %d: Missing argument.",
1145 1.1.1.4 christos filename, linenum);
1146 1.1.1.11 christos if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1147 1.1.1.4 christos fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1148 1.1.1.4 christos filename, linenum, arg ? arg : "<NONE>");
1149 1.1.1.4 christos if (*activep && options->kex_algorithms == NULL)
1150 1.1.1.4 christos options->kex_algorithms = xstrdup(arg);
1151 1.1.1.4 christos break;
1152 1.1.1.4 christos
1153 1.1 christos case oHostKeyAlgorithms:
1154 1.1.1.11 christos charptr = &options->hostkeyalgorithms;
1155 1.1.1.11 christos parse_keytypes:
1156 1.1 christos arg = strdelim(&s);
1157 1.1 christos if (!arg || *arg == '\0')
1158 1.1.1.11 christos fatal("%.200s line %d: Missing argument.",
1159 1.1.1.11 christos filename, linenum);
1160 1.1.1.11 christos if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1161 1.1.1.11 christos fatal("%s line %d: Bad key types '%s'.",
1162 1.1.1.11 christos filename, linenum, arg ? arg : "<NONE>");
1163 1.1.1.11 christos if (*activep && *charptr == NULL)
1164 1.1.1.11 christos *charptr = xstrdup(arg);
1165 1.1 christos break;
1166 1.1 christos
1167 1.1 christos case oProtocol:
1168 1.1 christos intptr = &options->protocol;
1169 1.1 christos arg = strdelim(&s);
1170 1.1 christos if (!arg || *arg == '\0')
1171 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1172 1.1 christos value = proto_spec(arg);
1173 1.1 christos if (value == SSH_PROTO_UNKNOWN)
1174 1.1 christos fatal("%.200s line %d: Bad protocol spec '%s'.",
1175 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1176 1.1 christos if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1177 1.1 christos *intptr = value;
1178 1.1 christos break;
1179 1.1 christos
1180 1.1 christos case oLogLevel:
1181 1.1 christos log_level_ptr = &options->log_level;
1182 1.1 christos arg = strdelim(&s);
1183 1.1 christos value = log_level_number(arg);
1184 1.1 christos if (value == SYSLOG_LEVEL_NOT_SET)
1185 1.1 christos fatal("%.200s line %d: unsupported log level '%s'",
1186 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1187 1.1 christos if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1188 1.1 christos *log_level_ptr = (LogLevel) value;
1189 1.1 christos break;
1190 1.1 christos
1191 1.1 christos case oLocalForward:
1192 1.1 christos case oRemoteForward:
1193 1.1 christos case oDynamicForward:
1194 1.1 christos arg = strdelim(&s);
1195 1.1 christos if (arg == NULL || *arg == '\0')
1196 1.1 christos fatal("%.200s line %d: Missing port argument.",
1197 1.1 christos filename, linenum);
1198 1.1 christos
1199 1.1 christos if (opcode == oLocalForward ||
1200 1.1 christos opcode == oRemoteForward) {
1201 1.1 christos arg2 = strdelim(&s);
1202 1.1 christos if (arg2 == NULL || *arg2 == '\0')
1203 1.1 christos fatal("%.200s line %d: Missing target argument.",
1204 1.1 christos filename, linenum);
1205 1.1 christos
1206 1.1 christos /* construct a string for parse_forward */
1207 1.1 christos snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1208 1.1 christos } else if (opcode == oDynamicForward) {
1209 1.1 christos strlcpy(fwdarg, arg, sizeof(fwdarg));
1210 1.1 christos }
1211 1.1 christos
1212 1.1 christos if (parse_forward(&fwd, fwdarg,
1213 1.1 christos opcode == oDynamicForward ? 1 : 0,
1214 1.1 christos opcode == oRemoteForward ? 1 : 0) == 0)
1215 1.1 christos fatal("%.200s line %d: Bad forwarding specification.",
1216 1.1 christos filename, linenum);
1217 1.1 christos
1218 1.1 christos if (*activep) {
1219 1.1 christos if (opcode == oLocalForward ||
1220 1.1 christos opcode == oDynamicForward)
1221 1.1 christos add_local_forward(options, &fwd);
1222 1.1 christos else if (opcode == oRemoteForward)
1223 1.1 christos add_remote_forward(options, &fwd);
1224 1.1 christos }
1225 1.1 christos break;
1226 1.1 christos
1227 1.1 christos case oClearAllForwardings:
1228 1.1 christos intptr = &options->clear_forwardings;
1229 1.1 christos goto parse_flag;
1230 1.1 christos
1231 1.1 christos case oHost:
1232 1.1.1.8 christos if (cmdline)
1233 1.1.1.8 christos fatal("Host directive not supported as a command-line "
1234 1.1.1.8 christos "option");
1235 1.1 christos *activep = 0;
1236 1.1.1.5 christos arg2 = NULL;
1237 1.1.1.5 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1238 1.1.1.5 christos negated = *arg == '!';
1239 1.1.1.5 christos if (negated)
1240 1.1.1.5 christos arg++;
1241 1.1 christos if (match_pattern(host, arg)) {
1242 1.1.1.5 christos if (negated) {
1243 1.1.1.5 christos debug("%.200s line %d: Skipping Host "
1244 1.1.1.5 christos "block because of negated match "
1245 1.1.1.5 christos "for %.100s", filename, linenum,
1246 1.1.1.5 christos arg);
1247 1.1.1.5 christos *activep = 0;
1248 1.1.1.5 christos break;
1249 1.1.1.5 christos }
1250 1.1.1.5 christos if (!*activep)
1251 1.1.1.5 christos arg2 = arg; /* logged below */
1252 1.1 christos *activep = 1;
1253 1.1 christos }
1254 1.1.1.5 christos }
1255 1.1.1.5 christos if (*activep)
1256 1.1.1.5 christos debug("%.200s line %d: Applying options for %.100s",
1257 1.1.1.5 christos filename, linenum, arg2);
1258 1.1 christos /* Avoid garbage check below, as strdelim is done. */
1259 1.1 christos return 0;
1260 1.1 christos
1261 1.1.1.8 christos case oMatch:
1262 1.1.1.8 christos if (cmdline)
1263 1.1.1.8 christos fatal("Host directive not supported as a command-line "
1264 1.1.1.8 christos "option");
1265 1.1.1.9 christos value = match_cfg_line(options, &s, pw, host, original_host,
1266 1.1.1.9 christos flags & SSHCONF_POSTCANON, filename, linenum);
1267 1.1.1.8 christos if (value < 0)
1268 1.1.1.8 christos fatal("%.200s line %d: Bad Match condition", filename,
1269 1.1.1.8 christos linenum);
1270 1.1.1.8 christos *activep = value;
1271 1.1.1.8 christos break;
1272 1.1.1.8 christos
1273 1.1 christos case oEscapeChar:
1274 1.1 christos intptr = &options->escape_char;
1275 1.1 christos arg = strdelim(&s);
1276 1.1 christos if (!arg || *arg == '\0')
1277 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1278 1.1.1.10 christos if (strcmp(arg, "none") == 0)
1279 1.1.1.10 christos value = SSH_ESCAPECHAR_NONE;
1280 1.1.1.10 christos else if (arg[1] == '\0')
1281 1.1.1.10 christos value = (u_char) arg[0];
1282 1.1.1.10 christos else if (arg[0] == '^' && arg[2] == 0 &&
1283 1.1 christos (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1284 1.1 christos value = (u_char) arg[1] & 31;
1285 1.1 christos else {
1286 1.1 christos fatal("%.200s line %d: Bad escape character.",
1287 1.1 christos filename, linenum);
1288 1.1 christos /* NOTREACHED */
1289 1.1 christos value = 0; /* Avoid compiler warning. */
1290 1.1 christos }
1291 1.1 christos if (*activep && *intptr == -1)
1292 1.1 christos *intptr = value;
1293 1.1 christos break;
1294 1.1 christos
1295 1.1 christos case oAddressFamily:
1296 1.1 christos intptr = &options->address_family;
1297 1.1.1.8 christos multistate_ptr = multistate_addressfamily;
1298 1.1.1.8 christos goto parse_multistate;
1299 1.1 christos
1300 1.1 christos case oEnableSSHKeysign:
1301 1.1 christos intptr = &options->enable_ssh_keysign;
1302 1.1 christos goto parse_flag;
1303 1.1 christos
1304 1.1 christos case oIdentitiesOnly:
1305 1.1 christos intptr = &options->identities_only;
1306 1.1 christos goto parse_flag;
1307 1.1 christos
1308 1.1 christos case oServerAliveInterval:
1309 1.1 christos intptr = &options->server_alive_interval;
1310 1.1 christos goto parse_time;
1311 1.1 christos
1312 1.1 christos case oServerAliveCountMax:
1313 1.1 christos intptr = &options->server_alive_count_max;
1314 1.1 christos goto parse_int;
1315 1.1 christos
1316 1.1 christos case oSendEnv:
1317 1.1 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1318 1.1 christos if (strchr(arg, '=') != NULL)
1319 1.1 christos fatal("%s line %d: Invalid environment name.",
1320 1.1 christos filename, linenum);
1321 1.1 christos if (!*activep)
1322 1.1 christos continue;
1323 1.1 christos if (options->num_send_env >= MAX_SEND_ENV)
1324 1.1 christos fatal("%s line %d: too many send env.",
1325 1.1 christos filename, linenum);
1326 1.1 christos options->send_env[options->num_send_env++] =
1327 1.1 christos xstrdup(arg);
1328 1.1 christos }
1329 1.1 christos break;
1330 1.1 christos
1331 1.1 christos case oControlPath:
1332 1.1 christos charptr = &options->control_path;
1333 1.1 christos goto parse_string;
1334 1.1 christos
1335 1.1 christos case oControlMaster:
1336 1.1 christos intptr = &options->control_master;
1337 1.1.1.8 christos multistate_ptr = multistate_controlmaster;
1338 1.1.1.8 christos goto parse_multistate;
1339 1.1 christos
1340 1.1.1.3 adam case oControlPersist:
1341 1.1.1.3 adam /* no/false/yes/true, or a time spec */
1342 1.1.1.3 adam intptr = &options->control_persist;
1343 1.1.1.3 adam arg = strdelim(&s);
1344 1.1.1.3 adam if (!arg || *arg == '\0')
1345 1.1.1.3 adam fatal("%.200s line %d: Missing ControlPersist"
1346 1.1.1.3 adam " argument.", filename, linenum);
1347 1.1.1.3 adam value = 0;
1348 1.1.1.3 adam value2 = 0; /* timeout */
1349 1.1.1.3 adam if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1350 1.1.1.3 adam value = 0;
1351 1.1.1.3 adam else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1352 1.1.1.3 adam value = 1;
1353 1.1.1.3 adam else if ((value2 = convtime(arg)) >= 0)
1354 1.1.1.3 adam value = 1;
1355 1.1.1.3 adam else
1356 1.1.1.3 adam fatal("%.200s line %d: Bad ControlPersist argument.",
1357 1.1.1.3 adam filename, linenum);
1358 1.1.1.3 adam if (*activep && *intptr == -1) {
1359 1.1.1.3 adam *intptr = value;
1360 1.1.1.3 adam options->control_persist_timeout = value2;
1361 1.1.1.3 adam }
1362 1.1.1.3 adam break;
1363 1.1.1.3 adam
1364 1.1 christos case oHashKnownHosts:
1365 1.1 christos intptr = &options->hash_known_hosts;
1366 1.1 christos goto parse_flag;
1367 1.1 christos
1368 1.1 christos case oTunnel:
1369 1.1 christos intptr = &options->tun_open;
1370 1.1.1.8 christos multistate_ptr = multistate_tunnel;
1371 1.1.1.8 christos goto parse_multistate;
1372 1.1 christos
1373 1.1 christos case oTunnelDevice:
1374 1.1 christos arg = strdelim(&s);
1375 1.1 christos if (!arg || *arg == '\0')
1376 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1377 1.1 christos value = a2tun(arg, &value2);
1378 1.1 christos if (value == SSH_TUNID_ERR)
1379 1.1 christos fatal("%.200s line %d: Bad tun device.", filename, linenum);
1380 1.1 christos if (*activep) {
1381 1.1 christos options->tun_local = value;
1382 1.1 christos options->tun_remote = value2;
1383 1.1 christos }
1384 1.1 christos break;
1385 1.1 christos
1386 1.1 christos case oLocalCommand:
1387 1.1 christos charptr = &options->local_command;
1388 1.1 christos goto parse_command;
1389 1.1 christos
1390 1.1 christos case oPermitLocalCommand:
1391 1.1 christos intptr = &options->permit_local_command;
1392 1.1 christos goto parse_flag;
1393 1.1 christos
1394 1.1 christos case oVisualHostKey:
1395 1.1 christos intptr = &options->visual_host_key;
1396 1.1 christos goto parse_flag;
1397 1.1 christos
1398 1.1.1.4 christos case oIPQoS:
1399 1.1.1.4 christos arg = strdelim(&s);
1400 1.1.1.4 christos if ((value = parse_ipqos(arg)) == -1)
1401 1.1.1.4 christos fatal("%s line %d: Bad IPQoS value: %s",
1402 1.1.1.4 christos filename, linenum, arg);
1403 1.1.1.4 christos arg = strdelim(&s);
1404 1.1.1.4 christos if (arg == NULL)
1405 1.1.1.4 christos value2 = value;
1406 1.1.1.4 christos else if ((value2 = parse_ipqos(arg)) == -1)
1407 1.1.1.4 christos fatal("%s line %d: Bad IPQoS value: %s",
1408 1.1.1.4 christos filename, linenum, arg);
1409 1.1.1.4 christos if (*activep) {
1410 1.1.1.4 christos options->ip_qos_interactive = value;
1411 1.1.1.4 christos options->ip_qos_bulk = value2;
1412 1.1.1.4 christos }
1413 1.1.1.4 christos break;
1414 1.1.1.4 christos
1415 1.1.1.5 christos case oRequestTTY:
1416 1.1.1.5 christos intptr = &options->request_tty;
1417 1.1.1.8 christos multistate_ptr = multistate_requesttty;
1418 1.1.1.8 christos goto parse_multistate;
1419 1.1.1.5 christos
1420 1.1.1.7 christos case oIgnoreUnknown:
1421 1.1.1.7 christos charptr = &options->ignored_unknown;
1422 1.1.1.7 christos goto parse_string;
1423 1.1.1.7 christos
1424 1.1.1.8 christos case oProxyUseFdpass:
1425 1.1.1.8 christos intptr = &options->proxy_use_fdpass;
1426 1.1.1.8 christos goto parse_flag;
1427 1.1.1.8 christos
1428 1.1.1.8 christos case oCanonicalDomains:
1429 1.1.1.8 christos value = options->num_canonical_domains != 0;
1430 1.1.1.8 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1431 1.1.1.8 christos valid_domain(arg, filename, linenum);
1432 1.1.1.8 christos if (!*activep || value)
1433 1.1.1.8 christos continue;
1434 1.1.1.8 christos if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1435 1.1.1.8 christos fatal("%s line %d: too many hostname suffixes.",
1436 1.1.1.8 christos filename, linenum);
1437 1.1.1.8 christos options->canonical_domains[
1438 1.1.1.8 christos options->num_canonical_domains++] = xstrdup(arg);
1439 1.1.1.8 christos }
1440 1.1.1.8 christos break;
1441 1.1.1.8 christos
1442 1.1.1.8 christos case oCanonicalizePermittedCNAMEs:
1443 1.1.1.8 christos value = options->num_permitted_cnames != 0;
1444 1.1.1.8 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1445 1.1.1.8 christos /* Either '*' for everything or 'list:list' */
1446 1.1.1.8 christos if (strcmp(arg, "*") == 0)
1447 1.1.1.8 christos arg2 = arg;
1448 1.1.1.8 christos else {
1449 1.1.1.8 christos lowercase(arg);
1450 1.1.1.8 christos if ((arg2 = strchr(arg, ':')) == NULL ||
1451 1.1.1.8 christos arg2[1] == '\0') {
1452 1.1.1.8 christos fatal("%s line %d: "
1453 1.1.1.8 christos "Invalid permitted CNAME \"%s\"",
1454 1.1.1.8 christos filename, linenum, arg);
1455 1.1.1.8 christos }
1456 1.1.1.8 christos *arg2 = '\0';
1457 1.1.1.8 christos arg2++;
1458 1.1.1.8 christos }
1459 1.1.1.8 christos if (!*activep || value)
1460 1.1.1.8 christos continue;
1461 1.1.1.8 christos if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1462 1.1.1.8 christos fatal("%s line %d: too many permitted CNAMEs.",
1463 1.1.1.8 christos filename, linenum);
1464 1.1.1.8 christos cname = options->permitted_cnames +
1465 1.1.1.8 christos options->num_permitted_cnames++;
1466 1.1.1.8 christos cname->source_list = xstrdup(arg);
1467 1.1.1.8 christos cname->target_list = xstrdup(arg2);
1468 1.1.1.8 christos }
1469 1.1.1.8 christos break;
1470 1.1.1.8 christos
1471 1.1.1.8 christos case oCanonicalizeHostname:
1472 1.1.1.8 christos intptr = &options->canonicalize_hostname;
1473 1.1.1.8 christos multistate_ptr = multistate_canonicalizehostname;
1474 1.1.1.8 christos goto parse_multistate;
1475 1.1.1.8 christos
1476 1.1.1.8 christos case oCanonicalizeMaxDots:
1477 1.1.1.8 christos intptr = &options->canonicalize_max_dots;
1478 1.1.1.8 christos goto parse_int;
1479 1.1.1.8 christos
1480 1.1.1.8 christos case oCanonicalizeFallbackLocal:
1481 1.1.1.8 christos intptr = &options->canonicalize_fallback_local;
1482 1.1.1.8 christos goto parse_flag;
1483 1.1.1.8 christos
1484 1.1.1.8 christos case oStreamLocalBindMask:
1485 1.1.1.8 christos arg = strdelim(&s);
1486 1.1.1.8 christos if (!arg || *arg == '\0')
1487 1.1.1.8 christos fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1488 1.1.1.8 christos /* Parse mode in octal format */
1489 1.1.1.8 christos value = strtol(arg, &endofnumber, 8);
1490 1.1.1.8 christos if (arg == endofnumber || value < 0 || value > 0777)
1491 1.1.1.8 christos fatal("%.200s line %d: Bad mask.", filename, linenum);
1492 1.1.1.8 christos options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1493 1.1.1.8 christos break;
1494 1.1.1.8 christos
1495 1.1.1.8 christos case oStreamLocalBindUnlink:
1496 1.1.1.8 christos intptr = &options->fwd_opts.streamlocal_bind_unlink;
1497 1.1.1.8 christos goto parse_flag;
1498 1.1.1.8 christos
1499 1.1.1.9 christos case oRevokedHostKeys:
1500 1.1.1.9 christos charptr = &options->revoked_host_keys;
1501 1.1.1.9 christos goto parse_string;
1502 1.1.1.9 christos
1503 1.1.1.9 christos case oFingerprintHash:
1504 1.1.1.9 christos intptr = &options->fingerprint_hash;
1505 1.1.1.9 christos arg = strdelim(&s);
1506 1.1.1.9 christos if (!arg || *arg == '\0')
1507 1.1.1.9 christos fatal("%.200s line %d: Missing argument.",
1508 1.1.1.9 christos filename, linenum);
1509 1.1.1.9 christos if ((value = ssh_digest_alg_by_name(arg)) == -1)
1510 1.1.1.9 christos fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1511 1.1.1.9 christos filename, linenum, arg);
1512 1.1.1.9 christos if (*activep && *intptr == -1)
1513 1.1.1.9 christos *intptr = value;
1514 1.1.1.9 christos break;
1515 1.1.1.9 christos
1516 1.1.1.9 christos case oUpdateHostkeys:
1517 1.1.1.9 christos intptr = &options->update_hostkeys;
1518 1.1.1.9 christos multistate_ptr = multistate_yesnoask;
1519 1.1.1.9 christos goto parse_multistate;
1520 1.1.1.9 christos
1521 1.1.1.9 christos case oHostbasedKeyTypes:
1522 1.1.1.9 christos charptr = &options->hostbased_key_types;
1523 1.1.1.11 christos goto parse_keytypes;
1524 1.1.1.11 christos
1525 1.1.1.11 christos case oPubkeyAcceptedKeyTypes:
1526 1.1.1.11 christos charptr = &options->pubkey_key_types;
1527 1.1.1.11 christos goto parse_keytypes;
1528 1.1.1.9 christos
1529 1.1.1.12 christos case oAddKeysToAgent:
1530 1.1.1.12 christos intptr = &options->add_keys_to_agent;
1531 1.1.1.12 christos multistate_ptr = multistate_yesnoaskconfirm;
1532 1.1.1.12 christos goto parse_multistate;
1533 1.1.1.12 christos
1534 1.1 christos case oDeprecated:
1535 1.1 christos debug("%s line %d: Deprecated option \"%s\"",
1536 1.1 christos filename, linenum, keyword);
1537 1.1 christos return 0;
1538 1.1 christos
1539 1.1 christos case oUnsupported:
1540 1.1 christos error("%s line %d: Unsupported option \"%s\"",
1541 1.1 christos filename, linenum, keyword);
1542 1.1 christos return 0;
1543 1.1 christos
1544 1.1 christos default:
1545 1.1.1.9 christos fatal("%s: Unimplemented opcode %d", __func__, opcode);
1546 1.1 christos }
1547 1.1 christos
1548 1.1 christos /* Check that there is no garbage at end of line. */
1549 1.1 christos if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1550 1.1 christos fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1551 1.1 christos filename, linenum, arg);
1552 1.1 christos }
1553 1.1 christos return 0;
1554 1.1 christos }
1555 1.1 christos
1556 1.1 christos
1557 1.1 christos /*
1558 1.1 christos * Reads the config file and modifies the options accordingly. Options
1559 1.1 christos * should already be initialized before this call. This never returns if
1560 1.1 christos * there is an error. If the file does not exist, this returns 0.
1561 1.1 christos */
1562 1.1 christos
1563 1.1 christos int
1564 1.1.1.8 christos read_config_file(const char *filename, struct passwd *pw, const char *host,
1565 1.1.1.9 christos const char *original_host, Options *options, int flags)
1566 1.1 christos {
1567 1.1 christos FILE *f;
1568 1.1 christos char line[1024];
1569 1.1 christos int active, linenum;
1570 1.1 christos int bad_options = 0;
1571 1.1 christos
1572 1.1 christos if ((f = fopen(filename, "r")) == NULL)
1573 1.1 christos return 0;
1574 1.1 christos
1575 1.1.1.7 christos if (flags & SSHCONF_CHECKPERM) {
1576 1.1 christos struct stat sb;
1577 1.1 christos
1578 1.1 christos if (fstat(fileno(f), &sb) == -1)
1579 1.1 christos fatal("fstat %s: %s", filename, strerror(errno));
1580 1.1 christos if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1581 1.1 christos (sb.st_mode & 022) != 0))
1582 1.1 christos fatal("Bad owner or permissions on %s", filename);
1583 1.1 christos }
1584 1.1 christos
1585 1.1 christos debug("Reading configuration data %.200s", filename);
1586 1.1 christos
1587 1.1 christos /*
1588 1.1 christos * Mark that we are now processing the options. This flag is turned
1589 1.1 christos * on/off by Host specifications.
1590 1.1 christos */
1591 1.1 christos active = 1;
1592 1.1 christos linenum = 0;
1593 1.1 christos while (fgets(line, sizeof(line), f)) {
1594 1.1 christos /* Update line number counter. */
1595 1.1 christos linenum++;
1596 1.1.1.9 christos if (process_config_line(options, pw, host, original_host,
1597 1.1.1.9 christos line, filename, linenum, &active, flags) != 0)
1598 1.1 christos bad_options++;
1599 1.1 christos }
1600 1.1 christos fclose(f);
1601 1.1 christos if (bad_options > 0)
1602 1.1 christos fatal("%s: terminating, %d bad configuration options",
1603 1.1 christos filename, bad_options);
1604 1.1 christos return 1;
1605 1.1 christos }
1606 1.1 christos
1607 1.1.1.8 christos /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1608 1.1.1.8 christos int
1609 1.1.1.8 christos option_clear_or_none(const char *o)
1610 1.1.1.8 christos {
1611 1.1.1.8 christos return o == NULL || strcasecmp(o, "none") == 0;
1612 1.1.1.8 christos }
1613 1.1.1.8 christos
1614 1.1 christos /*
1615 1.1 christos * Initializes options to special values that indicate that they have not yet
1616 1.1 christos * been set. Read_config_file will only set options with this value. Options
1617 1.1 christos * are processed in the following order: command line, user config file,
1618 1.1 christos * system config file. Last, fill_default_options is called.
1619 1.1 christos */
1620 1.1 christos
1621 1.1 christos void
1622 1.1 christos initialize_options(Options * options)
1623 1.1 christos {
1624 1.1 christos memset(options, 'X', sizeof(*options));
1625 1.1 christos options->forward_agent = -1;
1626 1.1 christos options->forward_x11 = -1;
1627 1.1 christos options->forward_x11_trusted = -1;
1628 1.1.1.3 adam options->forward_x11_timeout = -1;
1629 1.1 christos options->exit_on_forward_failure = -1;
1630 1.1 christos options->xauth_location = NULL;
1631 1.1.1.8 christos options->fwd_opts.gateway_ports = -1;
1632 1.1.1.8 christos options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1633 1.1.1.8 christos options->fwd_opts.streamlocal_bind_unlink = -1;
1634 1.1 christos options->use_privileged_port = -1;
1635 1.1 christos options->rsa_authentication = -1;
1636 1.1 christos options->pubkey_authentication = -1;
1637 1.1 christos options->challenge_response_authentication = -1;
1638 1.1 christos options->gss_authentication = -1;
1639 1.1 christos options->gss_deleg_creds = -1;
1640 1.1 christos options->password_authentication = -1;
1641 1.1 christos options->kbd_interactive_authentication = -1;
1642 1.1 christos options->kbd_interactive_devices = NULL;
1643 1.1 christos options->rhosts_rsa_authentication = -1;
1644 1.1 christos options->hostbased_authentication = -1;
1645 1.1 christos options->batch_mode = -1;
1646 1.1 christos options->check_host_ip = -1;
1647 1.1 christos options->strict_host_key_checking = -1;
1648 1.1 christos options->compression = -1;
1649 1.1 christos options->tcp_keep_alive = -1;
1650 1.1 christos options->compression_level = -1;
1651 1.1 christos options->port = -1;
1652 1.1 christos options->address_family = -1;
1653 1.1 christos options->connection_attempts = -1;
1654 1.1 christos options->connection_timeout = -1;
1655 1.1 christos options->number_of_password_prompts = -1;
1656 1.1 christos options->cipher = -1;
1657 1.1 christos options->ciphers = NULL;
1658 1.1 christos options->macs = NULL;
1659 1.1.1.4 christos options->kex_algorithms = NULL;
1660 1.1 christos options->hostkeyalgorithms = NULL;
1661 1.1 christos options->protocol = SSH_PROTO_UNKNOWN;
1662 1.1 christos options->num_identity_files = 0;
1663 1.1.1.12 christos options->num_certificate_files = 0;
1664 1.1 christos options->hostname = NULL;
1665 1.1 christos options->host_key_alias = NULL;
1666 1.1 christos options->proxy_command = NULL;
1667 1.1 christos options->user = NULL;
1668 1.1 christos options->escape_char = -1;
1669 1.1.1.5 christos options->num_system_hostfiles = 0;
1670 1.1.1.5 christos options->num_user_hostfiles = 0;
1671 1.1.1.3 adam options->local_forwards = NULL;
1672 1.1 christos options->num_local_forwards = 0;
1673 1.1.1.3 adam options->remote_forwards = NULL;
1674 1.1 christos options->num_remote_forwards = 0;
1675 1.1 christos options->clear_forwardings = -1;
1676 1.1 christos options->log_level = SYSLOG_LEVEL_NOT_SET;
1677 1.1 christos options->preferred_authentications = NULL;
1678 1.1 christos options->bind_address = NULL;
1679 1.1.1.3 adam options->pkcs11_provider = NULL;
1680 1.1 christos options->enable_ssh_keysign = - 1;
1681 1.1 christos options->no_host_authentication_for_localhost = - 1;
1682 1.1 christos options->identities_only = - 1;
1683 1.1 christos options->rekey_limit = - 1;
1684 1.1.1.7 christos options->rekey_interval = -1;
1685 1.1 christos options->verify_host_key_dns = -1;
1686 1.1 christos options->server_alive_interval = -1;
1687 1.1 christos options->server_alive_count_max = -1;
1688 1.1 christos options->num_send_env = 0;
1689 1.1 christos options->control_path = NULL;
1690 1.1 christos options->control_master = -1;
1691 1.1.1.3 adam options->control_persist = -1;
1692 1.1.1.3 adam options->control_persist_timeout = 0;
1693 1.1 christos options->hash_known_hosts = -1;
1694 1.1 christos options->tun_open = -1;
1695 1.1 christos options->tun_local = -1;
1696 1.1 christos options->tun_remote = -1;
1697 1.1 christos options->local_command = NULL;
1698 1.1 christos options->permit_local_command = -1;
1699 1.1.1.12 christos options->add_keys_to_agent = -1;
1700 1.1 christos options->visual_host_key = -1;
1701 1.1.1.4 christos options->ip_qos_interactive = -1;
1702 1.1.1.4 christos options->ip_qos_bulk = -1;
1703 1.1.1.5 christos options->request_tty = -1;
1704 1.1.1.8 christos options->proxy_use_fdpass = -1;
1705 1.1.1.7 christos options->ignored_unknown = NULL;
1706 1.1.1.8 christos options->num_canonical_domains = 0;
1707 1.1.1.8 christos options->num_permitted_cnames = 0;
1708 1.1.1.8 christos options->canonicalize_max_dots = -1;
1709 1.1.1.8 christos options->canonicalize_fallback_local = -1;
1710 1.1.1.8 christos options->canonicalize_hostname = -1;
1711 1.1.1.9 christos options->revoked_host_keys = NULL;
1712 1.1.1.9 christos options->fingerprint_hash = -1;
1713 1.1.1.9 christos options->update_hostkeys = -1;
1714 1.1.1.9 christos options->hostbased_key_types = NULL;
1715 1.1.1.11 christos options->pubkey_key_types = NULL;
1716 1.1.1.8 christos }
1717 1.1.1.8 christos
1718 1.1.1.8 christos /*
1719 1.1.1.8 christos * A petite version of fill_default_options() that just fills the options
1720 1.1.1.8 christos * needed for hostname canonicalization to proceed.
1721 1.1.1.8 christos */
1722 1.1.1.8 christos void
1723 1.1.1.8 christos fill_default_options_for_canonicalization(Options *options)
1724 1.1.1.8 christos {
1725 1.1.1.8 christos if (options->canonicalize_max_dots == -1)
1726 1.1.1.8 christos options->canonicalize_max_dots = 1;
1727 1.1.1.8 christos if (options->canonicalize_fallback_local == -1)
1728 1.1.1.8 christos options->canonicalize_fallback_local = 1;
1729 1.1.1.8 christos if (options->canonicalize_hostname == -1)
1730 1.1.1.8 christos options->canonicalize_hostname = SSH_CANONICALISE_NO;
1731 1.1 christos }
1732 1.1 christos
1733 1.1 christos /*
1734 1.1 christos * Called after processing other sources of option data, this fills those
1735 1.1 christos * options for which no value has been specified with their default values.
1736 1.1 christos */
1737 1.1 christos void
1738 1.1 christos fill_default_options(Options * options)
1739 1.1 christos {
1740 1.1 christos if (options->forward_agent == -1)
1741 1.1 christos options->forward_agent = 0;
1742 1.1 christos if (options->forward_x11 == -1)
1743 1.1 christos options->forward_x11 = 0;
1744 1.1 christos if (options->forward_x11_trusted == -1)
1745 1.1 christos options->forward_x11_trusted = 0;
1746 1.1.1.3 adam if (options->forward_x11_timeout == -1)
1747 1.1.1.3 adam options->forward_x11_timeout = 1200;
1748 1.1 christos if (options->exit_on_forward_failure == -1)
1749 1.1 christos options->exit_on_forward_failure = 0;
1750 1.1 christos if (options->xauth_location == NULL)
1751 1.1 christos options->xauth_location = _PATH_XAUTH;
1752 1.1.1.8 christos if (options->fwd_opts.gateway_ports == -1)
1753 1.1.1.8 christos options->fwd_opts.gateway_ports = 0;
1754 1.1.1.8 christos if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1755 1.1.1.8 christos options->fwd_opts.streamlocal_bind_mask = 0177;
1756 1.1.1.8 christos if (options->fwd_opts.streamlocal_bind_unlink == -1)
1757 1.1.1.8 christos options->fwd_opts.streamlocal_bind_unlink = 0;
1758 1.1 christos if (options->use_privileged_port == -1)
1759 1.1 christos options->use_privileged_port = 0;
1760 1.1 christos if (options->rsa_authentication == -1)
1761 1.1 christos options->rsa_authentication = 1;
1762 1.1 christos if (options->pubkey_authentication == -1)
1763 1.1 christos options->pubkey_authentication = 1;
1764 1.1 christos if (options->challenge_response_authentication == -1)
1765 1.1 christos options->challenge_response_authentication = 1;
1766 1.1 christos if (options->gss_authentication == -1)
1767 1.1 christos options->gss_authentication = 0;
1768 1.1 christos if (options->gss_deleg_creds == -1)
1769 1.1 christos options->gss_deleg_creds = 0;
1770 1.1 christos if (options->password_authentication == -1)
1771 1.1 christos options->password_authentication = 1;
1772 1.1 christos if (options->kbd_interactive_authentication == -1)
1773 1.1 christos options->kbd_interactive_authentication = 1;
1774 1.1 christos if (options->rhosts_rsa_authentication == -1)
1775 1.1 christos options->rhosts_rsa_authentication = 0;
1776 1.1 christos if (options->hostbased_authentication == -1)
1777 1.1 christos options->hostbased_authentication = 0;
1778 1.1 christos if (options->batch_mode == -1)
1779 1.1 christos options->batch_mode = 0;
1780 1.1 christos if (options->check_host_ip == -1)
1781 1.1 christos options->check_host_ip = 1;
1782 1.1 christos if (options->strict_host_key_checking == -1)
1783 1.1 christos options->strict_host_key_checking = 2; /* 2 is default */
1784 1.1 christos if (options->compression == -1)
1785 1.1 christos options->compression = 0;
1786 1.1 christos if (options->tcp_keep_alive == -1)
1787 1.1 christos options->tcp_keep_alive = 1;
1788 1.1 christos if (options->compression_level == -1)
1789 1.1 christos options->compression_level = 6;
1790 1.1 christos if (options->port == -1)
1791 1.1 christos options->port = 0; /* Filled in ssh_connect. */
1792 1.1 christos if (options->address_family == -1)
1793 1.1 christos options->address_family = AF_UNSPEC;
1794 1.1 christos if (options->connection_attempts == -1)
1795 1.1 christos options->connection_attempts = 1;
1796 1.1 christos if (options->number_of_password_prompts == -1)
1797 1.1 christos options->number_of_password_prompts = 3;
1798 1.1 christos /* Selected in ssh_login(). */
1799 1.1 christos if (options->cipher == -1)
1800 1.1 christos options->cipher = SSH_CIPHER_NOT_SET;
1801 1.1 christos /* options->hostkeyalgorithms, default set in myproposals.h */
1802 1.1 christos if (options->protocol == SSH_PROTO_UNKNOWN)
1803 1.1.1.3 adam options->protocol = SSH_PROTO_2;
1804 1.1.1.12 christos if (options->add_keys_to_agent == -1)
1805 1.1.1.12 christos options->add_keys_to_agent = 0;
1806 1.1 christos if (options->num_identity_files == 0) {
1807 1.1 christos if (options->protocol & SSH_PROTO_1) {
1808 1.1.1.7 christos add_identity_file(options, "~/",
1809 1.1.1.7 christos _PATH_SSH_CLIENT_IDENTITY, 0);
1810 1.1 christos }
1811 1.1 christos if (options->protocol & SSH_PROTO_2) {
1812 1.1.1.7 christos add_identity_file(options, "~/",
1813 1.1.1.7 christos _PATH_SSH_CLIENT_ID_RSA, 0);
1814 1.1.1.7 christos add_identity_file(options, "~/",
1815 1.1.1.7 christos _PATH_SSH_CLIENT_ID_DSA, 0);
1816 1.1.1.7 christos add_identity_file(options, "~/",
1817 1.1.1.7 christos _PATH_SSH_CLIENT_ID_ECDSA, 0);
1818 1.1.1.8 christos add_identity_file(options, "~/",
1819 1.1.1.8 christos _PATH_SSH_CLIENT_ID_ED25519, 0);
1820 1.1 christos }
1821 1.1 christos }
1822 1.1 christos if (options->escape_char == -1)
1823 1.1 christos options->escape_char = '~';
1824 1.1.1.5 christos if (options->num_system_hostfiles == 0) {
1825 1.1.1.5 christos options->system_hostfiles[options->num_system_hostfiles++] =
1826 1.1.1.5 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1827 1.1.1.5 christos options->system_hostfiles[options->num_system_hostfiles++] =
1828 1.1.1.5 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1829 1.1.1.5 christos }
1830 1.1.1.5 christos if (options->num_user_hostfiles == 0) {
1831 1.1.1.5 christos options->user_hostfiles[options->num_user_hostfiles++] =
1832 1.1.1.5 christos xstrdup(_PATH_SSH_USER_HOSTFILE);
1833 1.1.1.5 christos options->user_hostfiles[options->num_user_hostfiles++] =
1834 1.1.1.5 christos xstrdup(_PATH_SSH_USER_HOSTFILE2);
1835 1.1.1.5 christos }
1836 1.1 christos if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1837 1.1 christos options->log_level = SYSLOG_LEVEL_INFO;
1838 1.1 christos if (options->clear_forwardings == 1)
1839 1.1 christos clear_forwardings(options);
1840 1.1 christos if (options->no_host_authentication_for_localhost == - 1)
1841 1.1 christos options->no_host_authentication_for_localhost = 0;
1842 1.1 christos if (options->identities_only == -1)
1843 1.1 christos options->identities_only = 0;
1844 1.1 christos if (options->enable_ssh_keysign == -1)
1845 1.1 christos options->enable_ssh_keysign = 0;
1846 1.1 christos if (options->rekey_limit == -1)
1847 1.1 christos options->rekey_limit = 0;
1848 1.1.1.7 christos if (options->rekey_interval == -1)
1849 1.1.1.7 christos options->rekey_interval = 0;
1850 1.1 christos if (options->verify_host_key_dns == -1)
1851 1.1 christos options->verify_host_key_dns = 0;
1852 1.1 christos if (options->server_alive_interval == -1)
1853 1.1 christos options->server_alive_interval = 0;
1854 1.1 christos if (options->server_alive_count_max == -1)
1855 1.1 christos options->server_alive_count_max = 3;
1856 1.1 christos if (options->control_master == -1)
1857 1.1 christos options->control_master = 0;
1858 1.1.1.3 adam if (options->control_persist == -1) {
1859 1.1.1.3 adam options->control_persist = 0;
1860 1.1.1.3 adam options->control_persist_timeout = 0;
1861 1.1.1.3 adam }
1862 1.1 christos if (options->hash_known_hosts == -1)
1863 1.1 christos options->hash_known_hosts = 0;
1864 1.1 christos if (options->tun_open == -1)
1865 1.1 christos options->tun_open = SSH_TUNMODE_NO;
1866 1.1 christos if (options->tun_local == -1)
1867 1.1 christos options->tun_local = SSH_TUNID_ANY;
1868 1.1 christos if (options->tun_remote == -1)
1869 1.1 christos options->tun_remote = SSH_TUNID_ANY;
1870 1.1 christos if (options->permit_local_command == -1)
1871 1.1 christos options->permit_local_command = 0;
1872 1.1 christos if (options->visual_host_key == -1)
1873 1.1 christos options->visual_host_key = 0;
1874 1.1.1.4 christos if (options->ip_qos_interactive == -1)
1875 1.1.1.4 christos options->ip_qos_interactive = IPTOS_LOWDELAY;
1876 1.1.1.4 christos if (options->ip_qos_bulk == -1)
1877 1.1.1.4 christos options->ip_qos_bulk = IPTOS_THROUGHPUT;
1878 1.1.1.5 christos if (options->request_tty == -1)
1879 1.1.1.5 christos options->request_tty = REQUEST_TTY_AUTO;
1880 1.1.1.8 christos if (options->proxy_use_fdpass == -1)
1881 1.1.1.8 christos options->proxy_use_fdpass = 0;
1882 1.1.1.8 christos if (options->canonicalize_max_dots == -1)
1883 1.1.1.8 christos options->canonicalize_max_dots = 1;
1884 1.1.1.8 christos if (options->canonicalize_fallback_local == -1)
1885 1.1.1.8 christos options->canonicalize_fallback_local = 1;
1886 1.1.1.8 christos if (options->canonicalize_hostname == -1)
1887 1.1.1.8 christos options->canonicalize_hostname = SSH_CANONICALISE_NO;
1888 1.1.1.9 christos if (options->fingerprint_hash == -1)
1889 1.1.1.9 christos options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1890 1.1.1.9 christos if (options->update_hostkeys == -1)
1891 1.1.1.9 christos options->update_hostkeys = 0;
1892 1.1.1.11 christos if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
1893 1.1.1.11 christos kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
1894 1.1.1.11 christos kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
1895 1.1.1.11 christos kex_assemble_names(KEX_DEFAULT_PK_ALG,
1896 1.1.1.11 christos &options->hostbased_key_types) != 0 ||
1897 1.1.1.11 christos kex_assemble_names(KEX_DEFAULT_PK_ALG,
1898 1.1.1.11 christos &options->pubkey_key_types) != 0)
1899 1.1.1.11 christos fatal("%s: kex_assemble_names failed", __func__);
1900 1.1.1.9 christos
1901 1.1.1.8 christos #define CLEAR_ON_NONE(v) \
1902 1.1.1.8 christos do { \
1903 1.1.1.8 christos if (option_clear_or_none(v)) { \
1904 1.1.1.8 christos free(v); \
1905 1.1.1.8 christos v = NULL; \
1906 1.1.1.8 christos } \
1907 1.1.1.8 christos } while(0)
1908 1.1.1.8 christos CLEAR_ON_NONE(options->local_command);
1909 1.1.1.8 christos CLEAR_ON_NONE(options->proxy_command);
1910 1.1.1.8 christos CLEAR_ON_NONE(options->control_path);
1911 1.1.1.9 christos CLEAR_ON_NONE(options->revoked_host_keys);
1912 1.1 christos /* options->user will be set in the main program if appropriate */
1913 1.1 christos /* options->hostname will be set in the main program if appropriate */
1914 1.1 christos /* options->host_key_alias should not be set by default */
1915 1.1 christos /* options->preferred_authentications will be set in ssh */
1916 1.1 christos }
1917 1.1 christos
1918 1.1.1.8 christos struct fwdarg {
1919 1.1.1.8 christos char *arg;
1920 1.1.1.8 christos int ispath;
1921 1.1.1.8 christos };
1922 1.1.1.8 christos
1923 1.1.1.8 christos /*
1924 1.1.1.8 christos * parse_fwd_field
1925 1.1.1.8 christos * parses the next field in a port forwarding specification.
1926 1.1.1.8 christos * sets fwd to the parsed field and advances p past the colon
1927 1.1.1.8 christos * or sets it to NULL at end of string.
1928 1.1.1.8 christos * returns 0 on success, else non-zero.
1929 1.1.1.8 christos */
1930 1.1.1.8 christos static int
1931 1.1.1.8 christos parse_fwd_field(char **p, struct fwdarg *fwd)
1932 1.1.1.8 christos {
1933 1.1.1.8 christos char *ep, *cp = *p;
1934 1.1.1.8 christos int ispath = 0;
1935 1.1.1.8 christos
1936 1.1.1.8 christos if (*cp == '\0') {
1937 1.1.1.8 christos *p = NULL;
1938 1.1.1.8 christos return -1; /* end of string */
1939 1.1.1.8 christos }
1940 1.1.1.8 christos
1941 1.1.1.8 christos /*
1942 1.1.1.8 christos * A field escaped with square brackets is used literally.
1943 1.1.1.8 christos * XXX - allow ']' to be escaped via backslash?
1944 1.1.1.8 christos */
1945 1.1.1.8 christos if (*cp == '[') {
1946 1.1.1.8 christos /* find matching ']' */
1947 1.1.1.8 christos for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1948 1.1.1.8 christos if (*ep == '/')
1949 1.1.1.8 christos ispath = 1;
1950 1.1.1.8 christos }
1951 1.1.1.8 christos /* no matching ']' or not at end of field. */
1952 1.1.1.8 christos if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1953 1.1.1.8 christos return -1;
1954 1.1.1.8 christos /* NUL terminate the field and advance p past the colon */
1955 1.1.1.8 christos *ep++ = '\0';
1956 1.1.1.8 christos if (*ep != '\0')
1957 1.1.1.8 christos *ep++ = '\0';
1958 1.1.1.8 christos fwd->arg = cp + 1;
1959 1.1.1.8 christos fwd->ispath = ispath;
1960 1.1.1.8 christos *p = ep;
1961 1.1.1.8 christos return 0;
1962 1.1.1.8 christos }
1963 1.1.1.8 christos
1964 1.1.1.8 christos for (cp = *p; *cp != '\0'; cp++) {
1965 1.1.1.8 christos switch (*cp) {
1966 1.1.1.8 christos case '\\':
1967 1.1.1.8 christos memmove(cp, cp + 1, strlen(cp + 1) + 1);
1968 1.1.1.10 christos if (*cp == '\0')
1969 1.1.1.10 christos return -1;
1970 1.1.1.8 christos break;
1971 1.1.1.8 christos case '/':
1972 1.1.1.8 christos ispath = 1;
1973 1.1.1.8 christos break;
1974 1.1.1.8 christos case ':':
1975 1.1.1.8 christos *cp++ = '\0';
1976 1.1.1.8 christos goto done;
1977 1.1.1.8 christos }
1978 1.1.1.8 christos }
1979 1.1.1.8 christos done:
1980 1.1.1.8 christos fwd->arg = *p;
1981 1.1.1.8 christos fwd->ispath = ispath;
1982 1.1.1.8 christos *p = cp;
1983 1.1.1.8 christos return 0;
1984 1.1.1.8 christos }
1985 1.1.1.8 christos
1986 1.1 christos /*
1987 1.1 christos * parse_forward
1988 1.1 christos * parses a string containing a port forwarding specification of the form:
1989 1.1 christos * dynamicfwd == 0
1990 1.1.1.8 christos * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
1991 1.1.1.8 christos * listenpath:connectpath
1992 1.1 christos * dynamicfwd == 1
1993 1.1 christos * [listenhost:]listenport
1994 1.1 christos * returns number of arguments parsed or zero on error
1995 1.1 christos */
1996 1.1 christos int
1997 1.1.1.8 christos parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1998 1.1 christos {
1999 1.1.1.8 christos struct fwdarg fwdargs[4];
2000 1.1.1.8 christos char *p, *cp;
2001 1.1 christos int i;
2002 1.1 christos
2003 1.1.1.8 christos memset(fwd, 0, sizeof(*fwd));
2004 1.1.1.8 christos memset(fwdargs, 0, sizeof(fwdargs));
2005 1.1 christos
2006 1.1 christos cp = p = xstrdup(fwdspec);
2007 1.1 christos
2008 1.1 christos /* skip leading spaces */
2009 1.1.1.8 christos while (isspace((u_char)*cp))
2010 1.1 christos cp++;
2011 1.1 christos
2012 1.1.1.8 christos for (i = 0; i < 4; ++i) {
2013 1.1.1.8 christos if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2014 1.1 christos break;
2015 1.1.1.8 christos }
2016 1.1 christos
2017 1.1 christos /* Check for trailing garbage */
2018 1.1.1.8 christos if (cp != NULL && *cp != '\0') {
2019 1.1 christos i = 0; /* failure */
2020 1.1.1.8 christos }
2021 1.1 christos
2022 1.1 christos switch (i) {
2023 1.1 christos case 1:
2024 1.1.1.8 christos if (fwdargs[0].ispath) {
2025 1.1.1.8 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2026 1.1.1.8 christos fwd->listen_port = PORT_STREAMLOCAL;
2027 1.1.1.8 christos } else {
2028 1.1.1.8 christos fwd->listen_host = NULL;
2029 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[0].arg);
2030 1.1.1.8 christos }
2031 1.1 christos fwd->connect_host = xstrdup("socks");
2032 1.1 christos break;
2033 1.1 christos
2034 1.1 christos case 2:
2035 1.1.1.8 christos if (fwdargs[0].ispath && fwdargs[1].ispath) {
2036 1.1.1.8 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2037 1.1.1.8 christos fwd->listen_port = PORT_STREAMLOCAL;
2038 1.1.1.8 christos fwd->connect_path = xstrdup(fwdargs[1].arg);
2039 1.1.1.8 christos fwd->connect_port = PORT_STREAMLOCAL;
2040 1.1.1.8 christos } else if (fwdargs[1].ispath) {
2041 1.1.1.8 christos fwd->listen_host = NULL;
2042 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[0].arg);
2043 1.1.1.8 christos fwd->connect_path = xstrdup(fwdargs[1].arg);
2044 1.1.1.8 christos fwd->connect_port = PORT_STREAMLOCAL;
2045 1.1.1.8 christos } else {
2046 1.1.1.8 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2047 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[1].arg);
2048 1.1.1.8 christos fwd->connect_host = xstrdup("socks");
2049 1.1.1.8 christos }
2050 1.1 christos break;
2051 1.1 christos
2052 1.1 christos case 3:
2053 1.1.1.8 christos if (fwdargs[0].ispath) {
2054 1.1.1.8 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2055 1.1.1.8 christos fwd->listen_port = PORT_STREAMLOCAL;
2056 1.1.1.8 christos fwd->connect_host = xstrdup(fwdargs[1].arg);
2057 1.1.1.8 christos fwd->connect_port = a2port(fwdargs[2].arg);
2058 1.1.1.8 christos } else if (fwdargs[2].ispath) {
2059 1.1.1.8 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2060 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[1].arg);
2061 1.1.1.8 christos fwd->connect_path = xstrdup(fwdargs[2].arg);
2062 1.1.1.8 christos fwd->connect_port = PORT_STREAMLOCAL;
2063 1.1.1.8 christos } else {
2064 1.1.1.8 christos fwd->listen_host = NULL;
2065 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[0].arg);
2066 1.1.1.8 christos fwd->connect_host = xstrdup(fwdargs[1].arg);
2067 1.1.1.8 christos fwd->connect_port = a2port(fwdargs[2].arg);
2068 1.1.1.8 christos }
2069 1.1 christos break;
2070 1.1 christos
2071 1.1 christos case 4:
2072 1.1.1.8 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2073 1.1.1.8 christos fwd->listen_port = a2port(fwdargs[1].arg);
2074 1.1.1.8 christos fwd->connect_host = xstrdup(fwdargs[2].arg);
2075 1.1.1.8 christos fwd->connect_port = a2port(fwdargs[3].arg);
2076 1.1 christos break;
2077 1.1 christos default:
2078 1.1 christos i = 0; /* failure */
2079 1.1 christos }
2080 1.1 christos
2081 1.1.1.7 christos free(p);
2082 1.1 christos
2083 1.1 christos if (dynamicfwd) {
2084 1.1 christos if (!(i == 1 || i == 2))
2085 1.1 christos goto fail_free;
2086 1.1 christos } else {
2087 1.1.1.8 christos if (!(i == 3 || i == 4)) {
2088 1.1.1.8 christos if (fwd->connect_path == NULL &&
2089 1.1.1.8 christos fwd->listen_path == NULL)
2090 1.1.1.8 christos goto fail_free;
2091 1.1.1.8 christos }
2092 1.1.1.8 christos if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2093 1.1 christos goto fail_free;
2094 1.1 christos }
2095 1.1 christos
2096 1.1.1.8 christos if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2097 1.1.1.8 christos (!remotefwd && fwd->listen_port == 0))
2098 1.1 christos goto fail_free;
2099 1.1 christos if (fwd->connect_host != NULL &&
2100 1.1 christos strlen(fwd->connect_host) >= NI_MAXHOST)
2101 1.1 christos goto fail_free;
2102 1.1.1.8 christos /* XXX - if connecting to a remote socket, max sun len may not match this host */
2103 1.1.1.8 christos if (fwd->connect_path != NULL &&
2104 1.1.1.8 christos strlen(fwd->connect_path) >= PATH_MAX_SUN)
2105 1.1.1.8 christos goto fail_free;
2106 1.1 christos if (fwd->listen_host != NULL &&
2107 1.1 christos strlen(fwd->listen_host) >= NI_MAXHOST)
2108 1.1 christos goto fail_free;
2109 1.1.1.8 christos if (fwd->listen_path != NULL &&
2110 1.1.1.8 christos strlen(fwd->listen_path) >= PATH_MAX_SUN)
2111 1.1.1.8 christos goto fail_free;
2112 1.1 christos
2113 1.1 christos return (i);
2114 1.1 christos
2115 1.1 christos fail_free:
2116 1.1.1.7 christos free(fwd->connect_host);
2117 1.1.1.7 christos fwd->connect_host = NULL;
2118 1.1.1.8 christos free(fwd->connect_path);
2119 1.1.1.8 christos fwd->connect_path = NULL;
2120 1.1.1.7 christos free(fwd->listen_host);
2121 1.1.1.7 christos fwd->listen_host = NULL;
2122 1.1.1.8 christos free(fwd->listen_path);
2123 1.1.1.8 christos fwd->listen_path = NULL;
2124 1.1 christos return (0);
2125 1.1 christos }
2126 1.1.1.9 christos
2127 1.1.1.9 christos /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2128 1.1.1.9 christos static const char *
2129 1.1.1.9 christos fmt_multistate_int(int val, const struct multistate *m)
2130 1.1.1.9 christos {
2131 1.1.1.9 christos u_int i;
2132 1.1.1.9 christos
2133 1.1.1.9 christos for (i = 0; m[i].key != NULL; i++) {
2134 1.1.1.9 christos if (m[i].value == val)
2135 1.1.1.9 christos return m[i].key;
2136 1.1.1.9 christos }
2137 1.1.1.9 christos return "UNKNOWN";
2138 1.1.1.9 christos }
2139 1.1.1.9 christos
2140 1.1.1.9 christos static const char *
2141 1.1.1.9 christos fmt_intarg(OpCodes code, int val)
2142 1.1.1.9 christos {
2143 1.1.1.9 christos if (val == -1)
2144 1.1.1.9 christos return "unset";
2145 1.1.1.9 christos switch (code) {
2146 1.1.1.9 christos case oAddressFamily:
2147 1.1.1.9 christos return fmt_multistate_int(val, multistate_addressfamily);
2148 1.1.1.9 christos case oVerifyHostKeyDNS:
2149 1.1.1.9 christos case oStrictHostKeyChecking:
2150 1.1.1.9 christos case oUpdateHostkeys:
2151 1.1.1.9 christos return fmt_multistate_int(val, multistate_yesnoask);
2152 1.1.1.9 christos case oControlMaster:
2153 1.1.1.9 christos return fmt_multistate_int(val, multistate_controlmaster);
2154 1.1.1.9 christos case oTunnel:
2155 1.1.1.9 christos return fmt_multistate_int(val, multistate_tunnel);
2156 1.1.1.9 christos case oRequestTTY:
2157 1.1.1.9 christos return fmt_multistate_int(val, multistate_requesttty);
2158 1.1.1.9 christos case oCanonicalizeHostname:
2159 1.1.1.9 christos return fmt_multistate_int(val, multistate_canonicalizehostname);
2160 1.1.1.9 christos case oFingerprintHash:
2161 1.1.1.9 christos return ssh_digest_alg_name(val);
2162 1.1.1.9 christos case oProtocol:
2163 1.1.1.9 christos switch (val) {
2164 1.1.1.9 christos case SSH_PROTO_1:
2165 1.1.1.9 christos return "1";
2166 1.1.1.9 christos case SSH_PROTO_2:
2167 1.1.1.9 christos return "2";
2168 1.1.1.9 christos case (SSH_PROTO_1|SSH_PROTO_2):
2169 1.1.1.9 christos return "2,1";
2170 1.1.1.9 christos default:
2171 1.1.1.9 christos return "UNKNOWN";
2172 1.1.1.9 christos }
2173 1.1.1.9 christos default:
2174 1.1.1.9 christos switch (val) {
2175 1.1.1.9 christos case 0:
2176 1.1.1.9 christos return "no";
2177 1.1.1.9 christos case 1:
2178 1.1.1.9 christos return "yes";
2179 1.1.1.9 christos default:
2180 1.1.1.9 christos return "UNKNOWN";
2181 1.1.1.9 christos }
2182 1.1.1.9 christos }
2183 1.1.1.9 christos }
2184 1.1.1.9 christos
2185 1.1.1.9 christos static const char *
2186 1.1.1.9 christos lookup_opcode_name(OpCodes code)
2187 1.1.1.9 christos {
2188 1.1.1.9 christos u_int i;
2189 1.1.1.9 christos
2190 1.1.1.9 christos for (i = 0; keywords[i].name != NULL; i++)
2191 1.1.1.9 christos if (keywords[i].opcode == code)
2192 1.1.1.9 christos return(keywords[i].name);
2193 1.1.1.9 christos return "UNKNOWN";
2194 1.1.1.9 christos }
2195 1.1.1.9 christos
2196 1.1.1.9 christos static void
2197 1.1.1.9 christos dump_cfg_int(OpCodes code, int val)
2198 1.1.1.9 christos {
2199 1.1.1.9 christos printf("%s %d\n", lookup_opcode_name(code), val);
2200 1.1.1.9 christos }
2201 1.1.1.9 christos
2202 1.1.1.9 christos static void
2203 1.1.1.9 christos dump_cfg_fmtint(OpCodes code, int val)
2204 1.1.1.9 christos {
2205 1.1.1.9 christos printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2206 1.1.1.9 christos }
2207 1.1.1.9 christos
2208 1.1.1.9 christos static void
2209 1.1.1.9 christos dump_cfg_string(OpCodes code, const char *val)
2210 1.1.1.9 christos {
2211 1.1.1.9 christos if (val == NULL)
2212 1.1.1.9 christos return;
2213 1.1.1.9 christos printf("%s %s\n", lookup_opcode_name(code), val);
2214 1.1.1.9 christos }
2215 1.1.1.9 christos
2216 1.1.1.9 christos static void
2217 1.1.1.9 christos dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2218 1.1.1.9 christos {
2219 1.1.1.9 christos u_int i;
2220 1.1.1.9 christos
2221 1.1.1.9 christos for (i = 0; i < count; i++)
2222 1.1.1.9 christos printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2223 1.1.1.9 christos }
2224 1.1.1.9 christos
2225 1.1.1.9 christos static void
2226 1.1.1.9 christos dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2227 1.1.1.9 christos {
2228 1.1.1.9 christos u_int i;
2229 1.1.1.9 christos
2230 1.1.1.9 christos printf("%s", lookup_opcode_name(code));
2231 1.1.1.9 christos for (i = 0; i < count; i++)
2232 1.1.1.9 christos printf(" %s", vals[i]);
2233 1.1.1.9 christos printf("\n");
2234 1.1.1.9 christos }
2235 1.1.1.9 christos
2236 1.1.1.9 christos static void
2237 1.1.1.9 christos dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2238 1.1.1.9 christos {
2239 1.1.1.9 christos const struct Forward *fwd;
2240 1.1.1.9 christos u_int i;
2241 1.1.1.9 christos
2242 1.1.1.9 christos /* oDynamicForward */
2243 1.1.1.9 christos for (i = 0; i < count; i++) {
2244 1.1.1.9 christos fwd = &fwds[i];
2245 1.1.1.9 christos if (code == oDynamicForward &&
2246 1.1.1.9 christos strcmp(fwd->connect_host, "socks") != 0)
2247 1.1.1.9 christos continue;
2248 1.1.1.9 christos if (code == oLocalForward &&
2249 1.1.1.9 christos strcmp(fwd->connect_host, "socks") == 0)
2250 1.1.1.9 christos continue;
2251 1.1.1.9 christos printf("%s", lookup_opcode_name(code));
2252 1.1.1.9 christos if (fwd->listen_port == PORT_STREAMLOCAL)
2253 1.1.1.9 christos printf(" %s", fwd->listen_path);
2254 1.1.1.9 christos else if (fwd->listen_host == NULL)
2255 1.1.1.9 christos printf(" %d", fwd->listen_port);
2256 1.1.1.9 christos else {
2257 1.1.1.9 christos printf(" [%s]:%d",
2258 1.1.1.9 christos fwd->listen_host, fwd->listen_port);
2259 1.1.1.9 christos }
2260 1.1.1.9 christos if (code != oDynamicForward) {
2261 1.1.1.9 christos if (fwd->connect_port == PORT_STREAMLOCAL)
2262 1.1.1.9 christos printf(" %s", fwd->connect_path);
2263 1.1.1.9 christos else if (fwd->connect_host == NULL)
2264 1.1.1.9 christos printf(" %d", fwd->connect_port);
2265 1.1.1.9 christos else {
2266 1.1.1.9 christos printf(" [%s]:%d",
2267 1.1.1.9 christos fwd->connect_host, fwd->connect_port);
2268 1.1.1.9 christos }
2269 1.1.1.9 christos }
2270 1.1.1.9 christos printf("\n");
2271 1.1.1.9 christos }
2272 1.1.1.9 christos }
2273 1.1.1.9 christos
2274 1.1.1.9 christos void
2275 1.1.1.9 christos dump_client_config(Options *o, const char *host)
2276 1.1.1.9 christos {
2277 1.1.1.9 christos int i;
2278 1.1.1.9 christos char vbuf[5];
2279 1.1.1.9 christos
2280 1.1.1.12 christos /* This is normally prepared in ssh_kex2 */
2281 1.1.1.12 christos if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2282 1.1.1.12 christos fatal("%s: kex_assemble_names failed", __func__);
2283 1.1.1.12 christos
2284 1.1.1.9 christos /* Most interesting options first: user, host, port */
2285 1.1.1.9 christos dump_cfg_string(oUser, o->user);
2286 1.1.1.9 christos dump_cfg_string(oHostName, host);
2287 1.1.1.9 christos dump_cfg_int(oPort, o->port);
2288 1.1.1.9 christos
2289 1.1.1.9 christos /* Flag options */
2290 1.1.1.9 christos dump_cfg_fmtint(oAddressFamily, o->address_family);
2291 1.1.1.9 christos dump_cfg_fmtint(oBatchMode, o->batch_mode);
2292 1.1.1.9 christos dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2293 1.1.1.9 christos dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2294 1.1.1.9 christos dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2295 1.1.1.9 christos dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2296 1.1.1.9 christos dump_cfg_fmtint(oCompression, o->compression);
2297 1.1.1.9 christos dump_cfg_fmtint(oControlMaster, o->control_master);
2298 1.1.1.9 christos dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2299 1.1.1.9 christos dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2300 1.1.1.9 christos dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2301 1.1.1.9 christos dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2302 1.1.1.9 christos dump_cfg_fmtint(oForwardX11, o->forward_x11);
2303 1.1.1.9 christos dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2304 1.1.1.9 christos dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2305 1.1.1.9 christos #ifdef GSSAPI
2306 1.1.1.9 christos dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2307 1.1.1.9 christos dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2308 1.1.1.9 christos #endif /* GSSAPI */
2309 1.1.1.9 christos dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2310 1.1.1.9 christos dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2311 1.1.1.9 christos dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2312 1.1.1.9 christos dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2313 1.1.1.9 christos dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2314 1.1.1.9 christos dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2315 1.1.1.9 christos dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2316 1.1.1.9 christos dump_cfg_fmtint(oProtocol, o->protocol);
2317 1.1.1.9 christos dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2318 1.1.1.9 christos dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2319 1.1.1.9 christos dump_cfg_fmtint(oRequestTTY, o->request_tty);
2320 1.1.1.9 christos dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2321 1.1.1.9 christos dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2322 1.1.1.9 christos dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2323 1.1.1.9 christos dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2324 1.1.1.9 christos dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2325 1.1.1.9 christos dump_cfg_fmtint(oTunnel, o->tun_open);
2326 1.1.1.9 christos dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2327 1.1.1.9 christos dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2328 1.1.1.9 christos dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2329 1.1.1.9 christos dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2330 1.1.1.9 christos
2331 1.1.1.9 christos /* Integer options */
2332 1.1.1.9 christos dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2333 1.1.1.9 christos dump_cfg_int(oCompressionLevel, o->compression_level);
2334 1.1.1.9 christos dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2335 1.1.1.9 christos dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2336 1.1.1.9 christos dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2337 1.1.1.9 christos dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2338 1.1.1.9 christos dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2339 1.1.1.9 christos
2340 1.1.1.9 christos /* String options */
2341 1.1.1.9 christos dump_cfg_string(oBindAddress, o->bind_address);
2342 1.1.1.9 christos dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2343 1.1.1.9 christos dump_cfg_string(oControlPath, o->control_path);
2344 1.1.1.12 christos dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2345 1.1.1.9 christos dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2346 1.1.1.9 christos dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2347 1.1.1.9 christos dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2348 1.1.1.9 christos dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2349 1.1.1.9 christos dump_cfg_string(oLocalCommand, o->local_command);
2350 1.1.1.9 christos dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2351 1.1.1.9 christos dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2352 1.1.1.9 christos dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2353 1.1.1.9 christos dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2354 1.1.1.9 christos dump_cfg_string(oProxyCommand, o->proxy_command);
2355 1.1.1.12 christos dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2356 1.1.1.9 christos dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2357 1.1.1.9 christos dump_cfg_string(oXAuthLocation, o->xauth_location);
2358 1.1.1.9 christos
2359 1.1.1.9 christos /* Forwards */
2360 1.1.1.9 christos dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2361 1.1.1.9 christos dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2362 1.1.1.9 christos dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2363 1.1.1.9 christos
2364 1.1.1.9 christos /* String array options */
2365 1.1.1.9 christos dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2366 1.1.1.9 christos dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2367 1.1.1.9 christos dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2368 1.1.1.9 christos dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2369 1.1.1.9 christos dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2370 1.1.1.9 christos
2371 1.1.1.9 christos /* Special cases */
2372 1.1.1.9 christos
2373 1.1.1.9 christos /* oConnectTimeout */
2374 1.1.1.9 christos if (o->connection_timeout == -1)
2375 1.1.1.9 christos printf("connecttimeout none\n");
2376 1.1.1.9 christos else
2377 1.1.1.9 christos dump_cfg_int(oConnectTimeout, o->connection_timeout);
2378 1.1.1.9 christos
2379 1.1.1.9 christos /* oTunnelDevice */
2380 1.1.1.9 christos printf("tunneldevice");
2381 1.1.1.9 christos if (o->tun_local == SSH_TUNID_ANY)
2382 1.1.1.9 christos printf(" any");
2383 1.1.1.9 christos else
2384 1.1.1.9 christos printf(" %d", o->tun_local);
2385 1.1.1.9 christos if (o->tun_remote == SSH_TUNID_ANY)
2386 1.1.1.9 christos printf(":any");
2387 1.1.1.9 christos else
2388 1.1.1.9 christos printf(":%d", o->tun_remote);
2389 1.1.1.9 christos printf("\n");
2390 1.1.1.9 christos
2391 1.1.1.9 christos /* oCanonicalizePermittedCNAMEs */
2392 1.1.1.9 christos if ( o->num_permitted_cnames > 0) {
2393 1.1.1.9 christos printf("canonicalizePermittedcnames");
2394 1.1.1.9 christos for (i = 0; i < o->num_permitted_cnames; i++) {
2395 1.1.1.9 christos printf(" %s:%s", o->permitted_cnames[i].source_list,
2396 1.1.1.9 christos o->permitted_cnames[i].target_list);
2397 1.1.1.9 christos }
2398 1.1.1.9 christos printf("\n");
2399 1.1.1.9 christos }
2400 1.1.1.9 christos
2401 1.1.1.9 christos /* oCipher */
2402 1.1.1.9 christos if (o->cipher != SSH_CIPHER_NOT_SET)
2403 1.1.1.9 christos printf("Cipher %s\n", cipher_name(o->cipher));
2404 1.1.1.9 christos
2405 1.1.1.9 christos /* oControlPersist */
2406 1.1.1.9 christos if (o->control_persist == 0 || o->control_persist_timeout == 0)
2407 1.1.1.9 christos dump_cfg_fmtint(oControlPersist, o->control_persist);
2408 1.1.1.9 christos else
2409 1.1.1.9 christos dump_cfg_int(oControlPersist, o->control_persist_timeout);
2410 1.1.1.9 christos
2411 1.1.1.9 christos /* oEscapeChar */
2412 1.1.1.9 christos if (o->escape_char == SSH_ESCAPECHAR_NONE)
2413 1.1.1.9 christos printf("escapechar none\n");
2414 1.1.1.9 christos else {
2415 1.1.1.9 christos vis(vbuf, o->escape_char, VIS_WHITE, 0);
2416 1.1.1.9 christos printf("escapechar %s\n", vbuf);
2417 1.1.1.9 christos }
2418 1.1.1.9 christos
2419 1.1.1.9 christos /* oIPQoS */
2420 1.1.1.9 christos printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2421 1.1.1.9 christos printf("%s\n", iptos2str(o->ip_qos_bulk));
2422 1.1.1.9 christos
2423 1.1.1.9 christos /* oRekeyLimit */
2424 1.1.1.12 christos printf("rekeylimit %llu %d\n",
2425 1.1.1.12 christos (unsigned long long)o->rekey_limit, o->rekey_interval);
2426 1.1.1.9 christos
2427 1.1.1.9 christos /* oStreamLocalBindMask */
2428 1.1.1.9 christos printf("streamlocalbindmask 0%o\n",
2429 1.1.1.9 christos o->fwd_opts.streamlocal_bind_mask);
2430 1.1.1.9 christos }
2431