1*19261079SEd Maste /* $OpenBSD: compat.c,v 1.118 2021/06/06 03:40:39 djm Exp $ */ 2511b41d2SMark Murray /* 3af12a3e7SDag-Erling Smørgrav * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 4511b41d2SMark Murray * 5511b41d2SMark Murray * Redistribution and use in source and binary forms, with or without 6511b41d2SMark Murray * modification, are permitted provided that the following conditions 7511b41d2SMark Murray * are met: 8511b41d2SMark Murray * 1. Redistributions of source code must retain the above copyright 9511b41d2SMark Murray * notice, this list of conditions and the following disclaimer. 10511b41d2SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 11511b41d2SMark Murray * notice, this list of conditions and the following disclaimer in the 12511b41d2SMark Murray * documentation and/or other materials provided with the distribution. 13511b41d2SMark Murray * 14511b41d2SMark Murray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15511b41d2SMark Murray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16511b41d2SMark Murray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17511b41d2SMark Murray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18511b41d2SMark Murray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19511b41d2SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20511b41d2SMark Murray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21511b41d2SMark Murray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22511b41d2SMark Murray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23511b41d2SMark Murray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24511b41d2SMark Murray */ 25511b41d2SMark Murray 26511b41d2SMark Murray #include "includes.h" 27511b41d2SMark Murray 28333ee039SDag-Erling Smørgrav #include <sys/types.h> 29333ee039SDag-Erling Smørgrav 30333ee039SDag-Erling Smørgrav #include <stdlib.h> 31333ee039SDag-Erling Smørgrav #include <string.h> 32333ee039SDag-Erling Smørgrav #include <stdarg.h> 33333ee039SDag-Erling Smørgrav 34333ee039SDag-Erling Smørgrav #include "xmalloc.h" 35a04a10f8SKris Kennaway #include "packet.h" 36a04a10f8SKris Kennaway #include "compat.h" 37ca3176e7SBrian Feldman #include "log.h" 38af12a3e7SDag-Erling Smørgrav #include "match.h" 39d93a896eSDag-Erling Smørgrav #include "kex.h" 40511b41d2SMark Murray 41*19261079SEd Maste /* determine bug flags from SSH protocol banner */ 42*19261079SEd Maste void 43*19261079SEd Maste compat_banner(struct ssh *ssh, const char *version) 44a04a10f8SKris Kennaway { 45af12a3e7SDag-Erling Smørgrav int i; 465b9b2fafSBrian Feldman static struct { 475b9b2fafSBrian Feldman char *pat; 48a04a10f8SKris Kennaway int bugs; 49a04a10f8SKris Kennaway } check[] = { 5080628bacSDag-Erling Smørgrav { "OpenSSH_2.*," 5180628bacSDag-Erling Smørgrav "OpenSSH_3.0*," 52190cef3dSDag-Erling Smørgrav "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR| 53190cef3dSDag-Erling Smørgrav SSH_BUG_SIGTYPE}, 54190cef3dSDag-Erling Smørgrav { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE }, 55190cef3dSDag-Erling Smørgrav { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| 56190cef3dSDag-Erling Smørgrav SSH_BUG_SIGTYPE}, 5747dd1d1bSDag-Erling Smørgrav { "OpenSSH_2*," 5847dd1d1bSDag-Erling Smørgrav "OpenSSH_3*," 59190cef3dSDag-Erling Smørgrav "OpenSSH_4*", SSH_BUG_SIGTYPE }, 60190cef3dSDag-Erling Smørgrav { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT| 61190cef3dSDag-Erling Smørgrav SSH_BUG_SIGTYPE}, 62190cef3dSDag-Erling Smørgrav { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE}, 6330a03439SDag-Erling Smørgrav { "OpenSSH_6.5*," 64190cef3dSDag-Erling Smørgrav "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD| 65190cef3dSDag-Erling Smørgrav SSH_BUG_SIGTYPE}, 66*19261079SEd Maste { "OpenSSH_7.4*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE| 67*19261079SEd Maste SSH_BUG_SIGTYPE74}, 68190cef3dSDag-Erling Smørgrav { "OpenSSH_7.0*," 69190cef3dSDag-Erling Smørgrav "OpenSSH_7.1*," 70190cef3dSDag-Erling Smørgrav "OpenSSH_7.2*," 71190cef3dSDag-Erling Smørgrav "OpenSSH_7.3*," 72190cef3dSDag-Erling Smørgrav "OpenSSH_7.4*," 73190cef3dSDag-Erling Smørgrav "OpenSSH_7.5*," 74190cef3dSDag-Erling Smørgrav "OpenSSH_7.6*," 75190cef3dSDag-Erling Smørgrav "OpenSSH_7.7*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE}, 76cce7d346SDag-Erling Smørgrav { "OpenSSH*", SSH_NEW_OPENSSH }, 77af12a3e7SDag-Erling Smørgrav { "*MindTerm*", 0 }, 78af12a3e7SDag-Erling Smørgrav { "3.0.*", SSH_BUG_DEBUG }, 79af12a3e7SDag-Erling Smørgrav { "3.0 SecureCRT*", SSH_OLD_SESSIONID }, 80af12a3e7SDag-Erling Smørgrav { "1.7 SecureFX*", SSH_OLD_SESSIONID }, 81af12a3e7SDag-Erling Smørgrav { "1.2.18*," 82af12a3e7SDag-Erling Smørgrav "1.2.19*," 83af12a3e7SDag-Erling Smørgrav "1.2.20*," 84af12a3e7SDag-Erling Smørgrav "1.2.21*," 85cf2b5f3bSDag-Erling Smørgrav "1.2.22*", SSH_BUG_IGNOREMSG }, 8680628bacSDag-Erling Smørgrav { "1.3.2*", /* F-Secure */ 87cf2b5f3bSDag-Erling Smørgrav SSH_BUG_IGNOREMSG }, 88eccfee6eSDag-Erling Smørgrav { "Cisco-1.*", SSH_BUG_DHGEX_LARGE| 89eccfee6eSDag-Erling Smørgrav SSH_BUG_HOSTKEYS }, 90af12a3e7SDag-Erling Smørgrav { "*SSH Compatible Server*", /* Netscreen */ 91ca3176e7SBrian Feldman SSH_BUG_PASSWORDPAD }, 92af12a3e7SDag-Erling Smørgrav { "*OSU_0*," 93af12a3e7SDag-Erling Smørgrav "OSU_1.0*," 94af12a3e7SDag-Erling Smørgrav "OSU_1.1*," 95af12a3e7SDag-Erling Smørgrav "OSU_1.2*," 96af12a3e7SDag-Erling Smørgrav "OSU_1.3*," 97af12a3e7SDag-Erling Smørgrav "OSU_1.4*," 98af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha1*," 99af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha2*," 100af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, 101af12a3e7SDag-Erling Smørgrav { "*SSH_Version_Mapper*", 102ca3176e7SBrian Feldman SSH_BUG_SCANNER }, 103eccfee6eSDag-Erling Smørgrav { "PuTTY_Local:*," /* dev versions < Sep 2014 */ 104eccfee6eSDag-Erling Smørgrav "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */ 105557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.5*," /* 0.58-0.59 */ 106557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.60*," 107557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.61*," 108557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.62*," 109557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.63*," 110557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.64*", 111557f75e5SDag-Erling Smørgrav SSH_OLD_DHGEX }, 112fc1ba28aSDag-Erling Smørgrav { "FuTTY*", SSH_OLD_DHGEX }, /* Putty Fork */ 113f388f5efSDag-Erling Smørgrav { "Probe-*", 114f388f5efSDag-Erling Smørgrav SSH_BUG_PROBE }, 115557f75e5SDag-Erling Smørgrav { "TeraTerm SSH*," 116557f75e5SDag-Erling Smørgrav "TTSSH/1.5.*," 117557f75e5SDag-Erling Smørgrav "TTSSH/2.1*," 118557f75e5SDag-Erling Smørgrav "TTSSH/2.2*," 119557f75e5SDag-Erling Smørgrav "TTSSH/2.3*," 120557f75e5SDag-Erling Smørgrav "TTSSH/2.4*," 121557f75e5SDag-Erling Smørgrav "TTSSH/2.5*," 122557f75e5SDag-Erling Smørgrav "TTSSH/2.6*," 123557f75e5SDag-Erling Smørgrav "TTSSH/2.70*," 124557f75e5SDag-Erling Smørgrav "TTSSH/2.71*," 125557f75e5SDag-Erling Smørgrav "TTSSH/2.72*", SSH_BUG_HOSTKEYS }, 126fc1ba28aSDag-Erling Smørgrav { "WinSCP_release_4*," 127fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.0*," 1284f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.1," 1294f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.1.*," 1304f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.5," 1314f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.5.*," 1324f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.6," 1334f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.6.*," 134fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7," 135fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.1," 136fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.2," 137fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.3," 138fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.4", 139fc1ba28aSDag-Erling Smørgrav SSH_OLD_DHGEX }, 14047dd1d1bSDag-Erling Smørgrav { "ConfD-*", 14147dd1d1bSDag-Erling Smørgrav SSH_BUG_UTF8TTYMODE }, 142190cef3dSDag-Erling Smørgrav { "Twisted_*", 0 }, 143190cef3dSDag-Erling Smørgrav { "Twisted*", SSH_BUG_DEBUG }, 144a04a10f8SKris Kennaway { NULL, 0 } 145a04a10f8SKris Kennaway }; 146af12a3e7SDag-Erling Smørgrav 147b66f2d16SKris Kennaway /* process table, return first match */ 148*19261079SEd Maste ssh->compat = 0; 1495b9b2fafSBrian Feldman for (i = 0; check[i].pat; i++) { 150557f75e5SDag-Erling Smørgrav if (match_pattern_list(version, check[i].pat, 0) == 1) { 151*19261079SEd Maste debug_f("match: %s pat %s compat 0x%08x", 152bc5531deSDag-Erling Smørgrav version, check[i].pat, check[i].bugs); 153*19261079SEd Maste ssh->compat = check[i].bugs; 154*19261079SEd Maste return; 155a04a10f8SKris Kennaway } 156a04a10f8SKris Kennaway } 157*19261079SEd Maste debug_f("no match: %s", version); 158a04a10f8SKris Kennaway } 159ca3176e7SBrian Feldman 160f7167e0eSDag-Erling Smørgrav char * 161*19261079SEd Maste compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) 162f7167e0eSDag-Erling Smørgrav { 163*19261079SEd Maste if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) 164f7167e0eSDag-Erling Smørgrav return cipher_prop; 165*19261079SEd Maste debug2_f("original cipher proposal: %s", cipher_prop); 166*19261079SEd Maste if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) 167*19261079SEd Maste fatal("match_filter_denylist failed"); 168*19261079SEd Maste debug2_f("compat cipher proposal: %s", cipher_prop); 169f7167e0eSDag-Erling Smørgrav if (*cipher_prop == '\0') 170f7167e0eSDag-Erling Smørgrav fatal("No supported ciphers found"); 171f7167e0eSDag-Erling Smørgrav return cipher_prop; 172f7167e0eSDag-Erling Smørgrav } 173f7167e0eSDag-Erling Smørgrav 174f7167e0eSDag-Erling Smørgrav char * 175*19261079SEd Maste compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) 176f7167e0eSDag-Erling Smørgrav { 177*19261079SEd Maste if (!(ssh->compat & SSH_BUG_RSASIGMD5)) 178f7167e0eSDag-Erling Smørgrav return pkalg_prop; 179*19261079SEd Maste debug2_f("original public key proposal: %s", pkalg_prop); 180*19261079SEd Maste if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) 181*19261079SEd Maste fatal("match_filter_denylist failed"); 182*19261079SEd Maste debug2_f("compat public key proposal: %s", pkalg_prop); 183f7167e0eSDag-Erling Smørgrav if (*pkalg_prop == '\0') 184f7167e0eSDag-Erling Smørgrav fatal("No supported PK algorithms found"); 185f7167e0eSDag-Erling Smørgrav return pkalg_prop; 186f7167e0eSDag-Erling Smørgrav } 187f7167e0eSDag-Erling Smørgrav 18830a03439SDag-Erling Smørgrav char * 189*19261079SEd Maste compat_kex_proposal(struct ssh *ssh, char *p) 19030a03439SDag-Erling Smørgrav { 191*19261079SEd Maste if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) 192557f75e5SDag-Erling Smørgrav return p; 193*19261079SEd Maste debug2_f("original KEX proposal: %s", p); 194*19261079SEd Maste if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) 195*19261079SEd Maste if ((p = match_filter_denylist(p, 196d93a896eSDag-Erling Smørgrav "curve25519-sha256@libssh.org")) == NULL) 197*19261079SEd Maste fatal("match_filter_denylist failed"); 198*19261079SEd Maste if ((ssh->compat & SSH_OLD_DHGEX) != 0) { 199*19261079SEd Maste if ((p = match_filter_denylist(p, 200d93a896eSDag-Erling Smørgrav "diffie-hellman-group-exchange-sha256," 201d93a896eSDag-Erling Smørgrav "diffie-hellman-group-exchange-sha1")) == NULL) 202*19261079SEd Maste fatal("match_filter_denylist failed"); 203557f75e5SDag-Erling Smørgrav } 204*19261079SEd Maste debug2_f("compat KEX proposal: %s", p); 205557f75e5SDag-Erling Smørgrav if (*p == '\0') 20630a03439SDag-Erling Smørgrav fatal("No supported key exchange algorithms found"); 207557f75e5SDag-Erling Smørgrav return p; 20830a03439SDag-Erling Smørgrav } 20930a03439SDag-Erling Smørgrav 210