xref: /netbsd-src/crypto/external/bsd/openssh/dist/compat.c (revision b1066cf3cd3cc4bc809a7791a10cc5857ad5d501)
1*b1066cf3Schristos /*	$NetBSD: compat.c,v 1.26 2023/07/26 17:58:15 christos Exp $	*/
2*b1066cf3Schristos /* $OpenBSD: compat.c,v 1.126 2023/03/06 12:14:48 dtucker Exp $ */
3ca32bd8dSchristos /*
4ca32bd8dSchristos  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
5ca32bd8dSchristos  *
6ca32bd8dSchristos  * Redistribution and use in source and binary forms, with or without
7ca32bd8dSchristos  * modification, are permitted provided that the following conditions
8ca32bd8dSchristos  * are met:
9ca32bd8dSchristos  * 1. Redistributions of source code must retain the above copyright
10ca32bd8dSchristos  *    notice, this list of conditions and the following disclaimer.
11ca32bd8dSchristos  * 2. Redistributions in binary form must reproduce the above copyright
12ca32bd8dSchristos  *    notice, this list of conditions and the following disclaimer in the
13ca32bd8dSchristos  *    documentation and/or other materials provided with the distribution.
14ca32bd8dSchristos  *
15ca32bd8dSchristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16ca32bd8dSchristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17ca32bd8dSchristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18ca32bd8dSchristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19ca32bd8dSchristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20ca32bd8dSchristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21ca32bd8dSchristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22ca32bd8dSchristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23ca32bd8dSchristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24ca32bd8dSchristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25ca32bd8dSchristos  */
26ca32bd8dSchristos 
27313c6c94Schristos #include "includes.h"
28*b1066cf3Schristos __RCSID("$NetBSD: compat.c,v 1.26 2023/07/26 17:58:15 christos Exp $");
29ca32bd8dSchristos #include <sys/types.h>
30ca32bd8dSchristos 
31ca32bd8dSchristos #include <stdlib.h>
32ca32bd8dSchristos #include <string.h>
33ca32bd8dSchristos #include <stdarg.h>
34ca32bd8dSchristos 
35ca32bd8dSchristos #include "xmalloc.h"
36ca32bd8dSchristos #include "packet.h"
37ca32bd8dSchristos #include "compat.h"
38ca32bd8dSchristos #include "log.h"
39ca32bd8dSchristos #include "match.h"
40ca32bd8dSchristos 
4117418e98Schristos /* determine bug flags from SSH protocol banner */
4217418e98Schristos void
compat_banner(struct ssh * ssh,const char * version)4317418e98Schristos compat_banner(struct ssh *ssh, const char *version)
44ca32bd8dSchristos {
45ca32bd8dSchristos 	int i;
46ca32bd8dSchristos 	static struct {
47185c8f97Schristos 		const char	*pat;
48ca32bd8dSchristos 		int	bugs;
49ca32bd8dSchristos 	} check[] = {
50ca32bd8dSchristos 		{ "OpenSSH_2.*,"
51ca32bd8dSchristos 		  "OpenSSH_3.0*,"
5255a4608bSchristos 		  "OpenSSH_3.1*",	SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR|
5355a4608bSchristos 					SSH_BUG_SIGTYPE},
5455a4608bSchristos 		{ "OpenSSH_3.*",	SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE },
5555a4608bSchristos 		{ "Sun_SSH_1.0*",	SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
5655a4608bSchristos 					SSH_BUG_SIGTYPE},
57ffae97bbSchristos 		{ "OpenSSH_2*,"
58ffae97bbSchristos 		  "OpenSSH_3*,"
5955a4608bSchristos 		  "OpenSSH_4*",		SSH_BUG_SIGTYPE },
6055a4608bSchristos 		{ "OpenSSH_5*",		SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT|
6155a4608bSchristos 					SSH_BUG_SIGTYPE},
6255a4608bSchristos 		{ "OpenSSH_6.6.1*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
638a4530f9Schristos 		{ "OpenSSH_6.5*,"
6455a4608bSchristos 		  "OpenSSH_6.6*",	SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
6555a4608bSchristos 					SSH_BUG_SIGTYPE},
66b592f463Schristos 		{ "OpenSSH_7.4*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
67b592f463Schristos 					SSH_BUG_SIGTYPE74},
6855a4608bSchristos 		{ "OpenSSH_7.0*,"
6955a4608bSchristos 		  "OpenSSH_7.1*,"
7055a4608bSchristos 		  "OpenSSH_7.2*,"
7155a4608bSchristos 		  "OpenSSH_7.3*,"
7255a4608bSchristos 		  "OpenSSH_7.5*,"
7355a4608bSchristos 		  "OpenSSH_7.6*,"
7455a4608bSchristos 		  "OpenSSH_7.7*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
75ca32bd8dSchristos 		{ "OpenSSH*",		SSH_NEW_OPENSSH },
76ca32bd8dSchristos 		{ "*MindTerm*",		0 },
77ca32bd8dSchristos 		{ "3.0.*",		SSH_BUG_DEBUG },
78ca32bd8dSchristos 		{ "3.0 SecureCRT*",	SSH_OLD_SESSIONID },
79ca32bd8dSchristos 		{ "1.7 SecureFX*",	SSH_OLD_SESSIONID },
808395c133Schristos 		{ "Cisco-1.*",		SSH_BUG_DHGEX_LARGE|
818395c133Schristos 					SSH_BUG_HOSTKEYS },
82ca32bd8dSchristos 		{ "*SSH_Version_Mapper*",
83ca32bd8dSchristos 					SSH_BUG_SCANNER },
848395c133Schristos 		{ "PuTTY_Local:*,"	/* dev versions < Sep 2014 */
858395c133Schristos 		  "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */
864054ffb0Schristos 		  "PuTTY_Release_0.5*,"	/* 0.58-0.59 */
874054ffb0Schristos 		  "PuTTY_Release_0.60*,"
884054ffb0Schristos 		  "PuTTY_Release_0.61*,"
894054ffb0Schristos 		  "PuTTY_Release_0.62*,"
904054ffb0Schristos 		  "PuTTY_Release_0.63*,"
914054ffb0Schristos 		  "PuTTY_Release_0.64*",
924054ffb0Schristos 					SSH_OLD_DHGEX },
93b1c8f1c6Schristos 		{ "FuTTY*",		SSH_OLD_DHGEX }, /* Putty Fork */
94ca32bd8dSchristos 		{ "Probe-*",
95ca32bd8dSchristos 					SSH_BUG_PROBE },
964054ffb0Schristos 		{ "TeraTerm SSH*,"
974054ffb0Schristos 		  "TTSSH/1.5.*,"
984054ffb0Schristos 		  "TTSSH/2.1*,"
994054ffb0Schristos 		  "TTSSH/2.2*,"
1004054ffb0Schristos 		  "TTSSH/2.3*,"
1014054ffb0Schristos 		  "TTSSH/2.4*,"
1024054ffb0Schristos 		  "TTSSH/2.5*,"
1034054ffb0Schristos 		  "TTSSH/2.6*,"
1044054ffb0Schristos 		  "TTSSH/2.70*,"
1054054ffb0Schristos 		  "TTSSH/2.71*,"
1064054ffb0Schristos 		  "TTSSH/2.72*",	SSH_BUG_HOSTKEYS },
107b1c8f1c6Schristos 		{ "WinSCP_release_4*,"
108b1c8f1c6Schristos 		  "WinSCP_release_5.0*,"
1097a183406Schristos 		  "WinSCP_release_5.1,"
1107a183406Schristos 		  "WinSCP_release_5.1.*,"
1117a183406Schristos 		  "WinSCP_release_5.5,"
1127a183406Schristos 		  "WinSCP_release_5.5.*,"
1137a183406Schristos 		  "WinSCP_release_5.6,"
1147a183406Schristos 		  "WinSCP_release_5.6.*,"
115b1c8f1c6Schristos 		  "WinSCP_release_5.7,"
116b1c8f1c6Schristos 		  "WinSCP_release_5.7.1,"
117b1c8f1c6Schristos 		  "WinSCP_release_5.7.2,"
118b1c8f1c6Schristos 		  "WinSCP_release_5.7.3,"
119b1c8f1c6Schristos 		  "WinSCP_release_5.7.4",
120b1c8f1c6Schristos 					SSH_OLD_DHGEX },
121ffae97bbSchristos 		{ "ConfD-*",
122ffae97bbSchristos 					SSH_BUG_UTF8TTYMODE },
12355a4608bSchristos 		{ "Twisted_*",		0 },
12455a4608bSchristos 		{ "Twisted*",		SSH_BUG_DEBUG },
125ca32bd8dSchristos 		{ NULL,			0 }
126ca32bd8dSchristos 	};
127ca32bd8dSchristos 
128ca32bd8dSchristos 	/* process table, return first match */
12917418e98Schristos 	ssh->compat = 0;
130ca32bd8dSchristos 	for (i = 0; check[i].pat; i++) {
1314054ffb0Schristos 		if (match_pattern_list(version, check[i].pat, 0) == 1) {
13217418e98Schristos 			debug_f("match: %s pat %s compat 0x%08x",
133e4d43b82Schristos 			    version, check[i].pat, check[i].bugs);
13417418e98Schristos 			ssh->compat = check[i].bugs;
13517418e98Schristos 			return;
136313c6c94Schristos 		}
137313c6c94Schristos 	}
13817418e98Schristos 	debug_f("no match: %s", version);
139ca32bd8dSchristos }
140ca32bd8dSchristos 
141e160b4e8Schristos /* Always returns pointer to allocated memory, caller must free. */
142e160b4e8Schristos char *
compat_kex_proposal(struct ssh * ssh,const char * p)143*b1066cf3Schristos compat_kex_proposal(struct ssh *ssh, const char *p)
1448a4530f9Schristos {
145*b1066cf3Schristos 	char *cp = NULL, *cp2 = NULL;
146e160b4e8Schristos 
14717418e98Schristos 	if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
148e160b4e8Schristos 		return xstrdup(p);
14917418e98Schristos 	debug2_f("original KEX proposal: %s", p);
15017418e98Schristos 	if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
151*b1066cf3Schristos 		if ((cp = match_filter_denylist(p,
15241768fc1Schristos 		    "curve25519-sha256@libssh.org")) == NULL)
1532d3b0f52Schristos 			fatal("match_filter_denylist failed");
15417418e98Schristos 	if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
155*b1066cf3Schristos 		if ((cp2 = match_filter_denylist(cp ? cp : p,
15641768fc1Schristos 		    "diffie-hellman-group-exchange-sha256,"
15741768fc1Schristos 		    "diffie-hellman-group-exchange-sha1")) == NULL)
1582d3b0f52Schristos 			fatal("match_filter_denylist failed");
159e160b4e8Schristos 		free(cp);
160*b1066cf3Schristos 		cp = cp2;
1614054ffb0Schristos 	}
162*b1066cf3Schristos 	if (cp == NULL || *cp == '\0')
1638a4530f9Schristos 		fatal("No supported key exchange algorithms found");
164*b1066cf3Schristos 	debug2_f("compat KEX proposal: %s", cp);
165*b1066cf3Schristos 	return cp;
1668a4530f9Schristos }
1678a4530f9Schristos 
168