xref: /dflybsd-src/crypto/openssh/compat.c (revision ba1276acd1c8c22d225b1bcf370a14c878644f44)
1*ba1276acSMatthew Dillon /* $OpenBSD: compat.c,v 1.126 2023/03/06 12:14:48 dtucker Exp $ */
218de8d7fSPeter Avalos /*
318de8d7fSPeter Avalos  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
418de8d7fSPeter Avalos  *
518de8d7fSPeter Avalos  * Redistribution and use in source and binary forms, with or without
618de8d7fSPeter Avalos  * modification, are permitted provided that the following conditions
718de8d7fSPeter Avalos  * are met:
818de8d7fSPeter Avalos  * 1. Redistributions of source code must retain the above copyright
918de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer.
1018de8d7fSPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
1118de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
1218de8d7fSPeter Avalos  *    documentation and/or other materials provided with the distribution.
1318de8d7fSPeter Avalos  *
1418de8d7fSPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1518de8d7fSPeter Avalos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1618de8d7fSPeter Avalos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1718de8d7fSPeter Avalos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1818de8d7fSPeter Avalos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1918de8d7fSPeter Avalos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2018de8d7fSPeter Avalos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2118de8d7fSPeter Avalos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2218de8d7fSPeter Avalos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2318de8d7fSPeter Avalos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2418de8d7fSPeter Avalos  */
2518de8d7fSPeter Avalos 
2618de8d7fSPeter Avalos #include "includes.h"
2718de8d7fSPeter Avalos 
2818de8d7fSPeter Avalos #include <sys/types.h>
2918de8d7fSPeter Avalos 
3018de8d7fSPeter Avalos #include <stdlib.h>
3118de8d7fSPeter Avalos #include <string.h>
3218de8d7fSPeter Avalos #include <stdarg.h>
3318de8d7fSPeter Avalos 
3418de8d7fSPeter Avalos #include "xmalloc.h"
3518de8d7fSPeter Avalos #include "packet.h"
3618de8d7fSPeter Avalos #include "compat.h"
3718de8d7fSPeter Avalos #include "log.h"
3818de8d7fSPeter Avalos #include "match.h"
3918de8d7fSPeter Avalos 
4050a69bb5SSascha Wildner /* determine bug flags from SSH protocol banner */
4150a69bb5SSascha Wildner void
compat_banner(struct ssh * ssh,const char * version)4250a69bb5SSascha Wildner compat_banner(struct ssh *ssh, const char *version)
4318de8d7fSPeter Avalos {
4418de8d7fSPeter Avalos 	int i;
4518de8d7fSPeter Avalos 	static struct {
4618de8d7fSPeter Avalos 		char	*pat;
4718de8d7fSPeter Avalos 		int	bugs;
4818de8d7fSPeter Avalos 	} check[] = {
4918de8d7fSPeter Avalos 		{ "OpenSSH_2.*,"
5018de8d7fSPeter Avalos 		  "OpenSSH_3.0*,"
51664f4763Szrj 		  "OpenSSH_3.1*",	SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR|
52664f4763Szrj 					SSH_BUG_SIGTYPE},
53664f4763Szrj 		{ "OpenSSH_3.*",	SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE },
54664f4763Szrj 		{ "Sun_SSH_1.0*",	SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
55664f4763Szrj 					SSH_BUG_SIGTYPE},
56664f4763Szrj 		{ "OpenSSH_2*,"
57664f4763Szrj 		  "OpenSSH_3*,"
58664f4763Szrj 		  "OpenSSH_4*",		SSH_BUG_SIGTYPE },
59664f4763Szrj 		{ "OpenSSH_5*",		SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT|
60664f4763Szrj 					SSH_BUG_SIGTYPE},
61664f4763Szrj 		{ "OpenSSH_6.6.1*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
6236e94dc5SPeter Avalos 		{ "OpenSSH_6.5*,"
63664f4763Szrj 		  "OpenSSH_6.6*",	SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
64664f4763Szrj 					SSH_BUG_SIGTYPE},
6550a69bb5SSascha Wildner 		{ "OpenSSH_7.4*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
6650a69bb5SSascha Wildner 					SSH_BUG_SIGTYPE74},
67664f4763Szrj 		{ "OpenSSH_7.0*,"
68664f4763Szrj 		  "OpenSSH_7.1*,"
69664f4763Szrj 		  "OpenSSH_7.2*,"
70664f4763Szrj 		  "OpenSSH_7.3*,"
71664f4763Szrj 		  "OpenSSH_7.5*,"
72664f4763Szrj 		  "OpenSSH_7.6*,"
73664f4763Szrj 		  "OpenSSH_7.7*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
74cb5eb4f1SPeter Avalos 		{ "OpenSSH*",		SSH_NEW_OPENSSH },
7518de8d7fSPeter Avalos 		{ "*MindTerm*",		0 },
7618de8d7fSPeter Avalos 		{ "3.0.*",		SSH_BUG_DEBUG },
7718de8d7fSPeter Avalos 		{ "3.0 SecureCRT*",	SSH_OLD_SESSIONID },
7818de8d7fSPeter Avalos 		{ "1.7 SecureFX*",	SSH_OLD_SESSIONID },
79e9778795SPeter Avalos 		{ "Cisco-1.*",		SSH_BUG_DHGEX_LARGE|
80e9778795SPeter Avalos 					SSH_BUG_HOSTKEYS },
8118de8d7fSPeter Avalos 		{ "*SSH_Version_Mapper*",
8218de8d7fSPeter Avalos 					SSH_BUG_SCANNER },
83e9778795SPeter Avalos 		{ "PuTTY_Local:*,"	/* dev versions < Sep 2014 */
84e9778795SPeter Avalos 		  "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */
85e9778795SPeter Avalos 		  "PuTTY_Release_0.5*,"	/* 0.58-0.59 */
86e9778795SPeter Avalos 		  "PuTTY_Release_0.60*,"
87e9778795SPeter Avalos 		  "PuTTY_Release_0.61*,"
88e9778795SPeter Avalos 		  "PuTTY_Release_0.62*,"
89e9778795SPeter Avalos 		  "PuTTY_Release_0.63*,"
90e9778795SPeter Avalos 		  "PuTTY_Release_0.64*",
91e9778795SPeter Avalos 					SSH_OLD_DHGEX },
92e9778795SPeter Avalos 		{ "FuTTY*",		SSH_OLD_DHGEX }, /* Putty Fork */
9318de8d7fSPeter Avalos 		{ "Probe-*",
9418de8d7fSPeter Avalos 					SSH_BUG_PROBE },
95e9778795SPeter Avalos 		{ "TeraTerm SSH*,"
96e9778795SPeter Avalos 		  "TTSSH/1.5.*,"
97e9778795SPeter Avalos 		  "TTSSH/2.1*,"
98e9778795SPeter Avalos 		  "TTSSH/2.2*,"
99e9778795SPeter Avalos 		  "TTSSH/2.3*,"
100e9778795SPeter Avalos 		  "TTSSH/2.4*,"
101e9778795SPeter Avalos 		  "TTSSH/2.5*,"
102e9778795SPeter Avalos 		  "TTSSH/2.6*,"
103e9778795SPeter Avalos 		  "TTSSH/2.70*,"
104e9778795SPeter Avalos 		  "TTSSH/2.71*,"
105e9778795SPeter Avalos 		  "TTSSH/2.72*",	SSH_BUG_HOSTKEYS },
106e9778795SPeter Avalos 		{ "WinSCP_release_4*,"
107e9778795SPeter Avalos 		  "WinSCP_release_5.0*,"
108ce74bacaSMatthew Dillon 		  "WinSCP_release_5.1,"
109ce74bacaSMatthew Dillon 		  "WinSCP_release_5.1.*,"
110ce74bacaSMatthew Dillon 		  "WinSCP_release_5.5,"
111ce74bacaSMatthew Dillon 		  "WinSCP_release_5.5.*,"
112ce74bacaSMatthew Dillon 		  "WinSCP_release_5.6,"
113ce74bacaSMatthew Dillon 		  "WinSCP_release_5.6.*,"
114e9778795SPeter Avalos 		  "WinSCP_release_5.7,"
115e9778795SPeter Avalos 		  "WinSCP_release_5.7.1,"
116e9778795SPeter Avalos 		  "WinSCP_release_5.7.2,"
117e9778795SPeter Avalos 		  "WinSCP_release_5.7.3,"
118e9778795SPeter Avalos 		  "WinSCP_release_5.7.4",
119e9778795SPeter Avalos 					SSH_OLD_DHGEX },
120664f4763Szrj 		{ "ConfD-*",
121664f4763Szrj 					SSH_BUG_UTF8TTYMODE },
122664f4763Szrj 		{ "Twisted_*",		0 },
123664f4763Szrj 		{ "Twisted*",		SSH_BUG_DEBUG },
12418de8d7fSPeter Avalos 		{ NULL,			0 }
12518de8d7fSPeter Avalos 	};
12618de8d7fSPeter Avalos 
12718de8d7fSPeter Avalos 	/* process table, return first match */
12850a69bb5SSascha Wildner 	ssh->compat = 0;
12918de8d7fSPeter Avalos 	for (i = 0; check[i].pat; i++) {
130e9778795SPeter Avalos 		if (match_pattern_list(version, check[i].pat, 0) == 1) {
13150a69bb5SSascha Wildner 			debug_f("match: %s pat %s compat 0x%08x",
132e9778795SPeter Avalos 			    version, check[i].pat, check[i].bugs);
13350a69bb5SSascha Wildner 			ssh->compat = check[i].bugs;
13450a69bb5SSascha Wildner 			return;
13518de8d7fSPeter Avalos 		}
13618de8d7fSPeter Avalos 	}
13750a69bb5SSascha Wildner 	debug_f("no match: %s", version);
13818de8d7fSPeter Avalos }
13918de8d7fSPeter Avalos 
140ee116499SAntonio Huete Jimenez /* Always returns pointer to allocated memory, caller must free. */
14118de8d7fSPeter Avalos char *
compat_kex_proposal(struct ssh * ssh,const char * p)142*ba1276acSMatthew Dillon compat_kex_proposal(struct ssh *ssh, const char *p)
14318de8d7fSPeter Avalos {
144*ba1276acSMatthew Dillon 	char *cp = NULL, *cp2 = NULL;
145ee116499SAntonio Huete Jimenez 
14650a69bb5SSascha Wildner 	if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
147ee116499SAntonio Huete Jimenez 		return xstrdup(p);
14850a69bb5SSascha Wildner 	debug2_f("original KEX proposal: %s", p);
14950a69bb5SSascha Wildner 	if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
150*ba1276acSMatthew Dillon 		if ((cp = match_filter_denylist(p,
151ce74bacaSMatthew Dillon 		    "curve25519-sha256@libssh.org")) == NULL)
15250a69bb5SSascha Wildner 			fatal("match_filter_denylist failed");
15350a69bb5SSascha Wildner 	if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
154*ba1276acSMatthew Dillon 		if ((cp2 = match_filter_denylist(cp ? cp : p,
155ce74bacaSMatthew Dillon 		    "diffie-hellman-group-exchange-sha256,"
156ce74bacaSMatthew Dillon 		    "diffie-hellman-group-exchange-sha1")) == NULL)
15750a69bb5SSascha Wildner 			fatal("match_filter_denylist failed");
158ee116499SAntonio Huete Jimenez 		free(cp);
159*ba1276acSMatthew Dillon 		cp = cp2;
160e9778795SPeter Avalos 	}
161*ba1276acSMatthew Dillon 	if (cp == NULL || *cp == '\0')
16236e94dc5SPeter Avalos 		fatal("No supported key exchange algorithms found");
163*ba1276acSMatthew Dillon 	debug2_f("compat KEX proposal: %s", cp);
164*ba1276acSMatthew Dillon 	return cp;
16518de8d7fSPeter Avalos }
16636e94dc5SPeter Avalos 
167