1*38a52bd3SEd Maste /* $OpenBSD: compat.c,v 1.120 2022/07/01 03:35:45 dtucker 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 4119261079SEd Maste /* determine bug flags from SSH protocol banner */ 4219261079SEd Maste void 4319261079SEd 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}, 6619261079SEd Maste { "OpenSSH_7.4*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE| 6719261079SEd 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.5*," 73190cef3dSDag-Erling Smørgrav "OpenSSH_7.6*," 74190cef3dSDag-Erling Smørgrav "OpenSSH_7.7*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE}, 75cce7d346SDag-Erling Smørgrav { "OpenSSH*", SSH_NEW_OPENSSH }, 76af12a3e7SDag-Erling Smørgrav { "*MindTerm*", 0 }, 77af12a3e7SDag-Erling Smørgrav { "3.0.*", SSH_BUG_DEBUG }, 78af12a3e7SDag-Erling Smørgrav { "3.0 SecureCRT*", SSH_OLD_SESSIONID }, 79af12a3e7SDag-Erling Smørgrav { "1.7 SecureFX*", SSH_OLD_SESSIONID }, 80af12a3e7SDag-Erling Smørgrav { "1.2.18*," 81af12a3e7SDag-Erling Smørgrav "1.2.19*," 82af12a3e7SDag-Erling Smørgrav "1.2.20*," 83af12a3e7SDag-Erling Smørgrav "1.2.21*," 84cf2b5f3bSDag-Erling Smørgrav "1.2.22*", SSH_BUG_IGNOREMSG }, 8580628bacSDag-Erling Smørgrav { "1.3.2*", /* F-Secure */ 86cf2b5f3bSDag-Erling Smørgrav SSH_BUG_IGNOREMSG }, 87eccfee6eSDag-Erling Smørgrav { "Cisco-1.*", SSH_BUG_DHGEX_LARGE| 88eccfee6eSDag-Erling Smørgrav SSH_BUG_HOSTKEYS }, 89af12a3e7SDag-Erling Smørgrav { "*SSH Compatible Server*", /* Netscreen */ 90ca3176e7SBrian Feldman SSH_BUG_PASSWORDPAD }, 91af12a3e7SDag-Erling Smørgrav { "*OSU_0*," 92af12a3e7SDag-Erling Smørgrav "OSU_1.0*," 93af12a3e7SDag-Erling Smørgrav "OSU_1.1*," 94af12a3e7SDag-Erling Smørgrav "OSU_1.2*," 95af12a3e7SDag-Erling Smørgrav "OSU_1.3*," 96af12a3e7SDag-Erling Smørgrav "OSU_1.4*," 97af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha1*," 98af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha2*," 99af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, 100af12a3e7SDag-Erling Smørgrav { "*SSH_Version_Mapper*", 101ca3176e7SBrian Feldman SSH_BUG_SCANNER }, 102eccfee6eSDag-Erling Smørgrav { "PuTTY_Local:*," /* dev versions < Sep 2014 */ 103eccfee6eSDag-Erling Smørgrav "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */ 104557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.5*," /* 0.58-0.59 */ 105557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.60*," 106557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.61*," 107557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.62*," 108557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.63*," 109557f75e5SDag-Erling Smørgrav "PuTTY_Release_0.64*", 110557f75e5SDag-Erling Smørgrav SSH_OLD_DHGEX }, 111fc1ba28aSDag-Erling Smørgrav { "FuTTY*", SSH_OLD_DHGEX }, /* Putty Fork */ 112f388f5efSDag-Erling Smørgrav { "Probe-*", 113f388f5efSDag-Erling Smørgrav SSH_BUG_PROBE }, 114557f75e5SDag-Erling Smørgrav { "TeraTerm SSH*," 115557f75e5SDag-Erling Smørgrav "TTSSH/1.5.*," 116557f75e5SDag-Erling Smørgrav "TTSSH/2.1*," 117557f75e5SDag-Erling Smørgrav "TTSSH/2.2*," 118557f75e5SDag-Erling Smørgrav "TTSSH/2.3*," 119557f75e5SDag-Erling Smørgrav "TTSSH/2.4*," 120557f75e5SDag-Erling Smørgrav "TTSSH/2.5*," 121557f75e5SDag-Erling Smørgrav "TTSSH/2.6*," 122557f75e5SDag-Erling Smørgrav "TTSSH/2.70*," 123557f75e5SDag-Erling Smørgrav "TTSSH/2.71*," 124557f75e5SDag-Erling Smørgrav "TTSSH/2.72*", SSH_BUG_HOSTKEYS }, 125fc1ba28aSDag-Erling Smørgrav { "WinSCP_release_4*," 126fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.0*," 1274f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.1," 1284f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.1.*," 1294f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.5," 1304f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.5.*," 1314f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.6," 1324f52dfbbSDag-Erling Smørgrav "WinSCP_release_5.6.*," 133fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7," 134fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.1," 135fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.2," 136fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.3," 137fc1ba28aSDag-Erling Smørgrav "WinSCP_release_5.7.4", 138fc1ba28aSDag-Erling Smørgrav SSH_OLD_DHGEX }, 13947dd1d1bSDag-Erling Smørgrav { "ConfD-*", 14047dd1d1bSDag-Erling Smørgrav SSH_BUG_UTF8TTYMODE }, 141190cef3dSDag-Erling Smørgrav { "Twisted_*", 0 }, 142190cef3dSDag-Erling Smørgrav { "Twisted*", SSH_BUG_DEBUG }, 143a04a10f8SKris Kennaway { NULL, 0 } 144a04a10f8SKris Kennaway }; 145af12a3e7SDag-Erling Smørgrav 146b66f2d16SKris Kennaway /* process table, return first match */ 14719261079SEd Maste ssh->compat = 0; 1485b9b2fafSBrian Feldman for (i = 0; check[i].pat; i++) { 149557f75e5SDag-Erling Smørgrav if (match_pattern_list(version, check[i].pat, 0) == 1) { 15019261079SEd Maste debug_f("match: %s pat %s compat 0x%08x", 151bc5531deSDag-Erling Smørgrav version, check[i].pat, check[i].bugs); 15219261079SEd Maste ssh->compat = check[i].bugs; 15319261079SEd Maste return; 154a04a10f8SKris Kennaway } 155a04a10f8SKris Kennaway } 15619261079SEd Maste debug_f("no match: %s", version); 157a04a10f8SKris Kennaway } 158ca3176e7SBrian Feldman 159*38a52bd3SEd Maste /* Always returns pointer to allocated memory, caller must free. */ 160f7167e0eSDag-Erling Smørgrav char * 16119261079SEd Maste compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) 162f7167e0eSDag-Erling Smørgrav { 16319261079SEd Maste if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) 164*38a52bd3SEd Maste return xstrdup(cipher_prop); 16519261079SEd Maste debug2_f("original cipher proposal: %s", cipher_prop); 16619261079SEd Maste if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) 16719261079SEd Maste fatal("match_filter_denylist failed"); 16819261079SEd 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 174*38a52bd3SEd Maste /* Always returns pointer to allocated memory, caller must free. */ 175f7167e0eSDag-Erling Smørgrav char * 17619261079SEd Maste compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) 177f7167e0eSDag-Erling Smørgrav { 17819261079SEd Maste if (!(ssh->compat & SSH_BUG_RSASIGMD5)) 179*38a52bd3SEd Maste return xstrdup(pkalg_prop); 18019261079SEd Maste debug2_f("original public key proposal: %s", pkalg_prop); 18119261079SEd Maste if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) 18219261079SEd Maste fatal("match_filter_denylist failed"); 18319261079SEd Maste debug2_f("compat public key proposal: %s", pkalg_prop); 184f7167e0eSDag-Erling Smørgrav if (*pkalg_prop == '\0') 185f7167e0eSDag-Erling Smørgrav fatal("No supported PK algorithms found"); 186f7167e0eSDag-Erling Smørgrav return pkalg_prop; 187f7167e0eSDag-Erling Smørgrav } 188f7167e0eSDag-Erling Smørgrav 189*38a52bd3SEd Maste /* Always returns pointer to allocated memory, caller must free. */ 19030a03439SDag-Erling Smørgrav char * 19119261079SEd Maste compat_kex_proposal(struct ssh *ssh, char *p) 19230a03439SDag-Erling Smørgrav { 193*38a52bd3SEd Maste char *cp = NULL; 194*38a52bd3SEd Maste 19519261079SEd Maste if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) 196*38a52bd3SEd Maste return xstrdup(p); 19719261079SEd Maste debug2_f("original KEX proposal: %s", p); 19819261079SEd Maste if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) 19919261079SEd Maste if ((p = match_filter_denylist(p, 200d93a896eSDag-Erling Smørgrav "curve25519-sha256@libssh.org")) == NULL) 20119261079SEd Maste fatal("match_filter_denylist failed"); 20219261079SEd Maste if ((ssh->compat & SSH_OLD_DHGEX) != 0) { 203*38a52bd3SEd Maste cp = p; 20419261079SEd Maste if ((p = match_filter_denylist(p, 205d93a896eSDag-Erling Smørgrav "diffie-hellman-group-exchange-sha256," 206d93a896eSDag-Erling Smørgrav "diffie-hellman-group-exchange-sha1")) == NULL) 20719261079SEd Maste fatal("match_filter_denylist failed"); 208*38a52bd3SEd Maste free(cp); 209557f75e5SDag-Erling Smørgrav } 21019261079SEd Maste debug2_f("compat KEX proposal: %s", p); 211557f75e5SDag-Erling Smørgrav if (*p == '\0') 21230a03439SDag-Erling Smørgrav fatal("No supported key exchange algorithms found"); 213557f75e5SDag-Erling Smørgrav return p; 21430a03439SDag-Erling Smørgrav } 21530a03439SDag-Erling Smørgrav 216