readconf.c revision 1.31 1 1.30 kim /* $NetBSD: readconf.c,v 1.31 2020/05/28 17:05:49 christos Exp $ */
2 1.31 christos /* $OpenBSD: readconf.c,v 1.329 2020/04/24 03:33:21 dtucker Exp $ */
3 1.1 christos /*
4 1.1 christos * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
5 1.1 christos * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
6 1.1 christos * All rights reserved
7 1.1 christos * Functions for reading the configuration files.
8 1.1 christos *
9 1.1 christos * As far as I am concerned, the code I have written for this software
10 1.1 christos * can be used freely for any purpose. Any derived versions of this
11 1.1 christos * software must be clearly marked as such, and if the derived work is
12 1.1 christos * incompatible with the protocol description in the RFC file, it must be
13 1.1 christos * called by a name other than "ssh" or "Secure Shell".
14 1.1 christos */
15 1.1 christos
16 1.2 christos #include "includes.h"
17 1.30 kim __RCSID("$NetBSD: readconf.c,v 1.31 2020/05/28 17:05:49 christos Exp $");
18 1.1 christos #include <sys/types.h>
19 1.1 christos #include <sys/stat.h>
20 1.1 christos #include <sys/socket.h>
21 1.12 christos #include <sys/wait.h>
22 1.12 christos #include <sys/un.h>
23 1.1 christos
24 1.1 christos #include <netinet/in.h>
25 1.5 christos #include <netinet/ip.h>
26 1.1 christos
27 1.1 christos #include <ctype.h>
28 1.1 christos #include <errno.h>
29 1.12 christos #include <fcntl.h>
30 1.19 christos #include <glob.h>
31 1.1 christos #include <netdb.h>
32 1.12 christos #include <paths.h>
33 1.12 christos #include <pwd.h>
34 1.1 christos #include <signal.h>
35 1.1 christos #include <stdio.h>
36 1.1 christos #include <string.h>
37 1.29 christos #include <stdarg.h>
38 1.1 christos #include <unistd.h>
39 1.2 christos #include <limits.h>
40 1.11 christos #include <util.h>
41 1.13 christos #include <vis.h>
42 1.1 christos
43 1.1 christos #include "xmalloc.h"
44 1.1 christos #include "ssh.h"
45 1.25 christos #include "ssherr.h"
46 1.1 christos #include "compat.h"
47 1.1 christos #include "cipher.h"
48 1.1 christos #include "pathnames.h"
49 1.1 christos #include "log.h"
50 1.13 christos #include "sshkey.h"
51 1.12 christos #include "misc.h"
52 1.1 christos #include "readconf.h"
53 1.1 christos #include "match.h"
54 1.1 christos #include "kex.h"
55 1.1 christos #include "mac.h"
56 1.11 christos #include "fmt_scaled.h"
57 1.12 christos #include "uidswap.h"
58 1.13 christos #include "myproposal.h"
59 1.13 christos #include "digest.h"
60 1.1 christos
61 1.1 christos /* Format of the configuration file:
62 1.1 christos
63 1.1 christos # Configuration data is parsed as follows:
64 1.1 christos # 1. command line options
65 1.1 christos # 2. user-specific file
66 1.1 christos # 3. system-wide file
67 1.1 christos # Any configuration value is only changed the first time it is set.
68 1.1 christos # Thus, host-specific definitions should be at the beginning of the
69 1.1 christos # configuration file, and defaults at the end.
70 1.1 christos
71 1.1 christos # Host-specific declarations. These may override anything above. A single
72 1.1 christos # host may match multiple declarations; these are processed in the order
73 1.1 christos # that they are given in.
74 1.1 christos
75 1.1 christos Host *.ngs.fi ngs.fi
76 1.1 christos User foo
77 1.1 christos
78 1.1 christos Host fake.com
79 1.28 christos Hostname another.host.name.real.org
80 1.1 christos User blaah
81 1.1 christos Port 34289
82 1.1 christos ForwardX11 no
83 1.1 christos ForwardAgent no
84 1.1 christos
85 1.1 christos Host books.com
86 1.1 christos RemoteForward 9999 shadows.cs.hut.fi:9999
87 1.21 christos Ciphers 3des-cbc
88 1.1 christos
89 1.1 christos Host fascist.blob.com
90 1.1 christos Port 23123
91 1.1 christos User tylonen
92 1.1 christos PasswordAuthentication no
93 1.1 christos
94 1.1 christos Host puukko.hut.fi
95 1.1 christos User t35124p
96 1.1 christos ProxyCommand ssh-proxy %h %p
97 1.1 christos
98 1.1 christos Host *.fr
99 1.1 christos PublicKeyAuthentication no
100 1.1 christos
101 1.1 christos Host *.su
102 1.21 christos Ciphers aes128-ctr
103 1.1 christos PasswordAuthentication no
104 1.1 christos
105 1.1 christos Host vpn.fake.com
106 1.1 christos Tunnel yes
107 1.1 christos TunnelDevice 3
108 1.1 christos
109 1.1 christos # Defaults for various options
110 1.1 christos Host *
111 1.1 christos ForwardAgent no
112 1.1 christos ForwardX11 no
113 1.1 christos PasswordAuthentication yes
114 1.1 christos StrictHostKeyChecking yes
115 1.1 christos TcpKeepAlive no
116 1.1 christos IdentityFile ~/.ssh/identity
117 1.1 christos Port 22
118 1.1 christos EscapeChar ~
119 1.1 christos
120 1.1 christos */
121 1.1 christos
122 1.19 christos static int read_config_file_depth(const char *filename, struct passwd *pw,
123 1.19 christos const char *host, const char *original_host, Options *options,
124 1.27 christos int flags, int *activep, int *want_final_pass, int depth);
125 1.19 christos static int process_config_line_depth(Options *options, struct passwd *pw,
126 1.19 christos const char *host, const char *original_host, char *line,
127 1.27 christos const char *filename, int linenum, int *activep, int flags,
128 1.27 christos int *want_final_pass, int depth);
129 1.19 christos
130 1.1 christos /* Keyword tokens. */
131 1.1 christos
132 1.1 christos typedef enum {
133 1.1 christos oBadOption,
134 1.19 christos oHost, oMatch, oInclude,
135 1.4 adam oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
136 1.4 adam oGatewayPorts, oExitOnForwardFailure,
137 1.29 christos oPasswordAuthentication,
138 1.1 christos oChallengeResponseAuthentication, oXAuthLocation,
139 1.2 christos #if defined(KRB4) || defined(KRB5)
140 1.2 christos oKerberosAuthentication,
141 1.2 christos #endif
142 1.2 christos #if defined(AFS) || defined(KRB5)
143 1.2 christos oKerberosTgtPassing,
144 1.2 christos #endif
145 1.2 christos #ifdef AFS
146 1.2 christos oAFSTokenPassing,
147 1.2 christos #endif
148 1.29 christos oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
149 1.19 christos oCertificateFile, oAddKeysToAgent, oIdentityAgent,
150 1.29 christos oUser, oEscapeChar, oProxyCommand,
151 1.1 christos oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
152 1.1 christos oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
153 1.29 christos oTCPKeepAlive, oNumberOfPasswordPrompts,
154 1.29 christos oLogFacility, oLogLevel, oCiphers, oMacs,
155 1.13 christos oPubkeyAuthentication,
156 1.1 christos oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
157 1.1 christos oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
158 1.23 christos oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
159 1.1 christos oClearAllForwardings, oNoHostAuthenticationForLocalhost,
160 1.1 christos oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
161 1.1 christos oAddressFamily, oGssAuthentication, oGssDelegateCreds,
162 1.1 christos oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
163 1.25 christos oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
164 1.4 adam oHashKnownHosts,
165 1.22 christos oTunnel, oTunnelDevice,
166 1.22 christos oLocalCommand, oPermitLocalCommand, oRemoteCommand,
167 1.17 christos oVisualHostKey,
168 1.12 christos oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
169 1.12 christos oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
170 1.12 christos oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
171 1.13 christos oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
172 1.13 christos oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
173 1.27 christos oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump,
174 1.2 christos oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
175 1.2 christos oHPNBufferSize,
176 1.7 tls oSendVersionFirst,
177 1.29 christos oSecurityKeyProvider,
178 1.22 christos oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
179 1.1 christos } OpCodes;
180 1.1 christos
181 1.1 christos /* Textual representations of the tokens. */
182 1.1 christos
183 1.1 christos static struct {
184 1.1 christos const char *name;
185 1.1 christos OpCodes opcode;
186 1.1 christos } keywords[] = {
187 1.21 christos /* Deprecated options */
188 1.22 christos { "protocol", oIgnore }, /* NB. silently ignored */
189 1.22 christos { "cipher", oDeprecated },
190 1.21 christos { "fallbacktorsh", oDeprecated },
191 1.21 christos { "globalknownhostsfile2", oDeprecated },
192 1.21 christos { "rhostsauthentication", oDeprecated },
193 1.21 christos { "userknownhostsfile2", oDeprecated },
194 1.21 christos { "useroaming", oDeprecated },
195 1.21 christos { "usersh", oDeprecated },
196 1.25 christos { "useprivilegedport", oDeprecated },
197 1.21 christos
198 1.21 christos /* Unsupported options */
199 1.30 kim #ifdef AFS
200 1.30 kim { "afstokenpassing", oAFSTokenPassing },
201 1.30 kim #else
202 1.21 christos { "afstokenpassing", oUnsupported },
203 1.30 kim #endif
204 1.30 kim #if defined(KRB4) || defined(KRB5)
205 1.30 kim { "kerberosauthentication", oKerberosAuthentication },
206 1.30 kim #else
207 1.21 christos { "kerberosauthentication", oUnsupported },
208 1.30 kim #endif
209 1.30 kim #if defined(AFS) || defined(KRB5)
210 1.30 kim { "kerberostgtpassing", oKerberosTgtPassing },
211 1.30 kim { "kerberos5tgtpassing", oKerberosTgtPassing }, /* alias */
212 1.30 kim { "kerberos4tgtpassing", oKerberosTgtPassing }, /* alias */
213 1.30 kim #else
214 1.21 christos { "kerberostgtpassing", oUnsupported },
215 1.30 kim { "kerberos5tgtpassing", oUnsupported },
216 1.30 kim { "kerberos4tgtpassing", oUnsupported },
217 1.30 kim #endif
218 1.29 christos { "rsaauthentication", oUnsupported },
219 1.29 christos { "rhostsrsaauthentication", oUnsupported },
220 1.29 christos { "compressionlevel", oUnsupported },
221 1.21 christos
222 1.21 christos /* Sometimes-unsupported options */
223 1.21 christos #if defined(GSSAPI)
224 1.21 christos { "gssapiauthentication", oGssAuthentication },
225 1.21 christos { "gssapidelegatecredentials", oGssDelegateCreds },
226 1.21 christos # else
227 1.21 christos { "gssapiauthentication", oUnsupported },
228 1.21 christos { "gssapidelegatecredentials", oUnsupported },
229 1.21 christos #endif
230 1.21 christos #ifdef ENABLE_PKCS11
231 1.27 christos { "pkcs11provider", oPKCS11Provider },
232 1.21 christos { "smartcarddevice", oPKCS11Provider },
233 1.21 christos # else
234 1.21 christos { "smartcarddevice", oUnsupported },
235 1.21 christos { "pkcs11provider", oUnsupported },
236 1.21 christos #endif
237 1.21 christos
238 1.1 christos { "forwardagent", oForwardAgent },
239 1.1 christos { "forwardx11", oForwardX11 },
240 1.1 christos { "forwardx11trusted", oForwardX11Trusted },
241 1.4 adam { "forwardx11timeout", oForwardX11Timeout },
242 1.1 christos { "exitonforwardfailure", oExitOnForwardFailure },
243 1.1 christos { "xauthlocation", oXAuthLocation },
244 1.1 christos { "gatewayports", oGatewayPorts },
245 1.1 christos { "passwordauthentication", oPasswordAuthentication },
246 1.1 christos { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
247 1.1 christos { "kbdinteractivedevices", oKbdInteractiveDevices },
248 1.1 christos { "pubkeyauthentication", oPubkeyAuthentication },
249 1.1 christos { "dsaauthentication", oPubkeyAuthentication }, /* alias */
250 1.1 christos { "hostbasedauthentication", oHostbasedAuthentication },
251 1.1 christos { "challengeresponseauthentication", oChallengeResponseAuthentication },
252 1.1 christos { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
253 1.1 christos { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
254 1.1 christos #if defined(GSSAPI)
255 1.1 christos { "gssapiauthentication", oGssAuthentication },
256 1.1 christos { "gssapidelegatecredentials", oGssDelegateCreds },
257 1.1 christos #else
258 1.1 christos { "gssapiauthentication", oUnsupported },
259 1.1 christos { "gssapidelegatecredentials", oUnsupported },
260 1.1 christos #endif
261 1.1 christos { "identityfile", oIdentityFile },
262 1.1 christos { "identityfile2", oIdentityFile }, /* obsolete */
263 1.1 christos { "identitiesonly", oIdentitiesOnly },
264 1.18 christos { "certificatefile", oCertificateFile },
265 1.18 christos { "addkeystoagent", oAddKeysToAgent },
266 1.19 christos { "identityagent", oIdentityAgent },
267 1.28 christos { "hostname", oHostname },
268 1.1 christos { "hostkeyalias", oHostKeyAlias },
269 1.1 christos { "proxycommand", oProxyCommand },
270 1.1 christos { "port", oPort },
271 1.1 christos { "ciphers", oCiphers },
272 1.1 christos { "macs", oMacs },
273 1.1 christos { "remoteforward", oRemoteForward },
274 1.1 christos { "localforward", oLocalForward },
275 1.1 christos { "user", oUser },
276 1.1 christos { "host", oHost },
277 1.12 christos { "match", oMatch },
278 1.1 christos { "escapechar", oEscapeChar },
279 1.1 christos { "globalknownhostsfile", oGlobalKnownHostsFile },
280 1.1 christos { "userknownhostsfile", oUserKnownHostsFile },
281 1.1 christos { "connectionattempts", oConnectionAttempts },
282 1.1 christos { "batchmode", oBatchMode },
283 1.1 christos { "checkhostip", oCheckHostIP },
284 1.1 christos { "stricthostkeychecking", oStrictHostKeyChecking },
285 1.1 christos { "compression", oCompression },
286 1.1 christos { "tcpkeepalive", oTCPKeepAlive },
287 1.1 christos { "keepalive", oTCPKeepAlive }, /* obsolete */
288 1.1 christos { "numberofpasswordprompts", oNumberOfPasswordPrompts },
289 1.22 christos { "syslogfacility", oLogFacility },
290 1.1 christos { "loglevel", oLogLevel },
291 1.1 christos { "dynamicforward", oDynamicForward },
292 1.1 christos { "preferredauthentications", oPreferredAuthentications },
293 1.1 christos { "hostkeyalgorithms", oHostKeyAlgorithms },
294 1.27 christos { "casignaturealgorithms", oCASignatureAlgorithms },
295 1.1 christos { "bindaddress", oBindAddress },
296 1.23 christos { "bindinterface", oBindInterface },
297 1.1 christos { "clearallforwardings", oClearAllForwardings },
298 1.1 christos { "enablesshkeysign", oEnableSSHKeysign },
299 1.1 christos { "verifyhostkeydns", oVerifyHostKeyDNS },
300 1.1 christos { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
301 1.1 christos { "rekeylimit", oRekeyLimit },
302 1.1 christos { "connecttimeout", oConnectTimeout },
303 1.1 christos { "addressfamily", oAddressFamily },
304 1.1 christos { "serveraliveinterval", oServerAliveInterval },
305 1.1 christos { "serveralivecountmax", oServerAliveCountMax },
306 1.1 christos { "sendenv", oSendEnv },
307 1.25 christos { "setenv", oSetEnv },
308 1.1 christos { "controlpath", oControlPath },
309 1.1 christos { "controlmaster", oControlMaster },
310 1.4 adam { "controlpersist", oControlPersist },
311 1.1 christos { "hashknownhosts", oHashKnownHosts },
312 1.19 christos { "include", oInclude },
313 1.1 christos { "tunnel", oTunnel },
314 1.1 christos { "tunneldevice", oTunnelDevice },
315 1.1 christos { "localcommand", oLocalCommand },
316 1.1 christos { "permitlocalcommand", oPermitLocalCommand },
317 1.22 christos { "remotecommand", oRemoteCommand },
318 1.1 christos { "visualhostkey", oVisualHostKey },
319 1.5 christos { "kexalgorithms", oKexAlgorithms },
320 1.5 christos { "ipqos", oIPQoS },
321 1.6 christos { "requesttty", oRequestTTY },
322 1.12 christos { "proxyusefdpass", oProxyUseFdpass },
323 1.12 christos { "canonicaldomains", oCanonicalDomains },
324 1.12 christos { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
325 1.12 christos { "canonicalizehostname", oCanonicalizeHostname },
326 1.12 christos { "canonicalizemaxdots", oCanonicalizeMaxDots },
327 1.12 christos { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
328 1.12 christos { "streamlocalbindmask", oStreamLocalBindMask },
329 1.12 christos { "streamlocalbindunlink", oStreamLocalBindUnlink },
330 1.13 christos { "revokedhostkeys", oRevokedHostKeys },
331 1.13 christos { "fingerprinthash", oFingerprintHash },
332 1.13 christos { "updatehostkeys", oUpdateHostkeys },
333 1.13 christos { "hostbasedkeytypes", oHostbasedKeyTypes },
334 1.16 christos { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
335 1.19 christos { "proxyjump", oProxyJump },
336 1.2 christos { "noneenabled", oNoneEnabled },
337 1.2 christos { "tcprcvbufpoll", oTcpRcvBufPoll },
338 1.2 christos { "tcprcvbuf", oTcpRcvBuf },
339 1.2 christos { "noneswitch", oNoneSwitch },
340 1.2 christos { "hpndisabled", oHPNDisabled },
341 1.2 christos { "hpnbuffersize", oHPNBufferSize },
342 1.7 tls { "sendversionfirst", oSendVersionFirst },
343 1.12 christos { "ignoreunknown", oIgnoreUnknown },
344 1.29 christos { "proxyjump", oProxyJump },
345 1.29 christos { "securitykeyprovider", oSecurityKeyProvider },
346 1.19 christos
347 1.1 christos { NULL, oBadOption }
348 1.1 christos };
349 1.1 christos
350 1.29 christos static char *kex_default_pk_alg_filtered;
351 1.29 christos
352 1.29 christos const char *
353 1.29 christos kex_default_pk_alg(void)
354 1.29 christos {
355 1.29 christos if (kex_default_pk_alg_filtered == NULL)
356 1.29 christos fatal("kex_default_pk_alg not initialized.");
357 1.29 christos return kex_default_pk_alg_filtered;
358 1.29 christos }
359 1.29 christos
360 1.31 christos char *
361 1.31 christos ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
362 1.31 christos const char *user)
363 1.31 christos {
364 1.31 christos struct ssh_digest_ctx *md;
365 1.31 christos u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
366 1.31 christos
367 1.31 christos if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
368 1.31 christos ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
369 1.31 christos ssh_digest_update(md, host, strlen(host)) < 0 ||
370 1.31 christos ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
371 1.31 christos ssh_digest_update(md, user, strlen(user)) < 0 ||
372 1.31 christos ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
373 1.31 christos fatal("%s: mux digest failed", __func__);
374 1.31 christos ssh_digest_free(md);
375 1.31 christos return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
376 1.31 christos }
377 1.31 christos
378 1.1 christos /*
379 1.1 christos * Adds a local TCP/IP port forward to options. Never returns if there is an
380 1.1 christos * error.
381 1.1 christos */
382 1.1 christos
383 1.1 christos void
384 1.12 christos add_local_forward(Options *options, const struct Forward *newfwd)
385 1.1 christos {
386 1.12 christos struct Forward *fwd;
387 1.19 christos int i;
388 1.4 adam
389 1.19 christos /* Don't add duplicates */
390 1.19 christos for (i = 0; i < options->num_local_forwards; i++) {
391 1.19 christos if (forward_equals(newfwd, options->local_forwards + i))
392 1.19 christos return;
393 1.19 christos }
394 1.14 christos options->local_forwards = xreallocarray(options->local_forwards,
395 1.4 adam options->num_local_forwards + 1,
396 1.4 adam sizeof(*options->local_forwards));
397 1.1 christos fwd = &options->local_forwards[options->num_local_forwards++];
398 1.1 christos
399 1.1 christos fwd->listen_host = newfwd->listen_host;
400 1.1 christos fwd->listen_port = newfwd->listen_port;
401 1.12 christos fwd->listen_path = newfwd->listen_path;
402 1.1 christos fwd->connect_host = newfwd->connect_host;
403 1.1 christos fwd->connect_port = newfwd->connect_port;
404 1.12 christos fwd->connect_path = newfwd->connect_path;
405 1.1 christos }
406 1.1 christos
407 1.1 christos /*
408 1.1 christos * Adds a remote TCP/IP port forward to options. Never returns if there is
409 1.1 christos * an error.
410 1.1 christos */
411 1.1 christos
412 1.1 christos void
413 1.12 christos add_remote_forward(Options *options, const struct Forward *newfwd)
414 1.1 christos {
415 1.12 christos struct Forward *fwd;
416 1.19 christos int i;
417 1.4 adam
418 1.19 christos /* Don't add duplicates */
419 1.19 christos for (i = 0; i < options->num_remote_forwards; i++) {
420 1.19 christos if (forward_equals(newfwd, options->remote_forwards + i))
421 1.19 christos return;
422 1.19 christos }
423 1.14 christos options->remote_forwards = xreallocarray(options->remote_forwards,
424 1.4 adam options->num_remote_forwards + 1,
425 1.4 adam sizeof(*options->remote_forwards));
426 1.1 christos fwd = &options->remote_forwards[options->num_remote_forwards++];
427 1.1 christos
428 1.1 christos fwd->listen_host = newfwd->listen_host;
429 1.1 christos fwd->listen_port = newfwd->listen_port;
430 1.12 christos fwd->listen_path = newfwd->listen_path;
431 1.1 christos fwd->connect_host = newfwd->connect_host;
432 1.1 christos fwd->connect_port = newfwd->connect_port;
433 1.12 christos fwd->connect_path = newfwd->connect_path;
434 1.8 christos fwd->handle = newfwd->handle;
435 1.4 adam fwd->allocated_port = 0;
436 1.1 christos }
437 1.1 christos
438 1.1 christos static void
439 1.1 christos clear_forwardings(Options *options)
440 1.1 christos {
441 1.1 christos int i;
442 1.1 christos
443 1.1 christos for (i = 0; i < options->num_local_forwards; i++) {
444 1.11 christos free(options->local_forwards[i].listen_host);
445 1.12 christos free(options->local_forwards[i].listen_path);
446 1.11 christos free(options->local_forwards[i].connect_host);
447 1.12 christos free(options->local_forwards[i].connect_path);
448 1.1 christos }
449 1.4 adam if (options->num_local_forwards > 0) {
450 1.11 christos free(options->local_forwards);
451 1.4 adam options->local_forwards = NULL;
452 1.4 adam }
453 1.1 christos options->num_local_forwards = 0;
454 1.1 christos for (i = 0; i < options->num_remote_forwards; i++) {
455 1.11 christos free(options->remote_forwards[i].listen_host);
456 1.12 christos free(options->remote_forwards[i].listen_path);
457 1.11 christos free(options->remote_forwards[i].connect_host);
458 1.12 christos free(options->remote_forwards[i].connect_path);
459 1.1 christos }
460 1.4 adam if (options->num_remote_forwards > 0) {
461 1.11 christos free(options->remote_forwards);
462 1.4 adam options->remote_forwards = NULL;
463 1.4 adam }
464 1.1 christos options->num_remote_forwards = 0;
465 1.1 christos options->tun_open = SSH_TUNMODE_NO;
466 1.1 christos }
467 1.1 christos
468 1.9 mlelstv void
469 1.18 christos add_certificate_file(Options *options, const char *path, int userprovided)
470 1.18 christos {
471 1.18 christos int i;
472 1.18 christos
473 1.18 christos if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
474 1.18 christos fatal("Too many certificate files specified (max %d)",
475 1.18 christos SSH_MAX_CERTIFICATE_FILES);
476 1.18 christos
477 1.18 christos /* Avoid registering duplicates */
478 1.18 christos for (i = 0; i < options->num_certificate_files; i++) {
479 1.18 christos if (options->certificate_file_userprovided[i] == userprovided &&
480 1.18 christos strcmp(options->certificate_files[i], path) == 0) {
481 1.18 christos debug2("%s: ignoring duplicate key %s", __func__, path);
482 1.18 christos return;
483 1.18 christos }
484 1.18 christos }
485 1.18 christos
486 1.18 christos options->certificate_file_userprovided[options->num_certificate_files] =
487 1.18 christos userprovided;
488 1.18 christos options->certificate_files[options->num_certificate_files++] =
489 1.18 christos xstrdup(path);
490 1.18 christos }
491 1.18 christos
492 1.18 christos void
493 1.9 mlelstv add_identity_file(Options *options, const char *dir, const char *filename,
494 1.9 mlelstv int userprovided)
495 1.9 mlelstv {
496 1.9 mlelstv char *path;
497 1.12 christos int i;
498 1.9 mlelstv
499 1.9 mlelstv if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
500 1.9 mlelstv fatal("Too many identity files specified (max %d)",
501 1.9 mlelstv SSH_MAX_IDENTITY_FILES);
502 1.9 mlelstv
503 1.9 mlelstv if (dir == NULL) /* no dir, filename is absolute */
504 1.9 mlelstv path = xstrdup(filename);
505 1.22 christos else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
506 1.22 christos fatal("Identity file path %s too long", path);
507 1.9 mlelstv
508 1.12 christos /* Avoid registering duplicates */
509 1.12 christos for (i = 0; i < options->num_identity_files; i++) {
510 1.12 christos if (options->identity_file_userprovided[i] == userprovided &&
511 1.12 christos strcmp(options->identity_files[i], path) == 0) {
512 1.12 christos debug2("%s: ignoring duplicate key %s", __func__, path);
513 1.12 christos free(path);
514 1.12 christos return;
515 1.12 christos }
516 1.12 christos }
517 1.12 christos
518 1.9 mlelstv options->identity_file_userprovided[options->num_identity_files] =
519 1.9 mlelstv userprovided;
520 1.9 mlelstv options->identity_files[options->num_identity_files++] = path;
521 1.9 mlelstv }
522 1.9 mlelstv
523 1.12 christos int
524 1.12 christos default_ssh_port(void)
525 1.12 christos {
526 1.12 christos static int port;
527 1.12 christos struct servent *sp;
528 1.12 christos
529 1.12 christos if (port == 0) {
530 1.12 christos sp = getservbyname(SSH_SERVICE_NAME, "tcp");
531 1.12 christos port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
532 1.12 christos }
533 1.12 christos return port;
534 1.12 christos }
535 1.12 christos
536 1.12 christos /*
537 1.12 christos * Execute a command in a shell.
538 1.12 christos * Return its exit status or -1 on abnormal exit.
539 1.12 christos */
540 1.12 christos static int
541 1.12 christos execute_in_shell(const char *cmd)
542 1.12 christos {
543 1.12 christos const char *shell;
544 1.12 christos pid_t pid;
545 1.12 christos int devnull, status;
546 1.12 christos
547 1.12 christos if ((shell = getenv("SHELL")) == NULL)
548 1.12 christos shell = _PATH_BSHELL;
549 1.12 christos
550 1.28 christos if (access(shell, X_OK) == -1) {
551 1.28 christos fatal("Shell \"%s\" is not executable: %s",
552 1.28 christos shell, strerror(errno));
553 1.28 christos }
554 1.28 christos
555 1.12 christos /* Need this to redirect subprocess stdin/out */
556 1.12 christos if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
557 1.12 christos fatal("open(/dev/null): %s", strerror(errno));
558 1.12 christos
559 1.12 christos debug("Executing command: '%.500s'", cmd);
560 1.12 christos
561 1.12 christos /* Fork and execute the command. */
562 1.12 christos if ((pid = fork()) == 0) {
563 1.12 christos char *argv[4];
564 1.12 christos
565 1.12 christos /* Redirect child stdin and stdout. Leave stderr */
566 1.12 christos if (dup2(devnull, STDIN_FILENO) == -1)
567 1.12 christos fatal("dup2: %s", strerror(errno));
568 1.12 christos if (dup2(devnull, STDOUT_FILENO) == -1)
569 1.12 christos fatal("dup2: %s", strerror(errno));
570 1.12 christos if (devnull > STDERR_FILENO)
571 1.12 christos close(devnull);
572 1.15 christos if (closefrom(STDERR_FILENO + 1) == -1)
573 1.15 christos fatal("closefrom: %s", strerror(errno));
574 1.12 christos
575 1.12 christos argv[0] = __UNCONST(shell);
576 1.12 christos argv[1] = __UNCONST("-c");
577 1.18 christos argv[2] = xstrdup(cmd);
578 1.12 christos argv[3] = NULL;
579 1.12 christos
580 1.12 christos execv(argv[0], argv);
581 1.12 christos error("Unable to execute '%.100s': %s", cmd, strerror(errno));
582 1.12 christos /* Die with signal to make this error apparent to parent. */
583 1.29 christos ssh_signal(SIGTERM, SIG_DFL);
584 1.12 christos kill(getpid(), SIGTERM);
585 1.12 christos _exit(1);
586 1.12 christos }
587 1.12 christos /* Parent. */
588 1.28 christos if (pid == -1)
589 1.12 christos fatal("%s: fork: %.100s", __func__, strerror(errno));
590 1.12 christos
591 1.12 christos close(devnull);
592 1.12 christos
593 1.12 christos while (waitpid(pid, &status, 0) == -1) {
594 1.12 christos if (errno != EINTR && errno != EAGAIN)
595 1.12 christos fatal("%s: waitpid: %s", __func__, strerror(errno));
596 1.12 christos }
597 1.12 christos if (!WIFEXITED(status)) {
598 1.12 christos error("command '%.100s' exited abnormally", cmd);
599 1.12 christos return -1;
600 1.13 christos }
601 1.12 christos debug3("command returned status %d", WEXITSTATUS(status));
602 1.12 christos return WEXITSTATUS(status);
603 1.12 christos }
604 1.12 christos
605 1.12 christos /*
606 1.12 christos * Parse and execute a Match directive.
607 1.12 christos */
608 1.12 christos static int
609 1.12 christos match_cfg_line(Options *options, char **condition, struct passwd *pw,
610 1.27 christos const char *host_arg, const char *original_host, int final_pass,
611 1.27 christos int *want_final_pass, const char *filename, int linenum)
612 1.12 christos {
613 1.13 christos char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
614 1.12 christos const char *ruser;
615 1.13 christos int r, port, this_result, result = 1, attributes = 0, negate;
616 1.12 christos char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
617 1.25 christos char uidstr[32];
618 1.12 christos
619 1.12 christos /*
620 1.12 christos * Configuration is likely to be incomplete at this point so we
621 1.12 christos * must be prepared to use default values.
622 1.12 christos */
623 1.12 christos port = options->port <= 0 ? default_ssh_port() : options->port;
624 1.12 christos ruser = options->user == NULL ? pw->pw_name : options->user;
625 1.27 christos if (final_pass) {
626 1.18 christos host = xstrdup(options->hostname);
627 1.18 christos } else if (options->hostname != NULL) {
628 1.12 christos /* NB. Please keep in sync with ssh.c:main() */
629 1.12 christos host = percent_expand(options->hostname,
630 1.12 christos "h", host_arg, (char *)NULL);
631 1.18 christos } else {
632 1.12 christos host = xstrdup(host_arg);
633 1.18 christos }
634 1.12 christos
635 1.13 christos debug2("checking match for '%s' host %s originally %s",
636 1.13 christos cp, host, original_host);
637 1.13 christos while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
638 1.13 christos criteria = NULL;
639 1.13 christos this_result = 1;
640 1.13 christos if ((negate = attrib[0] == '!'))
641 1.13 christos attrib++;
642 1.13 christos /* criteria "all" and "canonical" have no argument */
643 1.12 christos if (strcasecmp(attrib, "all") == 0) {
644 1.13 christos if (attributes > 1 ||
645 1.12 christos ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
646 1.13 christos error("%.200s line %d: '%s' cannot be combined "
647 1.13 christos "with other Match attributes",
648 1.13 christos filename, linenum, oattrib);
649 1.12 christos result = -1;
650 1.12 christos goto out;
651 1.12 christos }
652 1.13 christos if (result)
653 1.13 christos result = negate ? 0 : 1;
654 1.12 christos goto out;
655 1.12 christos }
656 1.13 christos attributes++;
657 1.27 christos if (strcasecmp(attrib, "canonical") == 0 ||
658 1.27 christos strcasecmp(attrib, "final") == 0) {
659 1.27 christos /*
660 1.27 christos * If the config requests "Match final" then remember
661 1.27 christos * this so we can perform a second pass later.
662 1.27 christos */
663 1.27 christos if (strcasecmp(attrib, "final") == 0 &&
664 1.27 christos want_final_pass != NULL)
665 1.27 christos *want_final_pass = 1;
666 1.27 christos r = !!final_pass; /* force bitmask member to boolean */
667 1.13 christos if (r == (negate ? 1 : 0))
668 1.13 christos this_result = result = 0;
669 1.13 christos debug3("%.200s line %d: %smatched '%s'",
670 1.13 christos filename, linenum,
671 1.13 christos this_result ? "" : "not ", oattrib);
672 1.13 christos continue;
673 1.13 christos }
674 1.13 christos /* All other criteria require an argument */
675 1.12 christos if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
676 1.12 christos error("Missing Match criteria for %s", attrib);
677 1.12 christos result = -1;
678 1.12 christos goto out;
679 1.12 christos }
680 1.12 christos if (strcasecmp(attrib, "host") == 0) {
681 1.13 christos criteria = xstrdup(host);
682 1.14 christos r = match_hostname(host, arg) == 1;
683 1.13 christos if (r == (negate ? 1 : 0))
684 1.13 christos this_result = result = 0;
685 1.12 christos } else if (strcasecmp(attrib, "originalhost") == 0) {
686 1.13 christos criteria = xstrdup(original_host);
687 1.14 christos r = match_hostname(original_host, arg) == 1;
688 1.13 christos if (r == (negate ? 1 : 0))
689 1.13 christos this_result = result = 0;
690 1.12 christos } else if (strcasecmp(attrib, "user") == 0) {
691 1.13 christos criteria = xstrdup(ruser);
692 1.14 christos r = match_pattern_list(ruser, arg, 0) == 1;
693 1.13 christos if (r == (negate ? 1 : 0))
694 1.13 christos this_result = result = 0;
695 1.12 christos } else if (strcasecmp(attrib, "localuser") == 0) {
696 1.13 christos criteria = xstrdup(pw->pw_name);
697 1.14 christos r = match_pattern_list(pw->pw_name, arg, 0) == 1;
698 1.13 christos if (r == (negate ? 1 : 0))
699 1.13 christos this_result = result = 0;
700 1.12 christos } else if (strcasecmp(attrib, "exec") == 0) {
701 1.31 christos char *conn_hash_hex;
702 1.31 christos
703 1.12 christos if (gethostname(thishost, sizeof(thishost)) == -1)
704 1.12 christos fatal("gethostname: %s", strerror(errno));
705 1.12 christos strlcpy(shorthost, thishost, sizeof(shorthost));
706 1.12 christos shorthost[strcspn(thishost, ".")] = '\0';
707 1.12 christos snprintf(portstr, sizeof(portstr), "%d", port);
708 1.25 christos snprintf(uidstr, sizeof(uidstr), "%llu",
709 1.25 christos (unsigned long long)pw->pw_uid);
710 1.31 christos conn_hash_hex = ssh_connection_hash(thishost, host,
711 1.31 christos portstr, ruser);
712 1.12 christos
713 1.12 christos cmd = percent_expand(arg,
714 1.31 christos "C", conn_hash_hex,
715 1.12 christos "L", shorthost,
716 1.12 christos "d", pw->pw_dir,
717 1.12 christos "h", host,
718 1.12 christos "l", thishost,
719 1.13 christos "n", original_host,
720 1.12 christos "p", portstr,
721 1.12 christos "r", ruser,
722 1.12 christos "u", pw->pw_name,
723 1.25 christos "i", uidstr,
724 1.12 christos (char *)NULL);
725 1.31 christos free(conn_hash_hex);
726 1.12 christos if (result != 1) {
727 1.12 christos /* skip execution if prior predicate failed */
728 1.13 christos debug3("%.200s line %d: skipped exec "
729 1.13 christos "\"%.100s\"", filename, linenum, cmd);
730 1.13 christos free(cmd);
731 1.13 christos continue;
732 1.13 christos }
733 1.13 christos r = execute_in_shell(cmd);
734 1.13 christos if (r == -1) {
735 1.13 christos fatal("%.200s line %d: match exec "
736 1.13 christos "'%.100s' error", filename,
737 1.13 christos linenum, cmd);
738 1.12 christos }
739 1.13 christos criteria = xstrdup(cmd);
740 1.12 christos free(cmd);
741 1.13 christos /* Force exit status to boolean */
742 1.13 christos r = r == 0;
743 1.13 christos if (r == (negate ? 1 : 0))
744 1.13 christos this_result = result = 0;
745 1.12 christos } else {
746 1.12 christos error("Unsupported Match attribute %s", attrib);
747 1.12 christos result = -1;
748 1.12 christos goto out;
749 1.12 christos }
750 1.13 christos debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
751 1.13 christos filename, linenum, this_result ? "": "not ",
752 1.13 christos oattrib, criteria);
753 1.13 christos free(criteria);
754 1.12 christos }
755 1.12 christos if (attributes == 0) {
756 1.12 christos error("One or more attributes required for Match");
757 1.12 christos result = -1;
758 1.12 christos goto out;
759 1.12 christos }
760 1.13 christos out:
761 1.13 christos if (result != -1)
762 1.13 christos debug2("match %sfound", result ? "" : "not ");
763 1.12 christos *condition = cp;
764 1.12 christos free(host);
765 1.12 christos return result;
766 1.12 christos }
767 1.12 christos
768 1.25 christos /* Remove environment variable by pattern */
769 1.25 christos static void
770 1.25 christos rm_env(Options *options, const char *arg, const char *filename, int linenum)
771 1.25 christos {
772 1.25 christos int i, j;
773 1.25 christos char *cp;
774 1.25 christos
775 1.25 christos /* Remove an environment variable */
776 1.25 christos for (i = 0; i < options->num_send_env; ) {
777 1.25 christos cp = xstrdup(options->send_env[i]);
778 1.25 christos if (!match_pattern(cp, arg + 1)) {
779 1.25 christos free(cp);
780 1.25 christos i++;
781 1.25 christos continue;
782 1.25 christos }
783 1.25 christos debug3("%s line %d: removing environment %s",
784 1.25 christos filename, linenum, cp);
785 1.25 christos free(cp);
786 1.25 christos free(options->send_env[i]);
787 1.25 christos options->send_env[i] = NULL;
788 1.25 christos for (j = i; j < options->num_send_env - 1; j++) {
789 1.25 christos options->send_env[j] = options->send_env[j + 1];
790 1.25 christos options->send_env[j + 1] = NULL;
791 1.25 christos }
792 1.25 christos options->num_send_env--;
793 1.25 christos /* NB. don't increment i */
794 1.25 christos }
795 1.25 christos }
796 1.25 christos
797 1.1 christos /*
798 1.1 christos * Returns the number of the token pointed to by cp or oBadOption.
799 1.1 christos */
800 1.1 christos static OpCodes
801 1.11 christos parse_token(const char *cp, const char *filename, int linenum,
802 1.11 christos const char *ignored_unknown)
803 1.1 christos {
804 1.11 christos int i;
805 1.1 christos
806 1.1 christos for (i = 0; keywords[i].name; i++)
807 1.11 christos if (strcmp(cp, keywords[i].name) == 0)
808 1.1 christos return keywords[i].opcode;
809 1.14 christos if (ignored_unknown != NULL &&
810 1.14 christos match_pattern_list(cp, ignored_unknown, 1) == 1)
811 1.11 christos return oIgnoredUnknownOption;
812 1.1 christos error("%s: line %d: Bad configuration option: %s",
813 1.1 christos filename, linenum, cp);
814 1.1 christos return oBadOption;
815 1.1 christos }
816 1.1 christos
817 1.12 christos /* Multistate option parsing */
818 1.12 christos struct multistate {
819 1.12 christos const char *key;
820 1.12 christos int value;
821 1.12 christos };
822 1.12 christos static const struct multistate multistate_flag[] = {
823 1.12 christos { "true", 1 },
824 1.12 christos { "false", 0 },
825 1.12 christos { "yes", 1 },
826 1.12 christos { "no", 0 },
827 1.12 christos { NULL, -1 }
828 1.12 christos };
829 1.12 christos static const struct multistate multistate_yesnoask[] = {
830 1.12 christos { "true", 1 },
831 1.12 christos { "false", 0 },
832 1.12 christos { "yes", 1 },
833 1.12 christos { "no", 0 },
834 1.12 christos { "ask", 2 },
835 1.12 christos { NULL, -1 }
836 1.12 christos };
837 1.22 christos static const struct multistate multistate_strict_hostkey[] = {
838 1.22 christos { "true", SSH_STRICT_HOSTKEY_YES },
839 1.22 christos { "false", SSH_STRICT_HOSTKEY_OFF },
840 1.22 christos { "yes", SSH_STRICT_HOSTKEY_YES },
841 1.22 christos { "no", SSH_STRICT_HOSTKEY_OFF },
842 1.22 christos { "ask", SSH_STRICT_HOSTKEY_ASK },
843 1.22 christos { "off", SSH_STRICT_HOSTKEY_OFF },
844 1.22 christos { "accept-new", SSH_STRICT_HOSTKEY_NEW },
845 1.22 christos { NULL, -1 }
846 1.22 christos };
847 1.18 christos static const struct multistate multistate_yesnoaskconfirm[] = {
848 1.18 christos { "true", 1 },
849 1.18 christos { "false", 0 },
850 1.18 christos { "yes", 1 },
851 1.18 christos { "no", 0 },
852 1.18 christos { "ask", 2 },
853 1.18 christos { "confirm", 3 },
854 1.18 christos { NULL, -1 }
855 1.18 christos };
856 1.12 christos static const struct multistate multistate_addressfamily[] = {
857 1.12 christos { "inet", AF_INET },
858 1.12 christos { "inet6", AF_INET6 },
859 1.12 christos { "any", AF_UNSPEC },
860 1.12 christos { NULL, -1 }
861 1.12 christos };
862 1.12 christos static const struct multistate multistate_controlmaster[] = {
863 1.12 christos { "true", SSHCTL_MASTER_YES },
864 1.12 christos { "yes", SSHCTL_MASTER_YES },
865 1.12 christos { "false", SSHCTL_MASTER_NO },
866 1.12 christos { "no", SSHCTL_MASTER_NO },
867 1.12 christos { "auto", SSHCTL_MASTER_AUTO },
868 1.12 christos { "ask", SSHCTL_MASTER_ASK },
869 1.12 christos { "autoask", SSHCTL_MASTER_AUTO_ASK },
870 1.12 christos { NULL, -1 }
871 1.12 christos };
872 1.12 christos static const struct multistate multistate_tunnel[] = {
873 1.12 christos { "ethernet", SSH_TUNMODE_ETHERNET },
874 1.12 christos { "point-to-point", SSH_TUNMODE_POINTOPOINT },
875 1.12 christos { "true", SSH_TUNMODE_DEFAULT },
876 1.12 christos { "yes", SSH_TUNMODE_DEFAULT },
877 1.12 christos { "false", SSH_TUNMODE_NO },
878 1.12 christos { "no", SSH_TUNMODE_NO },
879 1.12 christos { NULL, -1 }
880 1.12 christos };
881 1.12 christos static const struct multistate multistate_requesttty[] = {
882 1.12 christos { "true", REQUEST_TTY_YES },
883 1.12 christos { "yes", REQUEST_TTY_YES },
884 1.12 christos { "false", REQUEST_TTY_NO },
885 1.12 christos { "no", REQUEST_TTY_NO },
886 1.12 christos { "force", REQUEST_TTY_FORCE },
887 1.12 christos { "auto", REQUEST_TTY_AUTO },
888 1.12 christos { NULL, -1 }
889 1.12 christos };
890 1.12 christos static const struct multistate multistate_canonicalizehostname[] = {
891 1.12 christos { "true", SSH_CANONICALISE_YES },
892 1.12 christos { "false", SSH_CANONICALISE_NO },
893 1.12 christos { "yes", SSH_CANONICALISE_YES },
894 1.12 christos { "no", SSH_CANONICALISE_NO },
895 1.12 christos { "always", SSH_CANONICALISE_ALWAYS },
896 1.12 christos { NULL, -1 }
897 1.12 christos };
898 1.29 christos static const struct multistate multistate_compression[] = {
899 1.29 christos #ifdef WITH_ZLIB
900 1.29 christos { "yes", COMP_ZLIB },
901 1.29 christos #endif
902 1.29 christos { "no", COMP_NONE },
903 1.29 christos { NULL, -1 }
904 1.29 christos };
905 1.12 christos
906 1.1 christos /*
907 1.1 christos * Processes a single option line as used in the configuration files. This
908 1.1 christos * only sets those values that have not already been set.
909 1.1 christos */
910 1.1 christos int
911 1.12 christos process_config_line(Options *options, struct passwd *pw, const char *host,
912 1.13 christos const char *original_host, char *line, const char *filename,
913 1.13 christos int linenum, int *activep, int flags)
914 1.1 christos {
915 1.19 christos return process_config_line_depth(options, pw, host, original_host,
916 1.27 christos line, filename, linenum, activep, flags, NULL, 0);
917 1.19 christos }
918 1.19 christos
919 1.19 christos #define WHITESPACE " \t\r\n"
920 1.19 christos static int
921 1.19 christos process_config_line_depth(Options *options, struct passwd *pw, const char *host,
922 1.19 christos const char *original_host, char *line, const char *filename,
923 1.27 christos int linenum, int *activep, int flags, int *want_final_pass, int depth)
924 1.19 christos {
925 1.6 christos char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
926 1.6 christos char **cpptr, fwdarg[256];
927 1.11 christos u_int i, *uintptr, max_entries = 0;
928 1.19 christos int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
929 1.22 christos int remotefwd, dynamicfwd;
930 1.1 christos LogLevel *log_level_ptr;
931 1.22 christos SyslogFacility *log_facility_ptr;
932 1.11 christos long long val64;
933 1.1 christos size_t len;
934 1.12 christos struct Forward fwd;
935 1.12 christos const struct multistate *multistate_ptr;
936 1.12 christos struct allowed_cname *cname;
937 1.19 christos glob_t gl;
938 1.23 christos const char *errstr;
939 1.12 christos
940 1.12 christos if (activep == NULL) { /* We are processing a command line directive */
941 1.12 christos cmdline = 1;
942 1.12 christos activep = &cmdline;
943 1.12 christos }
944 1.1 christos
945 1.21 christos /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
946 1.14 christos if ((len = strlen(line)) == 0)
947 1.14 christos return 0;
948 1.14 christos for (len--; len > 0; len--) {
949 1.21 christos if (strchr(WHITESPACE "\f", line[len]) == NULL)
950 1.1 christos break;
951 1.1 christos line[len] = '\0';
952 1.1 christos }
953 1.1 christos
954 1.1 christos s = line;
955 1.1 christos /* Get the keyword. (Each line is supposed to begin with a keyword). */
956 1.1 christos if ((keyword = strdelim(&s)) == NULL)
957 1.1 christos return 0;
958 1.1 christos /* Ignore leading whitespace. */
959 1.1 christos if (*keyword == '\0')
960 1.1 christos keyword = strdelim(&s);
961 1.1 christos if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
962 1.1 christos return 0;
963 1.11 christos /* Match lowercase keyword */
964 1.12 christos lowercase(keyword);
965 1.1 christos
966 1.11 christos opcode = parse_token(keyword, filename, linenum,
967 1.11 christos options->ignored_unknown);
968 1.1 christos
969 1.1 christos switch (opcode) {
970 1.1 christos case oBadOption:
971 1.1 christos /* don't panic, but count bad options */
972 1.1 christos return -1;
973 1.22 christos case oIgnore:
974 1.22 christos return 0;
975 1.11 christos case oIgnoredUnknownOption:
976 1.11 christos debug("%s line %d: Ignored unknown option \"%s\"",
977 1.11 christos filename, linenum, keyword);
978 1.11 christos return 0;
979 1.1 christos case oConnectTimeout:
980 1.1 christos intptr = &options->connection_timeout;
981 1.1 christos parse_time:
982 1.1 christos arg = strdelim(&s);
983 1.1 christos if (!arg || *arg == '\0')
984 1.1 christos fatal("%s line %d: missing time value.",
985 1.1 christos filename, linenum);
986 1.13 christos if (strcmp(arg, "none") == 0)
987 1.13 christos value = -1;
988 1.13 christos else if ((value = convtime(arg)) == -1)
989 1.1 christos fatal("%s line %d: invalid time value.",
990 1.1 christos filename, linenum);
991 1.1 christos if (*activep && *intptr == -1)
992 1.1 christos *intptr = value;
993 1.1 christos break;
994 1.1 christos
995 1.1 christos case oForwardAgent:
996 1.1 christos intptr = &options->forward_agent;
997 1.29 christos
998 1.29 christos arg = strdelim(&s);
999 1.29 christos if (!arg || *arg == '\0')
1000 1.29 christos fatal("%s line %d: missing argument.",
1001 1.29 christos filename, linenum);
1002 1.29 christos
1003 1.29 christos value = -1;
1004 1.29 christos multistate_ptr = multistate_flag;
1005 1.29 christos for (i = 0; multistate_ptr[i].key != NULL; i++) {
1006 1.29 christos if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1007 1.29 christos value = multistate_ptr[i].value;
1008 1.29 christos break;
1009 1.29 christos }
1010 1.29 christos }
1011 1.29 christos if (value != -1) {
1012 1.29 christos if (*activep && *intptr == -1)
1013 1.29 christos *intptr = value;
1014 1.29 christos break;
1015 1.29 christos }
1016 1.29 christos /* ForwardAgent wasn't 'yes' or 'no', assume a path */
1017 1.29 christos if (*activep && *intptr == -1)
1018 1.29 christos *intptr = 1;
1019 1.29 christos
1020 1.29 christos charptr = &options->forward_agent_sock_path;
1021 1.29 christos goto parse_agent_path;
1022 1.29 christos
1023 1.29 christos case oForwardX11:
1024 1.29 christos intptr = &options->forward_x11;
1025 1.12 christos parse_flag:
1026 1.12 christos multistate_ptr = multistate_flag;
1027 1.12 christos parse_multistate:
1028 1.1 christos arg = strdelim(&s);
1029 1.1 christos if (!arg || *arg == '\0')
1030 1.12 christos fatal("%s line %d: missing argument.",
1031 1.12 christos filename, linenum);
1032 1.12 christos value = -1;
1033 1.12 christos for (i = 0; multistate_ptr[i].key != NULL; i++) {
1034 1.12 christos if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1035 1.12 christos value = multistate_ptr[i].value;
1036 1.12 christos break;
1037 1.12 christos }
1038 1.12 christos }
1039 1.12 christos if (value == -1)
1040 1.12 christos fatal("%s line %d: unsupported option \"%s\".",
1041 1.12 christos filename, linenum, arg);
1042 1.1 christos if (*activep && *intptr == -1)
1043 1.1 christos *intptr = value;
1044 1.1 christos break;
1045 1.1 christos
1046 1.1 christos case oForwardX11Trusted:
1047 1.1 christos intptr = &options->forward_x11_trusted;
1048 1.1 christos goto parse_flag;
1049 1.13 christos
1050 1.4 adam case oForwardX11Timeout:
1051 1.4 adam intptr = &options->forward_x11_timeout;
1052 1.4 adam goto parse_time;
1053 1.1 christos
1054 1.1 christos case oGatewayPorts:
1055 1.12 christos intptr = &options->fwd_opts.gateway_ports;
1056 1.1 christos goto parse_flag;
1057 1.1 christos
1058 1.1 christos case oExitOnForwardFailure:
1059 1.1 christos intptr = &options->exit_on_forward_failure;
1060 1.1 christos goto parse_flag;
1061 1.1 christos
1062 1.1 christos case oPasswordAuthentication:
1063 1.1 christos intptr = &options->password_authentication;
1064 1.1 christos goto parse_flag;
1065 1.1 christos
1066 1.1 christos case oKbdInteractiveAuthentication:
1067 1.1 christos intptr = &options->kbd_interactive_authentication;
1068 1.1 christos goto parse_flag;
1069 1.1 christos
1070 1.1 christos case oKbdInteractiveDevices:
1071 1.1 christos charptr = &options->kbd_interactive_devices;
1072 1.1 christos goto parse_string;
1073 1.1 christos
1074 1.1 christos case oPubkeyAuthentication:
1075 1.1 christos intptr = &options->pubkey_authentication;
1076 1.1 christos goto parse_flag;
1077 1.1 christos
1078 1.1 christos case oHostbasedAuthentication:
1079 1.1 christos intptr = &options->hostbased_authentication;
1080 1.1 christos goto parse_flag;
1081 1.1 christos
1082 1.1 christos case oChallengeResponseAuthentication:
1083 1.1 christos intptr = &options->challenge_response_authentication;
1084 1.1 christos goto parse_flag;
1085 1.1 christos
1086 1.2 christos #if defined(KRB4) || defined(KRB5)
1087 1.2 christos case oKerberosAuthentication:
1088 1.2 christos intptr = &options->kerberos_authentication;
1089 1.2 christos goto parse_flag;
1090 1.2 christos #endif
1091 1.2 christos #if defined(AFS) || defined(KRB5)
1092 1.2 christos case oKerberosTgtPassing:
1093 1.2 christos intptr = &options->kerberos_tgt_passing;
1094 1.2 christos goto parse_flag;
1095 1.2 christos #endif
1096 1.2 christos
1097 1.1 christos case oGssAuthentication:
1098 1.1 christos intptr = &options->gss_authentication;
1099 1.1 christos goto parse_flag;
1100 1.1 christos
1101 1.2 christos #ifdef AFS
1102 1.2 christos case oAFSTokenPassing:
1103 1.2 christos intptr = &options->afs_token_passing;
1104 1.2 christos goto parse_flag;
1105 1.2 christos #endif
1106 1.2 christos
1107 1.1 christos case oGssDelegateCreds:
1108 1.1 christos intptr = &options->gss_deleg_creds;
1109 1.1 christos goto parse_flag;
1110 1.1 christos
1111 1.1 christos case oBatchMode:
1112 1.1 christos intptr = &options->batch_mode;
1113 1.1 christos goto parse_flag;
1114 1.1 christos
1115 1.1 christos case oCheckHostIP:
1116 1.1 christos intptr = &options->check_host_ip;
1117 1.1 christos goto parse_flag;
1118 1.1 christos
1119 1.2 christos case oNoneEnabled:
1120 1.2 christos intptr = &options->none_enabled;
1121 1.2 christos goto parse_flag;
1122 1.2 christos
1123 1.2 christos /* we check to see if the command comes from the */
1124 1.2 christos /* command line or not. If it does then enable it */
1125 1.2 christos /* otherwise fail. NONE should never be a default configuration */
1126 1.2 christos case oNoneSwitch:
1127 1.2 christos if(strcmp(filename,"command-line")==0)
1128 1.2 christos {
1129 1.2 christos intptr = &options->none_switch;
1130 1.2 christos goto parse_flag;
1131 1.2 christos } else {
1132 1.2 christos error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
1133 1.2 christos error("Continuing...");
1134 1.2 christos debug("NoneSwitch directive found in %.200s.", filename);
1135 1.2 christos return 0;
1136 1.2 christos }
1137 1.2 christos
1138 1.2 christos case oHPNDisabled:
1139 1.2 christos intptr = &options->hpn_disabled;
1140 1.2 christos goto parse_flag;
1141 1.2 christos
1142 1.2 christos case oHPNBufferSize:
1143 1.2 christos intptr = &options->hpn_buffer_size;
1144 1.2 christos goto parse_int;
1145 1.2 christos
1146 1.2 christos case oTcpRcvBufPoll:
1147 1.2 christos intptr = &options->tcp_rcv_buf_poll;
1148 1.2 christos goto parse_flag;
1149 1.2 christos
1150 1.1 christos case oVerifyHostKeyDNS:
1151 1.1 christos intptr = &options->verify_host_key_dns;
1152 1.12 christos multistate_ptr = multistate_yesnoask;
1153 1.12 christos goto parse_multistate;
1154 1.1 christos
1155 1.1 christos case oStrictHostKeyChecking:
1156 1.1 christos intptr = &options->strict_host_key_checking;
1157 1.22 christos multistate_ptr = multistate_strict_hostkey;
1158 1.12 christos goto parse_multistate;
1159 1.1 christos
1160 1.1 christos case oCompression:
1161 1.1 christos intptr = &options->compression;
1162 1.29 christos multistate_ptr = multistate_compression;
1163 1.29 christos goto parse_multistate;
1164 1.1 christos
1165 1.1 christos case oTCPKeepAlive:
1166 1.1 christos intptr = &options->tcp_keep_alive;
1167 1.1 christos goto parse_flag;
1168 1.1 christos
1169 1.1 christos case oNoHostAuthenticationForLocalhost:
1170 1.1 christos intptr = &options->no_host_authentication_for_localhost;
1171 1.1 christos goto parse_flag;
1172 1.1 christos
1173 1.1 christos case oNumberOfPasswordPrompts:
1174 1.1 christos intptr = &options->number_of_password_prompts;
1175 1.1 christos goto parse_int;
1176 1.1 christos
1177 1.1 christos case oRekeyLimit:
1178 1.1 christos arg = strdelim(&s);
1179 1.1 christos if (!arg || *arg == '\0')
1180 1.11 christos fatal("%.200s line %d: Missing argument.", filename,
1181 1.11 christos linenum);
1182 1.11 christos if (strcmp(arg, "default") == 0) {
1183 1.11 christos val64 = 0;
1184 1.11 christos } else {
1185 1.11 christos if (scan_scaled(arg, &val64) == -1)
1186 1.11 christos fatal("%.200s line %d: Bad number '%s': %s",
1187 1.11 christos filename, linenum, arg, strerror(errno));
1188 1.11 christos if (val64 != 0 && val64 < 16)
1189 1.11 christos fatal("%.200s line %d: RekeyLimit too small",
1190 1.11 christos filename, linenum);
1191 1.1 christos }
1192 1.1 christos if (*activep && options->rekey_limit == -1)
1193 1.18 christos options->rekey_limit = val64;
1194 1.11 christos if (s != NULL) { /* optional rekey interval present */
1195 1.11 christos if (strcmp(s, "none") == 0) {
1196 1.11 christos (void)strdelim(&s); /* discard */
1197 1.11 christos break;
1198 1.11 christos }
1199 1.11 christos intptr = &options->rekey_interval;
1200 1.11 christos goto parse_time;
1201 1.11 christos }
1202 1.1 christos break;
1203 1.1 christos
1204 1.1 christos case oIdentityFile:
1205 1.1 christos arg = strdelim(&s);
1206 1.1 christos if (!arg || *arg == '\0')
1207 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1208 1.1 christos if (*activep) {
1209 1.1 christos intptr = &options->num_identity_files;
1210 1.1 christos if (*intptr >= SSH_MAX_IDENTITY_FILES)
1211 1.1 christos fatal("%.200s line %d: Too many identity files specified (max %d).",
1212 1.1 christos filename, linenum, SSH_MAX_IDENTITY_FILES);
1213 1.13 christos add_identity_file(options, NULL,
1214 1.13 christos arg, flags & SSHCONF_USERCONF);
1215 1.1 christos }
1216 1.1 christos break;
1217 1.1 christos
1218 1.18 christos case oCertificateFile:
1219 1.18 christos arg = strdelim(&s);
1220 1.18 christos if (!arg || *arg == '\0')
1221 1.18 christos fatal("%.200s line %d: Missing argument.",
1222 1.18 christos filename, linenum);
1223 1.18 christos if (*activep) {
1224 1.18 christos intptr = &options->num_certificate_files;
1225 1.18 christos if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1226 1.18 christos fatal("%.200s line %d: Too many certificate "
1227 1.18 christos "files specified (max %d).",
1228 1.18 christos filename, linenum,
1229 1.18 christos SSH_MAX_CERTIFICATE_FILES);
1230 1.18 christos }
1231 1.18 christos add_certificate_file(options, arg,
1232 1.18 christos flags & SSHCONF_USERCONF);
1233 1.18 christos }
1234 1.18 christos break;
1235 1.18 christos
1236 1.1 christos case oXAuthLocation:
1237 1.1 christos charptr=&options->xauth_location;
1238 1.1 christos goto parse_string;
1239 1.1 christos
1240 1.1 christos case oUser:
1241 1.1 christos charptr = &options->user;
1242 1.1 christos parse_string:
1243 1.1 christos arg = strdelim(&s);
1244 1.1 christos if (!arg || *arg == '\0')
1245 1.6 christos fatal("%.200s line %d: Missing argument.",
1246 1.6 christos filename, linenum);
1247 1.1 christos if (*activep && *charptr == NULL)
1248 1.1 christos *charptr = xstrdup(arg);
1249 1.1 christos break;
1250 1.1 christos
1251 1.1 christos case oGlobalKnownHostsFile:
1252 1.6 christos cpptr = (char **)&options->system_hostfiles;
1253 1.6 christos uintptr = &options->num_system_hostfiles;
1254 1.6 christos max_entries = SSH_MAX_HOSTS_FILES;
1255 1.6 christos parse_char_array:
1256 1.6 christos if (*activep && *uintptr == 0) {
1257 1.6 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1258 1.6 christos if ((*uintptr) >= max_entries)
1259 1.6 christos fatal("%s line %d: "
1260 1.31 christos "too many known hosts files.",
1261 1.6 christos filename, linenum);
1262 1.6 christos cpptr[(*uintptr)++] = xstrdup(arg);
1263 1.6 christos }
1264 1.6 christos }
1265 1.6 christos return 0;
1266 1.1 christos
1267 1.1 christos case oUserKnownHostsFile:
1268 1.6 christos cpptr = (char **)&options->user_hostfiles;
1269 1.6 christos uintptr = &options->num_user_hostfiles;
1270 1.6 christos max_entries = SSH_MAX_HOSTS_FILES;
1271 1.6 christos goto parse_char_array;
1272 1.1 christos
1273 1.28 christos case oHostname:
1274 1.1 christos charptr = &options->hostname;
1275 1.1 christos goto parse_string;
1276 1.1 christos
1277 1.1 christos case oHostKeyAlias:
1278 1.1 christos charptr = &options->host_key_alias;
1279 1.1 christos goto parse_string;
1280 1.1 christos
1281 1.1 christos case oPreferredAuthentications:
1282 1.1 christos charptr = &options->preferred_authentications;
1283 1.1 christos goto parse_string;
1284 1.1 christos
1285 1.1 christos case oBindAddress:
1286 1.1 christos charptr = &options->bind_address;
1287 1.1 christos goto parse_string;
1288 1.1 christos
1289 1.23 christos case oBindInterface:
1290 1.23 christos charptr = &options->bind_interface;
1291 1.23 christos goto parse_string;
1292 1.23 christos
1293 1.4 adam case oPKCS11Provider:
1294 1.4 adam charptr = &options->pkcs11_provider;
1295 1.1 christos goto parse_string;
1296 1.1 christos
1297 1.29 christos case oSecurityKeyProvider:
1298 1.29 christos charptr = &options->sk_provider;
1299 1.29 christos goto parse_string;
1300 1.29 christos
1301 1.1 christos case oProxyCommand:
1302 1.1 christos charptr = &options->proxy_command;
1303 1.19 christos /* Ignore ProxyCommand if ProxyJump already specified */
1304 1.19 christos if (options->jump_host != NULL)
1305 1.19 christos charptr = &options->jump_host; /* Skip below */
1306 1.1 christos parse_command:
1307 1.1 christos if (s == NULL)
1308 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1309 1.1 christos len = strspn(s, WHITESPACE "=");
1310 1.1 christos if (*activep && *charptr == NULL)
1311 1.1 christos *charptr = xstrdup(s + len);
1312 1.1 christos return 0;
1313 1.1 christos
1314 1.19 christos case oProxyJump:
1315 1.19 christos if (s == NULL) {
1316 1.19 christos fatal("%.200s line %d: Missing argument.",
1317 1.19 christos filename, linenum);
1318 1.19 christos }
1319 1.19 christos len = strspn(s, WHITESPACE "=");
1320 1.19 christos if (parse_jump(s + len, options, *activep) == -1) {
1321 1.19 christos fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1322 1.19 christos filename, linenum, s + len);
1323 1.19 christos }
1324 1.19 christos return 0;
1325 1.19 christos
1326 1.1 christos case oPort:
1327 1.27 christos arg = strdelim(&s);
1328 1.27 christos if (!arg || *arg == '\0')
1329 1.27 christos fatal("%.200s line %d: Missing argument.",
1330 1.27 christos filename, linenum);
1331 1.27 christos value = a2port(arg);
1332 1.27 christos if (value <= 0)
1333 1.27 christos fatal("%.200s line %d: Bad port '%s'.",
1334 1.27 christos filename, linenum, arg);
1335 1.27 christos if (*activep && options->port == -1)
1336 1.27 christos options->port = value;
1337 1.27 christos break;
1338 1.27 christos
1339 1.27 christos case oConnectionAttempts:
1340 1.27 christos intptr = &options->connection_attempts;
1341 1.1 christos parse_int:
1342 1.1 christos arg = strdelim(&s);
1343 1.23 christos if ((errstr = atoi_err(arg, &value)) != NULL)
1344 1.23 christos fatal("%s line %d: integer value %s.",
1345 1.23 christos filename, linenum, errstr);
1346 1.1 christos if (*activep && *intptr == -1)
1347 1.1 christos *intptr = value;
1348 1.1 christos break;
1349 1.1 christos
1350 1.2 christos case oTcpRcvBuf:
1351 1.2 christos intptr = &options->tcp_rcv_buf;
1352 1.2 christos goto parse_int;
1353 1.2 christos
1354 1.1 christos case oCiphers:
1355 1.1 christos arg = strdelim(&s);
1356 1.1 christos if (!arg || *arg == '\0')
1357 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1358 1.28 christos if (*arg != '-' &&
1359 1.28 christos !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1360 1.1 christos fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1361 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1362 1.1 christos if (*activep && options->ciphers == NULL)
1363 1.1 christos options->ciphers = xstrdup(arg);
1364 1.1 christos break;
1365 1.1 christos
1366 1.1 christos case oMacs:
1367 1.1 christos arg = strdelim(&s);
1368 1.1 christos if (!arg || *arg == '\0')
1369 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1370 1.28 christos if (*arg != '-' &&
1371 1.28 christos !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1372 1.28 christos fatal("%.200s line %d: Bad SSH2 MAC spec '%s'.",
1373 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1374 1.1 christos if (*activep && options->macs == NULL)
1375 1.1 christos options->macs = xstrdup(arg);
1376 1.1 christos break;
1377 1.1 christos
1378 1.5 christos case oKexAlgorithms:
1379 1.5 christos arg = strdelim(&s);
1380 1.5 christos if (!arg || *arg == '\0')
1381 1.5 christos fatal("%.200s line %d: Missing argument.",
1382 1.5 christos filename, linenum);
1383 1.21 christos if (*arg != '-' &&
1384 1.28 christos !kex_names_valid(*arg == '+' || *arg == '^' ?
1385 1.28 christos arg + 1 : arg))
1386 1.5 christos fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1387 1.5 christos filename, linenum, arg ? arg : "<NONE>");
1388 1.5 christos if (*activep && options->kex_algorithms == NULL)
1389 1.5 christos options->kex_algorithms = xstrdup(arg);
1390 1.5 christos break;
1391 1.5 christos
1392 1.1 christos case oHostKeyAlgorithms:
1393 1.16 christos charptr = &options->hostkeyalgorithms;
1394 1.16 christos parse_keytypes:
1395 1.1 christos arg = strdelim(&s);
1396 1.1 christos if (!arg || *arg == '\0')
1397 1.16 christos fatal("%.200s line %d: Missing argument.",
1398 1.16 christos filename, linenum);
1399 1.21 christos if (*arg != '-' &&
1400 1.28 christos !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1401 1.28 christos arg + 1 : arg, 1))
1402 1.16 christos fatal("%s line %d: Bad key types '%s'.",
1403 1.16 christos filename, linenum, arg ? arg : "<NONE>");
1404 1.16 christos if (*activep && *charptr == NULL)
1405 1.16 christos *charptr = xstrdup(arg);
1406 1.1 christos break;
1407 1.1 christos
1408 1.27 christos case oCASignatureAlgorithms:
1409 1.27 christos charptr = &options->ca_sign_algorithms;
1410 1.27 christos goto parse_keytypes;
1411 1.27 christos
1412 1.1 christos case oLogLevel:
1413 1.1 christos log_level_ptr = &options->log_level;
1414 1.1 christos arg = strdelim(&s);
1415 1.1 christos value = log_level_number(arg);
1416 1.1 christos if (value == SYSLOG_LEVEL_NOT_SET)
1417 1.1 christos fatal("%.200s line %d: unsupported log level '%s'",
1418 1.1 christos filename, linenum, arg ? arg : "<NONE>");
1419 1.1 christos if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1420 1.1 christos *log_level_ptr = (LogLevel) value;
1421 1.1 christos break;
1422 1.1 christos
1423 1.22 christos case oLogFacility:
1424 1.22 christos log_facility_ptr = &options->log_facility;
1425 1.22 christos arg = strdelim(&s);
1426 1.22 christos value = log_facility_number(arg);
1427 1.22 christos if (value == SYSLOG_FACILITY_NOT_SET)
1428 1.22 christos fatal("%.200s line %d: unsupported log facility '%s'",
1429 1.22 christos filename, linenum, arg ? arg : "<NONE>");
1430 1.22 christos if (*log_facility_ptr == -1)
1431 1.22 christos *log_facility_ptr = (SyslogFacility) value;
1432 1.22 christos break;
1433 1.22 christos
1434 1.1 christos case oLocalForward:
1435 1.1 christos case oRemoteForward:
1436 1.1 christos case oDynamicForward:
1437 1.1 christos arg = strdelim(&s);
1438 1.1 christos if (arg == NULL || *arg == '\0')
1439 1.1 christos fatal("%.200s line %d: Missing port argument.",
1440 1.1 christos filename, linenum);
1441 1.1 christos
1442 1.22 christos remotefwd = (opcode == oRemoteForward);
1443 1.22 christos dynamicfwd = (opcode == oDynamicForward);
1444 1.22 christos
1445 1.22 christos if (!dynamicfwd) {
1446 1.1 christos arg2 = strdelim(&s);
1447 1.22 christos if (arg2 == NULL || *arg2 == '\0') {
1448 1.22 christos if (remotefwd)
1449 1.22 christos dynamicfwd = 1;
1450 1.22 christos else
1451 1.22 christos fatal("%.200s line %d: Missing target "
1452 1.22 christos "argument.", filename, linenum);
1453 1.22 christos } else {
1454 1.22 christos /* construct a string for parse_forward */
1455 1.22 christos snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1456 1.22 christos arg2);
1457 1.22 christos }
1458 1.22 christos }
1459 1.22 christos if (dynamicfwd)
1460 1.1 christos strlcpy(fwdarg, arg, sizeof(fwdarg));
1461 1.1 christos
1462 1.22 christos if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1463 1.1 christos fatal("%.200s line %d: Bad forwarding specification.",
1464 1.1 christos filename, linenum);
1465 1.1 christos
1466 1.1 christos if (*activep) {
1467 1.22 christos if (remotefwd) {
1468 1.22 christos add_remote_forward(options, &fwd);
1469 1.22 christos } else {
1470 1.1 christos add_local_forward(options, &fwd);
1471 1.22 christos }
1472 1.1 christos }
1473 1.1 christos break;
1474 1.1 christos
1475 1.1 christos case oClearAllForwardings:
1476 1.1 christos intptr = &options->clear_forwardings;
1477 1.1 christos goto parse_flag;
1478 1.1 christos
1479 1.1 christos case oHost:
1480 1.12 christos if (cmdline)
1481 1.12 christos fatal("Host directive not supported as a command-line "
1482 1.12 christos "option");
1483 1.1 christos *activep = 0;
1484 1.6 christos arg2 = NULL;
1485 1.6 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1486 1.19 christos if ((flags & SSHCONF_NEVERMATCH) != 0)
1487 1.19 christos break;
1488 1.6 christos negated = *arg == '!';
1489 1.6 christos if (negated)
1490 1.6 christos arg++;
1491 1.1 christos if (match_pattern(host, arg)) {
1492 1.6 christos if (negated) {
1493 1.6 christos debug("%.200s line %d: Skipping Host "
1494 1.6 christos "block because of negated match "
1495 1.6 christos "for %.100s", filename, linenum,
1496 1.6 christos arg);
1497 1.6 christos *activep = 0;
1498 1.6 christos break;
1499 1.6 christos }
1500 1.6 christos if (!*activep)
1501 1.6 christos arg2 = arg; /* logged below */
1502 1.1 christos *activep = 1;
1503 1.1 christos }
1504 1.6 christos }
1505 1.6 christos if (*activep)
1506 1.6 christos debug("%.200s line %d: Applying options for %.100s",
1507 1.6 christos filename, linenum, arg2);
1508 1.1 christos /* Avoid garbage check below, as strdelim is done. */
1509 1.1 christos return 0;
1510 1.1 christos
1511 1.12 christos case oMatch:
1512 1.12 christos if (cmdline)
1513 1.12 christos fatal("Host directive not supported as a command-line "
1514 1.12 christos "option");
1515 1.13 christos value = match_cfg_line(options, &s, pw, host, original_host,
1516 1.27 christos flags & SSHCONF_FINAL, want_final_pass,
1517 1.27 christos filename, linenum);
1518 1.12 christos if (value < 0)
1519 1.12 christos fatal("%.200s line %d: Bad Match condition", filename,
1520 1.12 christos linenum);
1521 1.19 christos *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1522 1.12 christos break;
1523 1.12 christos
1524 1.1 christos case oEscapeChar:
1525 1.1 christos intptr = &options->escape_char;
1526 1.1 christos arg = strdelim(&s);
1527 1.1 christos if (!arg || *arg == '\0')
1528 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1529 1.2 christos value = 0; /* To avoid compiler warning... */
1530 1.14 christos if (strcmp(arg, "none") == 0)
1531 1.14 christos value = SSH_ESCAPECHAR_NONE;
1532 1.14 christos else if (arg[1] == '\0')
1533 1.14 christos value = (u_char) arg[0];
1534 1.14 christos else if (arg[0] == '^' && arg[2] == 0 &&
1535 1.1 christos (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1536 1.1 christos value = (u_char) arg[1] & 31;
1537 1.1 christos else {
1538 1.1 christos fatal("%.200s line %d: Bad escape character.",
1539 1.1 christos filename, linenum);
1540 1.1 christos /* NOTREACHED */
1541 1.1 christos value = 0; /* Avoid compiler warning. */
1542 1.1 christos }
1543 1.1 christos if (*activep && *intptr == -1)
1544 1.1 christos *intptr = value;
1545 1.1 christos break;
1546 1.1 christos
1547 1.1 christos case oAddressFamily:
1548 1.1 christos intptr = &options->address_family;
1549 1.12 christos multistate_ptr = multistate_addressfamily;
1550 1.12 christos goto parse_multistate;
1551 1.1 christos
1552 1.1 christos case oEnableSSHKeysign:
1553 1.1 christos intptr = &options->enable_ssh_keysign;
1554 1.1 christos goto parse_flag;
1555 1.1 christos
1556 1.1 christos case oIdentitiesOnly:
1557 1.1 christos intptr = &options->identities_only;
1558 1.1 christos goto parse_flag;
1559 1.1 christos
1560 1.1 christos case oServerAliveInterval:
1561 1.1 christos intptr = &options->server_alive_interval;
1562 1.1 christos goto parse_time;
1563 1.1 christos
1564 1.1 christos case oServerAliveCountMax:
1565 1.1 christos intptr = &options->server_alive_count_max;
1566 1.1 christos goto parse_int;
1567 1.1 christos
1568 1.1 christos case oSendEnv:
1569 1.1 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1570 1.1 christos if (strchr(arg, '=') != NULL)
1571 1.1 christos fatal("%s line %d: Invalid environment name.",
1572 1.1 christos filename, linenum);
1573 1.1 christos if (!*activep)
1574 1.1 christos continue;
1575 1.25 christos if (*arg == '-') {
1576 1.25 christos /* Removing an env var */
1577 1.25 christos rm_env(options, arg, filename, linenum);
1578 1.25 christos continue;
1579 1.25 christos } else {
1580 1.25 christos /* Adding an env var */
1581 1.25 christos if (options->num_send_env >= INT_MAX)
1582 1.25 christos fatal("%s line %d: too many send env.",
1583 1.25 christos filename, linenum);
1584 1.25 christos options->send_env = xrecallocarray(
1585 1.25 christos options->send_env, options->num_send_env,
1586 1.25 christos options->num_send_env + 1,
1587 1.25 christos sizeof(*options->send_env));
1588 1.25 christos options->send_env[options->num_send_env++] =
1589 1.25 christos xstrdup(arg);
1590 1.25 christos }
1591 1.25 christos }
1592 1.25 christos break;
1593 1.25 christos
1594 1.25 christos case oSetEnv:
1595 1.25 christos value = options->num_setenv;
1596 1.25 christos while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1597 1.25 christos if (strchr(arg, '=') == NULL)
1598 1.25 christos fatal("%s line %d: Invalid SetEnv.",
1599 1.25 christos filename, linenum);
1600 1.25 christos if (!*activep || value != 0)
1601 1.25 christos continue;
1602 1.25 christos /* Adding a setenv var */
1603 1.25 christos if (options->num_setenv >= INT_MAX)
1604 1.25 christos fatal("%s line %d: too many SetEnv.",
1605 1.1 christos filename, linenum);
1606 1.25 christos options->setenv = xrecallocarray(
1607 1.25 christos options->setenv, options->num_setenv,
1608 1.25 christos options->num_setenv + 1, sizeof(*options->setenv));
1609 1.25 christos options->setenv[options->num_setenv++] = xstrdup(arg);
1610 1.1 christos }
1611 1.1 christos break;
1612 1.1 christos
1613 1.1 christos case oControlPath:
1614 1.1 christos charptr = &options->control_path;
1615 1.1 christos goto parse_string;
1616 1.1 christos
1617 1.1 christos case oControlMaster:
1618 1.1 christos intptr = &options->control_master;
1619 1.12 christos multistate_ptr = multistate_controlmaster;
1620 1.12 christos goto parse_multistate;
1621 1.1 christos
1622 1.4 adam case oControlPersist:
1623 1.4 adam /* no/false/yes/true, or a time spec */
1624 1.4 adam intptr = &options->control_persist;
1625 1.4 adam arg = strdelim(&s);
1626 1.4 adam if (!arg || *arg == '\0')
1627 1.4 adam fatal("%.200s line %d: Missing ControlPersist"
1628 1.4 adam " argument.", filename, linenum);
1629 1.4 adam value = 0;
1630 1.4 adam value2 = 0; /* timeout */
1631 1.4 adam if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1632 1.4 adam value = 0;
1633 1.4 adam else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1634 1.4 adam value = 1;
1635 1.4 adam else if ((value2 = convtime(arg)) >= 0)
1636 1.4 adam value = 1;
1637 1.4 adam else
1638 1.4 adam fatal("%.200s line %d: Bad ControlPersist argument.",
1639 1.4 adam filename, linenum);
1640 1.4 adam if (*activep && *intptr == -1) {
1641 1.4 adam *intptr = value;
1642 1.4 adam options->control_persist_timeout = value2;
1643 1.4 adam }
1644 1.4 adam break;
1645 1.4 adam
1646 1.1 christos case oHashKnownHosts:
1647 1.1 christos intptr = &options->hash_known_hosts;
1648 1.1 christos goto parse_flag;
1649 1.1 christos
1650 1.1 christos case oTunnel:
1651 1.1 christos intptr = &options->tun_open;
1652 1.12 christos multistate_ptr = multistate_tunnel;
1653 1.12 christos goto parse_multistate;
1654 1.1 christos
1655 1.1 christos case oTunnelDevice:
1656 1.1 christos arg = strdelim(&s);
1657 1.1 christos if (!arg || *arg == '\0')
1658 1.1 christos fatal("%.200s line %d: Missing argument.", filename, linenum);
1659 1.1 christos value = a2tun(arg, &value2);
1660 1.1 christos if (value == SSH_TUNID_ERR)
1661 1.1 christos fatal("%.200s line %d: Bad tun device.", filename, linenum);
1662 1.1 christos if (*activep) {
1663 1.1 christos options->tun_local = value;
1664 1.1 christos options->tun_remote = value2;
1665 1.1 christos }
1666 1.1 christos break;
1667 1.1 christos
1668 1.1 christos case oLocalCommand:
1669 1.1 christos charptr = &options->local_command;
1670 1.1 christos goto parse_command;
1671 1.1 christos
1672 1.1 christos case oPermitLocalCommand:
1673 1.1 christos intptr = &options->permit_local_command;
1674 1.1 christos goto parse_flag;
1675 1.1 christos
1676 1.22 christos case oRemoteCommand:
1677 1.22 christos charptr = &options->remote_command;
1678 1.22 christos goto parse_command;
1679 1.22 christos
1680 1.1 christos case oVisualHostKey:
1681 1.1 christos intptr = &options->visual_host_key;
1682 1.1 christos goto parse_flag;
1683 1.1 christos
1684 1.19 christos case oInclude:
1685 1.19 christos if (cmdline)
1686 1.19 christos fatal("Include directive not supported as a "
1687 1.19 christos "command-line option");
1688 1.19 christos value = 0;
1689 1.19 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1690 1.19 christos /*
1691 1.19 christos * Ensure all paths are anchored. User configuration
1692 1.19 christos * files may begin with '~/' but system configurations
1693 1.19 christos * must not. If the path is relative, then treat it
1694 1.19 christos * as living in ~/.ssh for user configurations or
1695 1.19 christos * /etc/ssh for system ones.
1696 1.19 christos */
1697 1.19 christos if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1698 1.19 christos fatal("%.200s line %d: bad include path %s.",
1699 1.19 christos filename, linenum, arg);
1700 1.27 christos if (!path_absolute(arg) && *arg != '~') {
1701 1.19 christos xasprintf(&arg2, "%s/%s",
1702 1.19 christos (flags & SSHCONF_USERCONF) ?
1703 1.19 christos "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1704 1.19 christos } else
1705 1.19 christos arg2 = xstrdup(arg);
1706 1.19 christos memset(&gl, 0, sizeof(gl));
1707 1.19 christos r = glob(arg2, GLOB_TILDE | GLOB_LIMIT, NULL, &gl);
1708 1.19 christos if (r == GLOB_NOMATCH) {
1709 1.19 christos debug("%.200s line %d: include %s matched no "
1710 1.19 christos "files",filename, linenum, arg2);
1711 1.21 christos free(arg2);
1712 1.19 christos continue;
1713 1.19 christos } else if (r != 0)
1714 1.19 christos fatal("%.200s line %d: glob failed for %s.",
1715 1.19 christos filename, linenum, arg2);
1716 1.19 christos free(arg2);
1717 1.19 christos oactive = *activep;
1718 1.29 christos for (i = 0; i < gl.gl_pathc; i++) {
1719 1.19 christos debug3("%.200s line %d: Including file %s "
1720 1.19 christos "depth %d%s", filename, linenum,
1721 1.19 christos gl.gl_pathv[i], depth,
1722 1.19 christos oactive ? "" : " (parse only)");
1723 1.19 christos r = read_config_file_depth(gl.gl_pathv[i],
1724 1.19 christos pw, host, original_host, options,
1725 1.19 christos flags | SSHCONF_CHECKPERM |
1726 1.19 christos (oactive ? 0 : SSHCONF_NEVERMATCH),
1727 1.27 christos activep, want_final_pass, depth + 1);
1728 1.21 christos if (r != 1 && errno != ENOENT) {
1729 1.21 christos fatal("Can't open user config file "
1730 1.21 christos "%.100s: %.100s", gl.gl_pathv[i],
1731 1.21 christos strerror(errno));
1732 1.21 christos }
1733 1.19 christos /*
1734 1.19 christos * don't let Match in includes clobber the
1735 1.19 christos * containing file's Match state.
1736 1.19 christos */
1737 1.19 christos *activep = oactive;
1738 1.19 christos if (r != 1)
1739 1.19 christos value = -1;
1740 1.19 christos }
1741 1.19 christos globfree(&gl);
1742 1.19 christos }
1743 1.19 christos if (value != 0)
1744 1.19 christos return value;
1745 1.19 christos break;
1746 1.19 christos
1747 1.5 christos case oIPQoS:
1748 1.5 christos arg = strdelim(&s);
1749 1.5 christos if ((value = parse_ipqos(arg)) == -1)
1750 1.5 christos fatal("%s line %d: Bad IPQoS value: %s",
1751 1.5 christos filename, linenum, arg);
1752 1.5 christos arg = strdelim(&s);
1753 1.5 christos if (arg == NULL)
1754 1.5 christos value2 = value;
1755 1.5 christos else if ((value2 = parse_ipqos(arg)) == -1)
1756 1.5 christos fatal("%s line %d: Bad IPQoS value: %s",
1757 1.5 christos filename, linenum, arg);
1758 1.5 christos if (*activep) {
1759 1.5 christos options->ip_qos_interactive = value;
1760 1.5 christos options->ip_qos_bulk = value2;
1761 1.5 christos }
1762 1.5 christos break;
1763 1.5 christos
1764 1.6 christos case oRequestTTY:
1765 1.6 christos intptr = &options->request_tty;
1766 1.12 christos multistate_ptr = multistate_requesttty;
1767 1.12 christos goto parse_multistate;
1768 1.6 christos
1769 1.7 tls case oSendVersionFirst:
1770 1.7 tls intptr = &options->send_version_first;
1771 1.7 tls goto parse_flag;
1772 1.7 tls
1773 1.11 christos case oIgnoreUnknown:
1774 1.11 christos charptr = &options->ignored_unknown;
1775 1.11 christos goto parse_string;
1776 1.11 christos
1777 1.12 christos case oProxyUseFdpass:
1778 1.12 christos intptr = &options->proxy_use_fdpass;
1779 1.12 christos goto parse_flag;
1780 1.12 christos
1781 1.12 christos case oCanonicalDomains:
1782 1.12 christos value = options->num_canonical_domains != 0;
1783 1.12 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1784 1.23 christos if (!valid_domain(arg, 1, &errstr)) {
1785 1.23 christos fatal("%s line %d: %s", filename, linenum,
1786 1.23 christos errstr);
1787 1.23 christos }
1788 1.12 christos if (!*activep || value)
1789 1.12 christos continue;
1790 1.12 christos if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1791 1.12 christos fatal("%s line %d: too many hostname suffixes.",
1792 1.12 christos filename, linenum);
1793 1.12 christos options->canonical_domains[
1794 1.12 christos options->num_canonical_domains++] = xstrdup(arg);
1795 1.12 christos }
1796 1.12 christos break;
1797 1.12 christos
1798 1.12 christos case oCanonicalizePermittedCNAMEs:
1799 1.12 christos value = options->num_permitted_cnames != 0;
1800 1.12 christos while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1801 1.12 christos /* Either '*' for everything or 'list:list' */
1802 1.12 christos if (strcmp(arg, "*") == 0)
1803 1.12 christos arg2 = arg;
1804 1.12 christos else {
1805 1.12 christos lowercase(arg);
1806 1.12 christos if ((arg2 = strchr(arg, ':')) == NULL ||
1807 1.12 christos arg2[1] == '\0') {
1808 1.12 christos fatal("%s line %d: "
1809 1.12 christos "Invalid permitted CNAME \"%s\"",
1810 1.12 christos filename, linenum, arg);
1811 1.12 christos }
1812 1.12 christos *arg2 = '\0';
1813 1.12 christos arg2++;
1814 1.12 christos }
1815 1.12 christos if (!*activep || value)
1816 1.12 christos continue;
1817 1.12 christos if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1818 1.12 christos fatal("%s line %d: too many permitted CNAMEs.",
1819 1.12 christos filename, linenum);
1820 1.12 christos cname = options->permitted_cnames +
1821 1.12 christos options->num_permitted_cnames++;
1822 1.12 christos cname->source_list = xstrdup(arg);
1823 1.12 christos cname->target_list = xstrdup(arg2);
1824 1.12 christos }
1825 1.12 christos break;
1826 1.12 christos
1827 1.12 christos case oCanonicalizeHostname:
1828 1.12 christos intptr = &options->canonicalize_hostname;
1829 1.12 christos multistate_ptr = multistate_canonicalizehostname;
1830 1.12 christos goto parse_multistate;
1831 1.12 christos
1832 1.12 christos case oCanonicalizeMaxDots:
1833 1.12 christos intptr = &options->canonicalize_max_dots;
1834 1.12 christos goto parse_int;
1835 1.12 christos
1836 1.12 christos case oCanonicalizeFallbackLocal:
1837 1.12 christos intptr = &options->canonicalize_fallback_local;
1838 1.12 christos goto parse_flag;
1839 1.12 christos
1840 1.12 christos case oStreamLocalBindMask:
1841 1.12 christos arg = strdelim(&s);
1842 1.12 christos if (!arg || *arg == '\0')
1843 1.12 christos fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1844 1.12 christos /* Parse mode in octal format */
1845 1.12 christos value = strtol(arg, &endofnumber, 8);
1846 1.12 christos if (arg == endofnumber || value < 0 || value > 0777)
1847 1.12 christos fatal("%.200s line %d: Bad mask.", filename, linenum);
1848 1.12 christos options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1849 1.12 christos break;
1850 1.12 christos
1851 1.12 christos case oStreamLocalBindUnlink:
1852 1.12 christos intptr = &options->fwd_opts.streamlocal_bind_unlink;
1853 1.12 christos goto parse_flag;
1854 1.12 christos
1855 1.13 christos case oRevokedHostKeys:
1856 1.13 christos charptr = &options->revoked_host_keys;
1857 1.13 christos goto parse_string;
1858 1.13 christos
1859 1.13 christos case oFingerprintHash:
1860 1.13 christos intptr = &options->fingerprint_hash;
1861 1.13 christos arg = strdelim(&s);
1862 1.13 christos if (!arg || *arg == '\0')
1863 1.13 christos fatal("%.200s line %d: Missing argument.",
1864 1.13 christos filename, linenum);
1865 1.13 christos if ((value = ssh_digest_alg_by_name(arg)) == -1)
1866 1.13 christos fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1867 1.13 christos filename, linenum, arg);
1868 1.13 christos if (*activep && *intptr == -1)
1869 1.13 christos *intptr = value;
1870 1.13 christos break;
1871 1.13 christos
1872 1.13 christos case oUpdateHostkeys:
1873 1.13 christos intptr = &options->update_hostkeys;
1874 1.13 christos multistate_ptr = multistate_yesnoask;
1875 1.13 christos goto parse_multistate;
1876 1.13 christos
1877 1.13 christos case oHostbasedKeyTypes:
1878 1.13 christos charptr = &options->hostbased_key_types;
1879 1.16 christos goto parse_keytypes;
1880 1.16 christos
1881 1.16 christos case oPubkeyAcceptedKeyTypes:
1882 1.16 christos charptr = &options->pubkey_key_types;
1883 1.16 christos goto parse_keytypes;
1884 1.13 christos
1885 1.18 christos case oAddKeysToAgent:
1886 1.18 christos intptr = &options->add_keys_to_agent;
1887 1.18 christos multistate_ptr = multistate_yesnoaskconfirm;
1888 1.18 christos goto parse_multistate;
1889 1.18 christos
1890 1.19 christos case oIdentityAgent:
1891 1.19 christos charptr = &options->identity_agent;
1892 1.27 christos arg = strdelim(&s);
1893 1.27 christos if (!arg || *arg == '\0')
1894 1.27 christos fatal("%.200s line %d: Missing argument.",
1895 1.27 christos filename, linenum);
1896 1.29 christos parse_agent_path:
1897 1.27 christos /* Extra validation if the string represents an env var. */
1898 1.27 christos if (arg[0] == '$' && !valid_env_name(arg + 1)) {
1899 1.27 christos fatal("%.200s line %d: Invalid environment name %s.",
1900 1.27 christos filename, linenum, arg);
1901 1.27 christos }
1902 1.27 christos if (*activep && *charptr == NULL)
1903 1.27 christos *charptr = xstrdup(arg);
1904 1.27 christos break;
1905 1.19 christos
1906 1.1 christos case oDeprecated:
1907 1.1 christos debug("%s line %d: Deprecated option \"%s\"",
1908 1.1 christos filename, linenum, keyword);
1909 1.1 christos return 0;
1910 1.1 christos
1911 1.1 christos case oUnsupported:
1912 1.1 christos error("%s line %d: Unsupported option \"%s\"",
1913 1.1 christos filename, linenum, keyword);
1914 1.1 christos return 0;
1915 1.1 christos
1916 1.1 christos default:
1917 1.13 christos fatal("%s: Unimplemented opcode %d", __func__, opcode);
1918 1.1 christos }
1919 1.1 christos
1920 1.1 christos /* Check that there is no garbage at end of line. */
1921 1.1 christos if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1922 1.1 christos fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1923 1.1 christos filename, linenum, arg);
1924 1.1 christos }
1925 1.1 christos return 0;
1926 1.1 christos }
1927 1.1 christos
1928 1.1 christos /*
1929 1.1 christos * Reads the config file and modifies the options accordingly. Options
1930 1.1 christos * should already be initialized before this call. This never returns if
1931 1.1 christos * there is an error. If the file does not exist, this returns 0.
1932 1.1 christos */
1933 1.1 christos int
1934 1.12 christos read_config_file(const char *filename, struct passwd *pw, const char *host,
1935 1.27 christos const char *original_host, Options *options, int flags,
1936 1.27 christos int *want_final_pass)
1937 1.1 christos {
1938 1.19 christos int active = 1;
1939 1.19 christos
1940 1.19 christos return read_config_file_depth(filename, pw, host, original_host,
1941 1.27 christos options, flags, &active, want_final_pass, 0);
1942 1.19 christos }
1943 1.19 christos
1944 1.19 christos #define READCONF_MAX_DEPTH 16
1945 1.19 christos static int
1946 1.19 christos read_config_file_depth(const char *filename, struct passwd *pw,
1947 1.19 christos const char *host, const char *original_host, Options *options,
1948 1.27 christos int flags, int *activep, int *want_final_pass, int depth)
1949 1.19 christos {
1950 1.1 christos FILE *f;
1951 1.25 christos char *line = NULL;
1952 1.25 christos size_t linesize = 0;
1953 1.19 christos int linenum;
1954 1.1 christos int bad_options = 0;
1955 1.1 christos
1956 1.19 christos if (depth < 0 || depth > READCONF_MAX_DEPTH)
1957 1.19 christos fatal("Too many recursive configuration includes");
1958 1.19 christos
1959 1.1 christos if ((f = fopen(filename, "r")) == NULL)
1960 1.1 christos return 0;
1961 1.1 christos
1962 1.9 mlelstv if (flags & SSHCONF_CHECKPERM) {
1963 1.1 christos struct stat sb;
1964 1.1 christos
1965 1.1 christos if (fstat(fileno(f), &sb) == -1)
1966 1.1 christos fatal("fstat %s: %s", filename, strerror(errno));
1967 1.1 christos if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1968 1.1 christos (sb.st_mode & 022) != 0))
1969 1.1 christos fatal("Bad owner or permissions on %s", filename);
1970 1.1 christos }
1971 1.1 christos
1972 1.1 christos debug("Reading configuration data %.200s", filename);
1973 1.1 christos
1974 1.1 christos /*
1975 1.1 christos * Mark that we are now processing the options. This flag is turned
1976 1.1 christos * on/off by Host specifications.
1977 1.1 christos */
1978 1.1 christos linenum = 0;
1979 1.25 christos while (getline(&line, &linesize, f) != -1) {
1980 1.1 christos /* Update line number counter. */
1981 1.1 christos linenum++;
1982 1.19 christos if (process_config_line_depth(options, pw, host, original_host,
1983 1.27 christos line, filename, linenum, activep, flags, want_final_pass,
1984 1.27 christos depth) != 0)
1985 1.1 christos bad_options++;
1986 1.1 christos }
1987 1.25 christos free(line);
1988 1.1 christos fclose(f);
1989 1.1 christos if (bad_options > 0)
1990 1.1 christos fatal("%s: terminating, %d bad configuration options",
1991 1.1 christos filename, bad_options);
1992 1.1 christos return 1;
1993 1.1 christos }
1994 1.1 christos
1995 1.12 christos /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1996 1.12 christos int
1997 1.12 christos option_clear_or_none(const char *o)
1998 1.12 christos {
1999 1.12 christos return o == NULL || strcasecmp(o, "none") == 0;
2000 1.12 christos }
2001 1.12 christos
2002 1.1 christos /*
2003 1.1 christos * Initializes options to special values that indicate that they have not yet
2004 1.1 christos * been set. Read_config_file will only set options with this value. Options
2005 1.1 christos * are processed in the following order: command line, user config file,
2006 1.1 christos * system config file. Last, fill_default_options is called.
2007 1.1 christos */
2008 1.1 christos
2009 1.1 christos void
2010 1.1 christos initialize_options(Options * options)
2011 1.1 christos {
2012 1.1 christos memset(options, 'X', sizeof(*options));
2013 1.1 christos options->forward_agent = -1;
2014 1.29 christos options->forward_agent_sock_path = NULL;
2015 1.1 christos options->forward_x11 = -1;
2016 1.1 christos options->forward_x11_trusted = -1;
2017 1.4 adam options->forward_x11_timeout = -1;
2018 1.19 christos options->stdio_forward_host = NULL;
2019 1.19 christos options->stdio_forward_port = 0;
2020 1.19 christos options->clear_forwardings = -1;
2021 1.1 christos options->exit_on_forward_failure = -1;
2022 1.1 christos options->xauth_location = NULL;
2023 1.12 christos options->fwd_opts.gateway_ports = -1;
2024 1.12 christos options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
2025 1.12 christos options->fwd_opts.streamlocal_bind_unlink = -1;
2026 1.1 christos options->pubkey_authentication = -1;
2027 1.1 christos options->challenge_response_authentication = -1;
2028 1.2 christos #if defined(KRB4) || defined(KRB5)
2029 1.2 christos options->kerberos_authentication = -1;
2030 1.2 christos #endif
2031 1.2 christos #if defined(AFS) || defined(KRB5)
2032 1.2 christos options->kerberos_tgt_passing = -1;
2033 1.2 christos #endif
2034 1.2 christos #ifdef AFS
2035 1.2 christos options->afs_token_passing = -1;
2036 1.2 christos #endif
2037 1.1 christos options->gss_authentication = -1;
2038 1.1 christos options->gss_deleg_creds = -1;
2039 1.1 christos options->password_authentication = -1;
2040 1.1 christos options->kbd_interactive_authentication = -1;
2041 1.1 christos options->kbd_interactive_devices = NULL;
2042 1.1 christos options->hostbased_authentication = -1;
2043 1.1 christos options->batch_mode = -1;
2044 1.1 christos options->check_host_ip = -1;
2045 1.1 christos options->strict_host_key_checking = -1;
2046 1.1 christos options->compression = -1;
2047 1.1 christos options->tcp_keep_alive = -1;
2048 1.1 christos options->port = -1;
2049 1.1 christos options->address_family = -1;
2050 1.1 christos options->connection_attempts = -1;
2051 1.1 christos options->connection_timeout = -1;
2052 1.1 christos options->number_of_password_prompts = -1;
2053 1.1 christos options->ciphers = NULL;
2054 1.1 christos options->macs = NULL;
2055 1.5 christos options->kex_algorithms = NULL;
2056 1.1 christos options->hostkeyalgorithms = NULL;
2057 1.27 christos options->ca_sign_algorithms = NULL;
2058 1.1 christos options->num_identity_files = 0;
2059 1.18 christos options->num_certificate_files = 0;
2060 1.1 christos options->hostname = NULL;
2061 1.1 christos options->host_key_alias = NULL;
2062 1.1 christos options->proxy_command = NULL;
2063 1.19 christos options->jump_user = NULL;
2064 1.19 christos options->jump_host = NULL;
2065 1.19 christos options->jump_port = -1;
2066 1.19 christos options->jump_extra = NULL;
2067 1.1 christos options->user = NULL;
2068 1.1 christos options->escape_char = -1;
2069 1.6 christos options->num_system_hostfiles = 0;
2070 1.6 christos options->num_user_hostfiles = 0;
2071 1.4 adam options->local_forwards = NULL;
2072 1.1 christos options->num_local_forwards = 0;
2073 1.4 adam options->remote_forwards = NULL;
2074 1.1 christos options->num_remote_forwards = 0;
2075 1.22 christos options->log_facility = SYSLOG_FACILITY_NOT_SET;
2076 1.1 christos options->log_level = SYSLOG_LEVEL_NOT_SET;
2077 1.1 christos options->preferred_authentications = NULL;
2078 1.1 christos options->bind_address = NULL;
2079 1.23 christos options->bind_interface = NULL;
2080 1.4 adam options->pkcs11_provider = NULL;
2081 1.29 christos options->sk_provider = NULL;
2082 1.1 christos options->enable_ssh_keysign = - 1;
2083 1.1 christos options->no_host_authentication_for_localhost = - 1;
2084 1.1 christos options->identities_only = - 1;
2085 1.1 christos options->rekey_limit = - 1;
2086 1.11 christos options->rekey_interval = -1;
2087 1.1 christos options->verify_host_key_dns = -1;
2088 1.1 christos options->server_alive_interval = -1;
2089 1.1 christos options->server_alive_count_max = -1;
2090 1.25 christos options->send_env = NULL;
2091 1.1 christos options->num_send_env = 0;
2092 1.25 christos options->setenv = NULL;
2093 1.25 christos options->num_setenv = 0;
2094 1.1 christos options->control_path = NULL;
2095 1.1 christos options->control_master = -1;
2096 1.4 adam options->control_persist = -1;
2097 1.4 adam options->control_persist_timeout = 0;
2098 1.1 christos options->hash_known_hosts = -1;
2099 1.1 christos options->tun_open = -1;
2100 1.1 christos options->tun_local = -1;
2101 1.1 christos options->tun_remote = -1;
2102 1.1 christos options->local_command = NULL;
2103 1.1 christos options->permit_local_command = -1;
2104 1.22 christos options->remote_command = NULL;
2105 1.18 christos options->add_keys_to_agent = -1;
2106 1.19 christos options->identity_agent = NULL;
2107 1.1 christos options->visual_host_key = -1;
2108 1.5 christos options->ip_qos_interactive = -1;
2109 1.5 christos options->ip_qos_bulk = -1;
2110 1.6 christos options->request_tty = -1;
2111 1.12 christos options->proxy_use_fdpass = -1;
2112 1.11 christos options->ignored_unknown = NULL;
2113 1.12 christos options->num_canonical_domains = 0;
2114 1.12 christos options->num_permitted_cnames = 0;
2115 1.12 christos options->canonicalize_max_dots = -1;
2116 1.12 christos options->canonicalize_fallback_local = -1;
2117 1.12 christos options->canonicalize_hostname = -1;
2118 1.13 christos options->revoked_host_keys = NULL;
2119 1.13 christos options->fingerprint_hash = -1;
2120 1.13 christos options->update_hostkeys = -1;
2121 1.13 christos options->hostbased_key_types = NULL;
2122 1.16 christos options->pubkey_key_types = NULL;
2123 1.2 christos options->none_switch = -1;
2124 1.2 christos options->none_enabled = -1;
2125 1.2 christos options->hpn_disabled = -1;
2126 1.2 christos options->hpn_buffer_size = -1;
2127 1.2 christos options->tcp_rcv_buf_poll = -1;
2128 1.2 christos options->tcp_rcv_buf = -1;
2129 1.7 tls options->send_version_first = -1;
2130 1.1 christos }
2131 1.1 christos
2132 1.1 christos /*
2133 1.12 christos * A petite version of fill_default_options() that just fills the options
2134 1.12 christos * needed for hostname canonicalization to proceed.
2135 1.12 christos */
2136 1.12 christos void
2137 1.12 christos fill_default_options_for_canonicalization(Options *options)
2138 1.12 christos {
2139 1.12 christos if (options->canonicalize_max_dots == -1)
2140 1.12 christos options->canonicalize_max_dots = 1;
2141 1.12 christos if (options->canonicalize_fallback_local == -1)
2142 1.12 christos options->canonicalize_fallback_local = 1;
2143 1.12 christos if (options->canonicalize_hostname == -1)
2144 1.12 christos options->canonicalize_hostname = SSH_CANONICALISE_NO;
2145 1.12 christos }
2146 1.12 christos
2147 1.12 christos /*
2148 1.1 christos * Called after processing other sources of option data, this fills those
2149 1.1 christos * options for which no value has been specified with their default values.
2150 1.1 christos */
2151 1.1 christos void
2152 1.1 christos fill_default_options(Options * options)
2153 1.1 christos {
2154 1.27 christos char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
2155 1.29 christos char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
2156 1.25 christos int r;
2157 1.25 christos
2158 1.1 christos if (options->forward_agent == -1)
2159 1.1 christos options->forward_agent = 0;
2160 1.1 christos if (options->forward_x11 == -1)
2161 1.1 christos options->forward_x11 = 0;
2162 1.1 christos if (options->forward_x11_trusted == -1)
2163 1.1 christos options->forward_x11_trusted = 0;
2164 1.4 adam if (options->forward_x11_timeout == -1)
2165 1.4 adam options->forward_x11_timeout = 1200;
2166 1.19 christos /*
2167 1.19 christos * stdio forwarding (-W) changes the default for these but we defer
2168 1.19 christos * setting the values so they can be overridden.
2169 1.19 christos */
2170 1.1 christos if (options->exit_on_forward_failure == -1)
2171 1.19 christos options->exit_on_forward_failure =
2172 1.19 christos options->stdio_forward_host != NULL ? 1 : 0;
2173 1.19 christos if (options->clear_forwardings == -1)
2174 1.19 christos options->clear_forwardings =
2175 1.19 christos options->stdio_forward_host != NULL ? 1 : 0;
2176 1.19 christos if (options->clear_forwardings == 1)
2177 1.19 christos clear_forwardings(options);
2178 1.19 christos
2179 1.1 christos if (options->xauth_location == NULL)
2180 1.5 christos options->xauth_location = __UNCONST(_PATH_XAUTH);
2181 1.12 christos if (options->fwd_opts.gateway_ports == -1)
2182 1.12 christos options->fwd_opts.gateway_ports = 0;
2183 1.12 christos if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
2184 1.12 christos options->fwd_opts.streamlocal_bind_mask = 0177;
2185 1.12 christos if (options->fwd_opts.streamlocal_bind_unlink == -1)
2186 1.12 christos options->fwd_opts.streamlocal_bind_unlink = 0;
2187 1.1 christos if (options->pubkey_authentication == -1)
2188 1.1 christos options->pubkey_authentication = 1;
2189 1.1 christos if (options->challenge_response_authentication == -1)
2190 1.1 christos options->challenge_response_authentication = 1;
2191 1.2 christos #if defined(KRB4) || defined(KRB5)
2192 1.2 christos if (options->kerberos_authentication == -1)
2193 1.2 christos options->kerberos_authentication = 1;
2194 1.2 christos #endif
2195 1.2 christos #if defined(AFS) || defined(KRB5)
2196 1.2 christos if (options->kerberos_tgt_passing == -1)
2197 1.2 christos options->kerberos_tgt_passing = 1;
2198 1.2 christos #endif
2199 1.2 christos #ifdef AFS
2200 1.2 christos if (options->afs_token_passing == -1)
2201 1.2 christos options->afs_token_passing = 1;
2202 1.2 christos #endif
2203 1.1 christos if (options->gss_authentication == -1)
2204 1.1 christos options->gss_authentication = 0;
2205 1.1 christos if (options->gss_deleg_creds == -1)
2206 1.1 christos options->gss_deleg_creds = 0;
2207 1.1 christos if (options->password_authentication == -1)
2208 1.1 christos options->password_authentication = 1;
2209 1.1 christos if (options->kbd_interactive_authentication == -1)
2210 1.1 christos options->kbd_interactive_authentication = 1;
2211 1.1 christos if (options->hostbased_authentication == -1)
2212 1.1 christos options->hostbased_authentication = 0;
2213 1.1 christos if (options->batch_mode == -1)
2214 1.1 christos options->batch_mode = 0;
2215 1.1 christos if (options->check_host_ip == -1)
2216 1.1 christos options->check_host_ip = 1;
2217 1.1 christos if (options->strict_host_key_checking == -1)
2218 1.22 christos options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2219 1.1 christos if (options->compression == -1)
2220 1.1 christos options->compression = 0;
2221 1.1 christos if (options->tcp_keep_alive == -1)
2222 1.1 christos options->tcp_keep_alive = 1;
2223 1.1 christos if (options->port == -1)
2224 1.1 christos options->port = 0; /* Filled in ssh_connect. */
2225 1.1 christos if (options->address_family == -1)
2226 1.1 christos options->address_family = AF_UNSPEC;
2227 1.1 christos if (options->connection_attempts == -1)
2228 1.1 christos options->connection_attempts = 1;
2229 1.1 christos if (options->number_of_password_prompts == -1)
2230 1.1 christos options->number_of_password_prompts = 3;
2231 1.1 christos /* options->hostkeyalgorithms, default set in myproposals.h */
2232 1.18 christos if (options->add_keys_to_agent == -1)
2233 1.18 christos options->add_keys_to_agent = 0;
2234 1.1 christos if (options->num_identity_files == 0) {
2235 1.22 christos add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2236 1.22 christos add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2237 1.22 christos add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2238 1.22 christos add_identity_file(options, "~/",
2239 1.29 christos _PATH_SSH_CLIENT_ID_ECDSA_SK, 0);
2240 1.29 christos add_identity_file(options, "~/",
2241 1.22 christos _PATH_SSH_CLIENT_ID_ED25519, 0);
2242 1.29 christos add_identity_file(options, "~/",
2243 1.29 christos _PATH_SSH_CLIENT_ID_ED25519_SK, 0);
2244 1.23 christos add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2245 1.1 christos }
2246 1.1 christos if (options->escape_char == -1)
2247 1.1 christos options->escape_char = '~';
2248 1.6 christos if (options->num_system_hostfiles == 0) {
2249 1.6 christos options->system_hostfiles[options->num_system_hostfiles++] =
2250 1.6 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2251 1.6 christos options->system_hostfiles[options->num_system_hostfiles++] =
2252 1.6 christos xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2253 1.6 christos }
2254 1.29 christos if (options->update_hostkeys == -1)
2255 1.29 christos options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO;
2256 1.6 christos if (options->num_user_hostfiles == 0) {
2257 1.6 christos options->user_hostfiles[options->num_user_hostfiles++] =
2258 1.6 christos xstrdup(_PATH_SSH_USER_HOSTFILE);
2259 1.6 christos options->user_hostfiles[options->num_user_hostfiles++] =
2260 1.6 christos xstrdup(_PATH_SSH_USER_HOSTFILE2);
2261 1.6 christos }
2262 1.1 christos if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2263 1.1 christos options->log_level = SYSLOG_LEVEL_INFO;
2264 1.22 christos if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2265 1.22 christos options->log_facility = SYSLOG_FACILITY_USER;
2266 1.1 christos if (options->no_host_authentication_for_localhost == - 1)
2267 1.1 christos options->no_host_authentication_for_localhost = 0;
2268 1.1 christos if (options->identities_only == -1)
2269 1.1 christos options->identities_only = 0;
2270 1.1 christos if (options->enable_ssh_keysign == -1)
2271 1.1 christos options->enable_ssh_keysign = 0;
2272 1.1 christos if (options->rekey_limit == -1)
2273 1.1 christos options->rekey_limit = 0;
2274 1.11 christos if (options->rekey_interval == -1)
2275 1.11 christos options->rekey_interval = 0;
2276 1.1 christos if (options->verify_host_key_dns == -1)
2277 1.1 christos options->verify_host_key_dns = 0;
2278 1.1 christos if (options->server_alive_interval == -1)
2279 1.1 christos options->server_alive_interval = 0;
2280 1.1 christos if (options->server_alive_count_max == -1)
2281 1.1 christos options->server_alive_count_max = 3;
2282 1.2 christos if (options->none_switch == -1)
2283 1.2 christos options->none_switch = 0;
2284 1.2 christos if (options->hpn_disabled == -1)
2285 1.2 christos options->hpn_disabled = 0;
2286 1.2 christos if (options->hpn_buffer_size > -1)
2287 1.2 christos {
2288 1.2 christos /* if a user tries to set the size to 0 set it to 1KB */
2289 1.2 christos if (options->hpn_buffer_size == 0)
2290 1.2 christos options->hpn_buffer_size = 1024;
2291 1.2 christos /*limit the buffer to 64MB*/
2292 1.2 christos if (options->hpn_buffer_size > 65536)
2293 1.2 christos {
2294 1.2 christos options->hpn_buffer_size = 65536*1024;
2295 1.2 christos debug("User requested buffer larger than 64MB. Request reverted to 64MB");
2296 1.2 christos }
2297 1.2 christos debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
2298 1.2 christos }
2299 1.2 christos if (options->tcp_rcv_buf == 0)
2300 1.2 christos options->tcp_rcv_buf = 1;
2301 1.2 christos if (options->tcp_rcv_buf > -1)
2302 1.2 christos options->tcp_rcv_buf *=1024;
2303 1.2 christos if (options->tcp_rcv_buf_poll == -1)
2304 1.2 christos options->tcp_rcv_buf_poll = 1;
2305 1.1 christos if (options->control_master == -1)
2306 1.1 christos options->control_master = 0;
2307 1.4 adam if (options->control_persist == -1) {
2308 1.4 adam options->control_persist = 0;
2309 1.4 adam options->control_persist_timeout = 0;
2310 1.4 adam }
2311 1.1 christos if (options->hash_known_hosts == -1)
2312 1.1 christos options->hash_known_hosts = 0;
2313 1.1 christos if (options->tun_open == -1)
2314 1.1 christos options->tun_open = SSH_TUNMODE_NO;
2315 1.1 christos if (options->tun_local == -1)
2316 1.1 christos options->tun_local = SSH_TUNID_ANY;
2317 1.1 christos if (options->tun_remote == -1)
2318 1.1 christos options->tun_remote = SSH_TUNID_ANY;
2319 1.1 christos if (options->permit_local_command == -1)
2320 1.1 christos options->permit_local_command = 0;
2321 1.1 christos if (options->visual_host_key == -1)
2322 1.1 christos options->visual_host_key = 0;
2323 1.5 christos if (options->ip_qos_interactive == -1)
2324 1.25 christos options->ip_qos_interactive = IPTOS_DSCP_AF21;
2325 1.5 christos if (options->ip_qos_bulk == -1)
2326 1.25 christos options->ip_qos_bulk = IPTOS_DSCP_CS1;
2327 1.6 christos if (options->request_tty == -1)
2328 1.6 christos options->request_tty = REQUEST_TTY_AUTO;
2329 1.12 christos if (options->proxy_use_fdpass == -1)
2330 1.12 christos options->proxy_use_fdpass = 0;
2331 1.12 christos if (options->canonicalize_max_dots == -1)
2332 1.12 christos options->canonicalize_max_dots = 1;
2333 1.12 christos if (options->canonicalize_fallback_local == -1)
2334 1.12 christos options->canonicalize_fallback_local = 1;
2335 1.12 christos if (options->canonicalize_hostname == -1)
2336 1.12 christos options->canonicalize_hostname = SSH_CANONICALISE_NO;
2337 1.13 christos if (options->fingerprint_hash == -1)
2338 1.13 christos options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2339 1.29 christos if (options->sk_provider == NULL)
2340 1.29 christos options->sk_provider = xstrdup("internal");
2341 1.25 christos
2342 1.25 christos /* Expand KEX name lists */
2343 1.25 christos all_cipher = cipher_alg_list(',', 0);
2344 1.25 christos all_mac = mac_alg_list(',');
2345 1.25 christos all_kex = kex_alg_list(',');
2346 1.25 christos all_key = sshkey_alg_list(0, 0, 1, ',');
2347 1.27 christos all_sig = sshkey_alg_list(0, 1, 1, ',');
2348 1.29 christos /* remove unsupported algos from default lists */
2349 1.29 christos def_cipher = match_filter_whitelist(KEX_CLIENT_ENCRYPT, all_cipher);
2350 1.29 christos def_mac = match_filter_whitelist(KEX_CLIENT_MAC, all_mac);
2351 1.29 christos def_kex = match_filter_whitelist(KEX_CLIENT_KEX, all_kex);
2352 1.29 christos def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key);
2353 1.29 christos def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig);
2354 1.25 christos #define ASSEMBLE(what, defaults, all) \
2355 1.25 christos do { \
2356 1.25 christos if ((r = kex_assemble_names(&options->what, \
2357 1.25 christos defaults, all)) != 0) \
2358 1.25 christos fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2359 1.25 christos } while (0)
2360 1.29 christos ASSEMBLE(ciphers, def_cipher, all_cipher);
2361 1.29 christos ASSEMBLE(macs, def_mac, all_mac);
2362 1.29 christos ASSEMBLE(kex_algorithms, def_kex, all_kex);
2363 1.29 christos ASSEMBLE(hostbased_key_types, def_key, all_key);
2364 1.29 christos ASSEMBLE(pubkey_key_types, def_key, all_key);
2365 1.29 christos ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
2366 1.25 christos #undef ASSEMBLE
2367 1.25 christos free(all_cipher);
2368 1.25 christos free(all_mac);
2369 1.25 christos free(all_kex);
2370 1.25 christos free(all_key);
2371 1.27 christos free(all_sig);
2372 1.29 christos free(def_cipher);
2373 1.29 christos free(def_mac);
2374 1.29 christos free(def_kex);
2375 1.29 christos kex_default_pk_alg_filtered = def_key; /* save for later use */
2376 1.29 christos free(def_sig);
2377 1.13 christos
2378 1.7 tls if (options->send_version_first == -1)
2379 1.7 tls options->send_version_first = 1;
2380 1.12 christos #define CLEAR_ON_NONE(v) \
2381 1.12 christos do { \
2382 1.12 christos if (option_clear_or_none(v)) { \
2383 1.12 christos free(v); \
2384 1.12 christos v = NULL; \
2385 1.12 christos } \
2386 1.12 christos } while(0)
2387 1.12 christos CLEAR_ON_NONE(options->local_command);
2388 1.22 christos CLEAR_ON_NONE(options->remote_command);
2389 1.12 christos CLEAR_ON_NONE(options->proxy_command);
2390 1.12 christos CLEAR_ON_NONE(options->control_path);
2391 1.13 christos CLEAR_ON_NONE(options->revoked_host_keys);
2392 1.27 christos CLEAR_ON_NONE(options->pkcs11_provider);
2393 1.29 christos CLEAR_ON_NONE(options->sk_provider);
2394 1.25 christos if (options->jump_host != NULL &&
2395 1.25 christos strcmp(options->jump_host, "none") == 0 &&
2396 1.25 christos options->jump_port == 0 && options->jump_user == NULL) {
2397 1.25 christos free(options->jump_host);
2398 1.25 christos options->jump_host = NULL;
2399 1.25 christos }
2400 1.19 christos /* options->identity_agent distinguishes NULL from 'none' */
2401 1.1 christos /* options->user will be set in the main program if appropriate */
2402 1.1 christos /* options->hostname will be set in the main program if appropriate */
2403 1.1 christos /* options->host_key_alias should not be set by default */
2404 1.1 christos /* options->preferred_authentications will be set in ssh */
2405 1.1 christos }
2406 1.1 christos
2407 1.12 christos struct fwdarg {
2408 1.12 christos char *arg;
2409 1.12 christos int ispath;
2410 1.12 christos };
2411 1.12 christos
2412 1.12 christos /*
2413 1.12 christos * parse_fwd_field
2414 1.12 christos * parses the next field in a port forwarding specification.
2415 1.12 christos * sets fwd to the parsed field and advances p past the colon
2416 1.12 christos * or sets it to NULL at end of string.
2417 1.12 christos * returns 0 on success, else non-zero.
2418 1.12 christos */
2419 1.12 christos static int
2420 1.12 christos parse_fwd_field(char **p, struct fwdarg *fwd)
2421 1.12 christos {
2422 1.12 christos char *ep, *cp = *p;
2423 1.12 christos int ispath = 0;
2424 1.12 christos
2425 1.12 christos if (*cp == '\0') {
2426 1.12 christos *p = NULL;
2427 1.12 christos return -1; /* end of string */
2428 1.12 christos }
2429 1.12 christos
2430 1.12 christos /*
2431 1.12 christos * A field escaped with square brackets is used literally.
2432 1.12 christos * XXX - allow ']' to be escaped via backslash?
2433 1.12 christos */
2434 1.12 christos if (*cp == '[') {
2435 1.12 christos /* find matching ']' */
2436 1.12 christos for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2437 1.12 christos if (*ep == '/')
2438 1.12 christos ispath = 1;
2439 1.12 christos }
2440 1.12 christos /* no matching ']' or not at end of field. */
2441 1.12 christos if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2442 1.12 christos return -1;
2443 1.12 christos /* NUL terminate the field and advance p past the colon */
2444 1.12 christos *ep++ = '\0';
2445 1.12 christos if (*ep != '\0')
2446 1.12 christos *ep++ = '\0';
2447 1.12 christos fwd->arg = cp + 1;
2448 1.12 christos fwd->ispath = ispath;
2449 1.12 christos *p = ep;
2450 1.12 christos return 0;
2451 1.12 christos }
2452 1.12 christos
2453 1.12 christos for (cp = *p; *cp != '\0'; cp++) {
2454 1.12 christos switch (*cp) {
2455 1.12 christos case '\\':
2456 1.12 christos memmove(cp, cp + 1, strlen(cp + 1) + 1);
2457 1.14 christos if (*cp == '\0')
2458 1.14 christos return -1;
2459 1.12 christos break;
2460 1.12 christos case '/':
2461 1.12 christos ispath = 1;
2462 1.12 christos break;
2463 1.12 christos case ':':
2464 1.12 christos *cp++ = '\0';
2465 1.12 christos goto done;
2466 1.12 christos }
2467 1.12 christos }
2468 1.12 christos done:
2469 1.12 christos fwd->arg = *p;
2470 1.12 christos fwd->ispath = ispath;
2471 1.12 christos *p = cp;
2472 1.12 christos return 0;
2473 1.12 christos }
2474 1.12 christos
2475 1.1 christos /*
2476 1.1 christos * parse_forward
2477 1.1 christos * parses a string containing a port forwarding specification of the form:
2478 1.1 christos * dynamicfwd == 0
2479 1.12 christos * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2480 1.12 christos * listenpath:connectpath
2481 1.1 christos * dynamicfwd == 1
2482 1.1 christos * [listenhost:]listenport
2483 1.1 christos * returns number of arguments parsed or zero on error
2484 1.1 christos */
2485 1.1 christos int
2486 1.12 christos parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2487 1.1 christos {
2488 1.12 christos struct fwdarg fwdargs[4];
2489 1.12 christos char *p, *cp;
2490 1.1 christos int i;
2491 1.1 christos
2492 1.12 christos memset(fwd, 0, sizeof(*fwd));
2493 1.12 christos memset(fwdargs, 0, sizeof(fwdargs));
2494 1.1 christos
2495 1.1 christos cp = p = xstrdup(fwdspec);
2496 1.1 christos
2497 1.1 christos /* skip leading spaces */
2498 1.12 christos while (isspace((u_char)*cp))
2499 1.1 christos cp++;
2500 1.1 christos
2501 1.12 christos for (i = 0; i < 4; ++i) {
2502 1.12 christos if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2503 1.1 christos break;
2504 1.12 christos }
2505 1.1 christos
2506 1.1 christos /* Check for trailing garbage */
2507 1.12 christos if (cp != NULL && *cp != '\0') {
2508 1.1 christos i = 0; /* failure */
2509 1.12 christos }
2510 1.1 christos
2511 1.1 christos switch (i) {
2512 1.1 christos case 1:
2513 1.12 christos if (fwdargs[0].ispath) {
2514 1.12 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2515 1.12 christos fwd->listen_port = PORT_STREAMLOCAL;
2516 1.12 christos } else {
2517 1.12 christos fwd->listen_host = NULL;
2518 1.12 christos fwd->listen_port = a2port(fwdargs[0].arg);
2519 1.12 christos }
2520 1.1 christos fwd->connect_host = xstrdup("socks");
2521 1.1 christos break;
2522 1.1 christos
2523 1.1 christos case 2:
2524 1.12 christos if (fwdargs[0].ispath && fwdargs[1].ispath) {
2525 1.12 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2526 1.12 christos fwd->listen_port = PORT_STREAMLOCAL;
2527 1.12 christos fwd->connect_path = xstrdup(fwdargs[1].arg);
2528 1.12 christos fwd->connect_port = PORT_STREAMLOCAL;
2529 1.12 christos } else if (fwdargs[1].ispath) {
2530 1.12 christos fwd->listen_host = NULL;
2531 1.12 christos fwd->listen_port = a2port(fwdargs[0].arg);
2532 1.12 christos fwd->connect_path = xstrdup(fwdargs[1].arg);
2533 1.12 christos fwd->connect_port = PORT_STREAMLOCAL;
2534 1.12 christos } else {
2535 1.12 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2536 1.12 christos fwd->listen_port = a2port(fwdargs[1].arg);
2537 1.12 christos fwd->connect_host = xstrdup("socks");
2538 1.12 christos }
2539 1.1 christos break;
2540 1.1 christos
2541 1.1 christos case 3:
2542 1.12 christos if (fwdargs[0].ispath) {
2543 1.12 christos fwd->listen_path = xstrdup(fwdargs[0].arg);
2544 1.12 christos fwd->listen_port = PORT_STREAMLOCAL;
2545 1.12 christos fwd->connect_host = xstrdup(fwdargs[1].arg);
2546 1.12 christos fwd->connect_port = a2port(fwdargs[2].arg);
2547 1.12 christos } else if (fwdargs[2].ispath) {
2548 1.12 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2549 1.12 christos fwd->listen_port = a2port(fwdargs[1].arg);
2550 1.12 christos fwd->connect_path = xstrdup(fwdargs[2].arg);
2551 1.12 christos fwd->connect_port = PORT_STREAMLOCAL;
2552 1.12 christos } else {
2553 1.12 christos fwd->listen_host = NULL;
2554 1.12 christos fwd->listen_port = a2port(fwdargs[0].arg);
2555 1.12 christos fwd->connect_host = xstrdup(fwdargs[1].arg);
2556 1.12 christos fwd->connect_port = a2port(fwdargs[2].arg);
2557 1.12 christos }
2558 1.1 christos break;
2559 1.1 christos
2560 1.1 christos case 4:
2561 1.12 christos fwd->listen_host = xstrdup(fwdargs[0].arg);
2562 1.12 christos fwd->listen_port = a2port(fwdargs[1].arg);
2563 1.12 christos fwd->connect_host = xstrdup(fwdargs[2].arg);
2564 1.12 christos fwd->connect_port = a2port(fwdargs[3].arg);
2565 1.1 christos break;
2566 1.1 christos default:
2567 1.1 christos i = 0; /* failure */
2568 1.1 christos }
2569 1.1 christos
2570 1.11 christos free(p);
2571 1.1 christos
2572 1.1 christos if (dynamicfwd) {
2573 1.1 christos if (!(i == 1 || i == 2))
2574 1.1 christos goto fail_free;
2575 1.1 christos } else {
2576 1.12 christos if (!(i == 3 || i == 4)) {
2577 1.12 christos if (fwd->connect_path == NULL &&
2578 1.12 christos fwd->listen_path == NULL)
2579 1.12 christos goto fail_free;
2580 1.12 christos }
2581 1.12 christos if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2582 1.1 christos goto fail_free;
2583 1.1 christos }
2584 1.1 christos
2585 1.12 christos if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2586 1.12 christos (!remotefwd && fwd->listen_port == 0))
2587 1.1 christos goto fail_free;
2588 1.1 christos if (fwd->connect_host != NULL &&
2589 1.1 christos strlen(fwd->connect_host) >= NI_MAXHOST)
2590 1.1 christos goto fail_free;
2591 1.12 christos /* XXX - if connecting to a remote socket, max sun len may not match this host */
2592 1.12 christos if (fwd->connect_path != NULL &&
2593 1.12 christos strlen(fwd->connect_path) >= PATH_MAX_SUN)
2594 1.12 christos goto fail_free;
2595 1.1 christos if (fwd->listen_host != NULL &&
2596 1.1 christos strlen(fwd->listen_host) >= NI_MAXHOST)
2597 1.1 christos goto fail_free;
2598 1.12 christos if (fwd->listen_path != NULL &&
2599 1.12 christos strlen(fwd->listen_path) >= PATH_MAX_SUN)
2600 1.12 christos goto fail_free;
2601 1.1 christos
2602 1.1 christos return (i);
2603 1.1 christos
2604 1.1 christos fail_free:
2605 1.11 christos free(fwd->connect_host);
2606 1.11 christos fwd->connect_host = NULL;
2607 1.12 christos free(fwd->connect_path);
2608 1.12 christos fwd->connect_path = NULL;
2609 1.11 christos free(fwd->listen_host);
2610 1.11 christos fwd->listen_host = NULL;
2611 1.12 christos free(fwd->listen_path);
2612 1.12 christos fwd->listen_path = NULL;
2613 1.1 christos return (0);
2614 1.1 christos }
2615 1.13 christos
2616 1.19 christos int
2617 1.19 christos parse_jump(const char *s, Options *o, int active)
2618 1.19 christos {
2619 1.19 christos char *orig, *sdup, *cp;
2620 1.19 christos char *host = NULL, *user = NULL;
2621 1.19 christos int ret = -1, port = -1, first;
2622 1.19 christos
2623 1.19 christos active &= o->proxy_command == NULL && o->jump_host == NULL;
2624 1.19 christos
2625 1.19 christos orig = sdup = xstrdup(s);
2626 1.19 christos first = active;
2627 1.19 christos do {
2628 1.25 christos if (strcasecmp(s, "none") == 0)
2629 1.25 christos break;
2630 1.19 christos if ((cp = strrchr(sdup, ',')) == NULL)
2631 1.19 christos cp = sdup; /* last */
2632 1.19 christos else
2633 1.19 christos *cp++ = '\0';
2634 1.19 christos
2635 1.19 christos if (first) {
2636 1.19 christos /* First argument and configuration is active */
2637 1.23 christos if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2638 1.23 christos parse_user_host_port(cp, &user, &host, &port) != 0)
2639 1.19 christos goto out;
2640 1.19 christos } else {
2641 1.19 christos /* Subsequent argument or inactive configuration */
2642 1.23 christos if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2643 1.23 christos parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2644 1.19 christos goto out;
2645 1.19 christos }
2646 1.19 christos first = 0; /* only check syntax for subsequent hosts */
2647 1.19 christos } while (cp != sdup);
2648 1.19 christos /* success */
2649 1.19 christos if (active) {
2650 1.25 christos if (strcasecmp(s, "none") == 0) {
2651 1.25 christos o->jump_host = xstrdup("none");
2652 1.25 christos o->jump_port = 0;
2653 1.25 christos } else {
2654 1.25 christos o->jump_user = user;
2655 1.25 christos o->jump_host = host;
2656 1.25 christos o->jump_port = port;
2657 1.25 christos o->proxy_command = xstrdup("none");
2658 1.25 christos user = host = NULL;
2659 1.25 christos if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2660 1.25 christos o->jump_extra = xstrdup(s);
2661 1.25 christos o->jump_extra[cp - s] = '\0';
2662 1.25 christos }
2663 1.19 christos }
2664 1.19 christos }
2665 1.19 christos ret = 0;
2666 1.19 christos out:
2667 1.19 christos free(orig);
2668 1.19 christos free(user);
2669 1.19 christos free(host);
2670 1.19 christos return ret;
2671 1.19 christos }
2672 1.19 christos
2673 1.23 christos int
2674 1.23 christos parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2675 1.23 christos {
2676 1.24 christos const char *path;
2677 1.23 christos int r;
2678 1.23 christos
2679 1.23 christos r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2680 1.23 christos if (r == 0 && path != NULL)
2681 1.23 christos r = -1; /* path not allowed */
2682 1.23 christos return r;
2683 1.23 christos }
2684 1.23 christos
2685 1.13 christos /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2686 1.13 christos static const char *
2687 1.13 christos fmt_multistate_int(int val, const struct multistate *m)
2688 1.13 christos {
2689 1.13 christos u_int i;
2690 1.13 christos
2691 1.13 christos for (i = 0; m[i].key != NULL; i++) {
2692 1.13 christos if (m[i].value == val)
2693 1.13 christos return m[i].key;
2694 1.13 christos }
2695 1.13 christos return "UNKNOWN";
2696 1.13 christos }
2697 1.13 christos
2698 1.13 christos static const char *
2699 1.13 christos fmt_intarg(OpCodes code, int val)
2700 1.13 christos {
2701 1.13 christos if (val == -1)
2702 1.13 christos return "unset";
2703 1.13 christos switch (code) {
2704 1.13 christos case oAddressFamily:
2705 1.13 christos return fmt_multistate_int(val, multistate_addressfamily);
2706 1.13 christos case oVerifyHostKeyDNS:
2707 1.13 christos case oUpdateHostkeys:
2708 1.13 christos return fmt_multistate_int(val, multistate_yesnoask);
2709 1.22 christos case oStrictHostKeyChecking:
2710 1.22 christos return fmt_multistate_int(val, multistate_strict_hostkey);
2711 1.13 christos case oControlMaster:
2712 1.13 christos return fmt_multistate_int(val, multistate_controlmaster);
2713 1.13 christos case oTunnel:
2714 1.13 christos return fmt_multistate_int(val, multistate_tunnel);
2715 1.13 christos case oRequestTTY:
2716 1.13 christos return fmt_multistate_int(val, multistate_requesttty);
2717 1.13 christos case oCanonicalizeHostname:
2718 1.13 christos return fmt_multistate_int(val, multistate_canonicalizehostname);
2719 1.25 christos case oAddKeysToAgent:
2720 1.25 christos return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2721 1.13 christos case oFingerprintHash:
2722 1.13 christos return ssh_digest_alg_name(val);
2723 1.13 christos default:
2724 1.13 christos switch (val) {
2725 1.13 christos case 0:
2726 1.13 christos return "no";
2727 1.13 christos case 1:
2728 1.13 christos return "yes";
2729 1.13 christos default:
2730 1.13 christos return "UNKNOWN";
2731 1.13 christos }
2732 1.13 christos }
2733 1.13 christos }
2734 1.13 christos
2735 1.13 christos static const char *
2736 1.13 christos lookup_opcode_name(OpCodes code)
2737 1.13 christos {
2738 1.13 christos u_int i;
2739 1.13 christos
2740 1.13 christos for (i = 0; keywords[i].name != NULL; i++)
2741 1.13 christos if (keywords[i].opcode == code)
2742 1.13 christos return(keywords[i].name);
2743 1.13 christos return "UNKNOWN";
2744 1.13 christos }
2745 1.13 christos
2746 1.13 christos static void
2747 1.13 christos dump_cfg_int(OpCodes code, int val)
2748 1.13 christos {
2749 1.13 christos printf("%s %d\n", lookup_opcode_name(code), val);
2750 1.13 christos }
2751 1.13 christos
2752 1.13 christos static void
2753 1.13 christos dump_cfg_fmtint(OpCodes code, int val)
2754 1.13 christos {
2755 1.13 christos printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2756 1.13 christos }
2757 1.13 christos
2758 1.13 christos static void
2759 1.13 christos dump_cfg_string(OpCodes code, const char *val)
2760 1.13 christos {
2761 1.13 christos if (val == NULL)
2762 1.13 christos return;
2763 1.13 christos printf("%s %s\n", lookup_opcode_name(code), val);
2764 1.13 christos }
2765 1.13 christos
2766 1.13 christos static void
2767 1.13 christos dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2768 1.13 christos {
2769 1.13 christos u_int i;
2770 1.13 christos
2771 1.13 christos for (i = 0; i < count; i++)
2772 1.13 christos printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2773 1.13 christos }
2774 1.13 christos
2775 1.13 christos static void
2776 1.13 christos dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2777 1.13 christos {
2778 1.13 christos u_int i;
2779 1.13 christos
2780 1.13 christos printf("%s", lookup_opcode_name(code));
2781 1.13 christos for (i = 0; i < count; i++)
2782 1.13 christos printf(" %s", vals[i]);
2783 1.13 christos printf("\n");
2784 1.13 christos }
2785 1.13 christos
2786 1.13 christos static void
2787 1.13 christos dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2788 1.13 christos {
2789 1.13 christos const struct Forward *fwd;
2790 1.13 christos u_int i;
2791 1.13 christos
2792 1.13 christos /* oDynamicForward */
2793 1.13 christos for (i = 0; i < count; i++) {
2794 1.13 christos fwd = &fwds[i];
2795 1.21 christos if (code == oDynamicForward && fwd->connect_host != NULL &&
2796 1.13 christos strcmp(fwd->connect_host, "socks") != 0)
2797 1.13 christos continue;
2798 1.21 christos if (code == oLocalForward && fwd->connect_host != NULL &&
2799 1.13 christos strcmp(fwd->connect_host, "socks") == 0)
2800 1.13 christos continue;
2801 1.13 christos printf("%s", lookup_opcode_name(code));
2802 1.13 christos if (fwd->listen_port == PORT_STREAMLOCAL)
2803 1.13 christos printf(" %s", fwd->listen_path);
2804 1.13 christos else if (fwd->listen_host == NULL)
2805 1.13 christos printf(" %d", fwd->listen_port);
2806 1.13 christos else {
2807 1.13 christos printf(" [%s]:%d",
2808 1.13 christos fwd->listen_host, fwd->listen_port);
2809 1.13 christos }
2810 1.13 christos if (code != oDynamicForward) {
2811 1.13 christos if (fwd->connect_port == PORT_STREAMLOCAL)
2812 1.13 christos printf(" %s", fwd->connect_path);
2813 1.13 christos else if (fwd->connect_host == NULL)
2814 1.13 christos printf(" %d", fwd->connect_port);
2815 1.13 christos else {
2816 1.13 christos printf(" [%s]:%d",
2817 1.13 christos fwd->connect_host, fwd->connect_port);
2818 1.13 christos }
2819 1.13 christos }
2820 1.13 christos printf("\n");
2821 1.13 christos }
2822 1.13 christos }
2823 1.13 christos
2824 1.13 christos void
2825 1.13 christos dump_client_config(Options *o, const char *host)
2826 1.13 christos {
2827 1.29 christos int i, r;
2828 1.25 christos char buf[8], *all_key;
2829 1.13 christos
2830 1.29 christos /*
2831 1.29 christos * Expand HostKeyAlgorithms name lists. This isn't handled in
2832 1.29 christos * fill_default_options() like the other algorithm lists because
2833 1.29 christos * the host key algorithms are by default dynamically chosen based
2834 1.29 christos * on the host's keys found in known_hosts.
2835 1.29 christos */
2836 1.25 christos all_key = sshkey_alg_list(0, 0, 1, ',');
2837 1.29 christos if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
2838 1.29 christos all_key)) != 0)
2839 1.29 christos fatal("%s: expand HostKeyAlgorithms: %s", __func__, ssh_err(r));
2840 1.25 christos free(all_key);
2841 1.18 christos
2842 1.13 christos /* Most interesting options first: user, host, port */
2843 1.13 christos dump_cfg_string(oUser, o->user);
2844 1.28 christos dump_cfg_string(oHostname, host);
2845 1.13 christos dump_cfg_int(oPort, o->port);
2846 1.13 christos
2847 1.13 christos /* Flag options */
2848 1.25 christos dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2849 1.13 christos dump_cfg_fmtint(oAddressFamily, o->address_family);
2850 1.13 christos dump_cfg_fmtint(oBatchMode, o->batch_mode);
2851 1.13 christos dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2852 1.13 christos dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2853 1.13 christos dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2854 1.13 christos dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2855 1.13 christos dump_cfg_fmtint(oCompression, o->compression);
2856 1.13 christos dump_cfg_fmtint(oControlMaster, o->control_master);
2857 1.13 christos dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2858 1.19 christos dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2859 1.13 christos dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2860 1.13 christos dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2861 1.13 christos dump_cfg_fmtint(oForwardX11, o->forward_x11);
2862 1.13 christos dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2863 1.13 christos dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2864 1.13 christos #ifdef GSSAPI
2865 1.13 christos dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2866 1.13 christos dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2867 1.13 christos #endif /* GSSAPI */
2868 1.13 christos dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2869 1.13 christos dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2870 1.13 christos dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2871 1.13 christos dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2872 1.13 christos dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2873 1.13 christos dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2874 1.13 christos dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2875 1.13 christos dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2876 1.13 christos dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2877 1.13 christos dump_cfg_fmtint(oRequestTTY, o->request_tty);
2878 1.13 christos dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2879 1.13 christos dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2880 1.13 christos dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2881 1.13 christos dump_cfg_fmtint(oTunnel, o->tun_open);
2882 1.13 christos dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2883 1.13 christos dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2884 1.13 christos dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2885 1.13 christos
2886 1.13 christos /* Integer options */
2887 1.13 christos dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2888 1.13 christos dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2889 1.13 christos dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2890 1.13 christos dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2891 1.13 christos dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2892 1.13 christos dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2893 1.13 christos
2894 1.13 christos /* String options */
2895 1.13 christos dump_cfg_string(oBindAddress, o->bind_address);
2896 1.23 christos dump_cfg_string(oBindInterface, o->bind_interface);
2897 1.29 christos dump_cfg_string(oCiphers, o->ciphers);
2898 1.13 christos dump_cfg_string(oControlPath, o->control_path);
2899 1.18 christos dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2900 1.13 christos dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2901 1.13 christos dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2902 1.19 christos dump_cfg_string(oIdentityAgent, o->identity_agent);
2903 1.25 christos dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2904 1.13 christos dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2905 1.29 christos dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
2906 1.29 christos dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
2907 1.13 christos dump_cfg_string(oLocalCommand, o->local_command);
2908 1.22 christos dump_cfg_string(oRemoteCommand, o->remote_command);
2909 1.13 christos dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2910 1.29 christos dump_cfg_string(oMacs, o->macs);
2911 1.21 christos #ifdef ENABLE_PKCS11
2912 1.13 christos dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2913 1.21 christos #endif
2914 1.29 christos dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
2915 1.13 christos dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2916 1.18 christos dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2917 1.13 christos dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2918 1.13 christos dump_cfg_string(oXAuthLocation, o->xauth_location);
2919 1.13 christos
2920 1.13 christos /* Forwards */
2921 1.13 christos dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2922 1.13 christos dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2923 1.13 christos dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2924 1.13 christos
2925 1.13 christos /* String array options */
2926 1.13 christos dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2927 1.13 christos dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2928 1.25 christos dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2929 1.13 christos dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2930 1.13 christos dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2931 1.13 christos dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2932 1.25 christos dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2933 1.13 christos
2934 1.13 christos /* Special cases */
2935 1.13 christos
2936 1.29 christos /* oForwardAgent */
2937 1.29 christos if (o->forward_agent_sock_path == NULL)
2938 1.29 christos dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2939 1.29 christos else
2940 1.29 christos dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
2941 1.29 christos
2942 1.13 christos /* oConnectTimeout */
2943 1.13 christos if (o->connection_timeout == -1)
2944 1.13 christos printf("connecttimeout none\n");
2945 1.13 christos else
2946 1.13 christos dump_cfg_int(oConnectTimeout, o->connection_timeout);
2947 1.13 christos
2948 1.13 christos /* oTunnelDevice */
2949 1.13 christos printf("tunneldevice");
2950 1.13 christos if (o->tun_local == SSH_TUNID_ANY)
2951 1.13 christos printf(" any");
2952 1.13 christos else
2953 1.13 christos printf(" %d", o->tun_local);
2954 1.13 christos if (o->tun_remote == SSH_TUNID_ANY)
2955 1.13 christos printf(":any");
2956 1.13 christos else
2957 1.13 christos printf(":%d", o->tun_remote);
2958 1.13 christos printf("\n");
2959 1.13 christos
2960 1.13 christos /* oCanonicalizePermittedCNAMEs */
2961 1.13 christos if ( o->num_permitted_cnames > 0) {
2962 1.13 christos printf("canonicalizePermittedcnames");
2963 1.13 christos for (i = 0; i < o->num_permitted_cnames; i++) {
2964 1.13 christos printf(" %s:%s", o->permitted_cnames[i].source_list,
2965 1.13 christos o->permitted_cnames[i].target_list);
2966 1.13 christos }
2967 1.13 christos printf("\n");
2968 1.13 christos }
2969 1.13 christos
2970 1.13 christos /* oControlPersist */
2971 1.13 christos if (o->control_persist == 0 || o->control_persist_timeout == 0)
2972 1.13 christos dump_cfg_fmtint(oControlPersist, o->control_persist);
2973 1.13 christos else
2974 1.13 christos dump_cfg_int(oControlPersist, o->control_persist_timeout);
2975 1.13 christos
2976 1.13 christos /* oEscapeChar */
2977 1.13 christos if (o->escape_char == SSH_ESCAPECHAR_NONE)
2978 1.13 christos printf("escapechar none\n");
2979 1.13 christos else {
2980 1.19 christos vis(buf, o->escape_char, VIS_WHITE, 0);
2981 1.19 christos printf("escapechar %s\n", buf);
2982 1.13 christos }
2983 1.13 christos
2984 1.13 christos /* oIPQoS */
2985 1.13 christos printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2986 1.13 christos printf("%s\n", iptos2str(o->ip_qos_bulk));
2987 1.13 christos
2988 1.13 christos /* oRekeyLimit */
2989 1.18 christos printf("rekeylimit %llu %d\n",
2990 1.18 christos (unsigned long long)o->rekey_limit, o->rekey_interval);
2991 1.13 christos
2992 1.13 christos /* oStreamLocalBindMask */
2993 1.13 christos printf("streamlocalbindmask 0%o\n",
2994 1.13 christos o->fwd_opts.streamlocal_bind_mask);
2995 1.19 christos
2996 1.25 christos /* oLogFacility */
2997 1.25 christos printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2998 1.25 christos
2999 1.19 christos /* oProxyCommand / oProxyJump */
3000 1.19 christos if (o->jump_host == NULL)
3001 1.19 christos dump_cfg_string(oProxyCommand, o->proxy_command);
3002 1.19 christos else {
3003 1.19 christos /* Check for numeric addresses */
3004 1.19 christos i = strchr(o->jump_host, ':') != NULL ||
3005 1.19 christos strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
3006 1.19 christos snprintf(buf, sizeof(buf), "%d", o->jump_port);
3007 1.19 christos printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
3008 1.19 christos /* optional additional jump spec */
3009 1.19 christos o->jump_extra == NULL ? "" : o->jump_extra,
3010 1.19 christos o->jump_extra == NULL ? "" : ",",
3011 1.19 christos /* optional user */
3012 1.19 christos o->jump_user == NULL ? "" : o->jump_user,
3013 1.19 christos o->jump_user == NULL ? "" : "@",
3014 1.19 christos /* opening [ if hostname is numeric */
3015 1.19 christos i ? "[" : "",
3016 1.19 christos /* mandatory hostname */
3017 1.19 christos o->jump_host,
3018 1.19 christos /* closing ] if hostname is numeric */
3019 1.19 christos i ? "]" : "",
3020 1.19 christos /* optional port number */
3021 1.19 christos o->jump_port <= 0 ? "" : ":",
3022 1.19 christos o->jump_port <= 0 ? "" : buf);
3023 1.19 christos }
3024 1.13 christos }
3025