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