1511b41d2SMark Murray /* 2af12a3e7SDag-Erling Smørgrav * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3511b41d2SMark Murray * 4511b41d2SMark Murray * Redistribution and use in source and binary forms, with or without 5511b41d2SMark Murray * modification, are permitted provided that the following conditions 6511b41d2SMark Murray * are met: 7511b41d2SMark Murray * 1. Redistributions of source code must retain the above copyright 8511b41d2SMark Murray * notice, this list of conditions and the following disclaimer. 9511b41d2SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 10511b41d2SMark Murray * notice, this list of conditions and the following disclaimer in the 11511b41d2SMark Murray * documentation and/or other materials provided with the distribution. 12511b41d2SMark Murray * 13511b41d2SMark Murray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14511b41d2SMark Murray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15511b41d2SMark Murray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16511b41d2SMark Murray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17511b41d2SMark Murray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18511b41d2SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19511b41d2SMark Murray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20511b41d2SMark Murray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21511b41d2SMark Murray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22511b41d2SMark Murray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23511b41d2SMark Murray */ 24511b41d2SMark Murray 25511b41d2SMark Murray #include "includes.h" 2680628bacSDag-Erling Smørgrav RCSID("$OpenBSD: compat.c,v 1.63 2002/04/10 08:21:47 markus Exp $"); 2709958426SBrian Feldman RCSID("$FreeBSD$"); 28511b41d2SMark Murray 29af12a3e7SDag-Erling Smørgrav #include "buffer.h" 30a04a10f8SKris Kennaway #include "packet.h" 31a04a10f8SKris Kennaway #include "xmalloc.h" 32a04a10f8SKris Kennaway #include "compat.h" 33ca3176e7SBrian Feldman #include "log.h" 34af12a3e7SDag-Erling Smørgrav #include "match.h" 35511b41d2SMark Murray 36511b41d2SMark Murray int compat13 = 0; 37a04a10f8SKris Kennaway int compat20 = 0; 38a04a10f8SKris Kennaway int datafellows = 0; 39511b41d2SMark Murray 40511b41d2SMark Murray void 41a04a10f8SKris Kennaway enable_compat20(void) 42a04a10f8SKris Kennaway { 43a04a10f8SKris Kennaway verbose("Enabling compatibility mode for protocol 2.0"); 44a04a10f8SKris Kennaway compat20 = 1; 45a04a10f8SKris Kennaway } 46a04a10f8SKris Kennaway void 47511b41d2SMark Murray enable_compat13(void) 48511b41d2SMark Murray { 49511b41d2SMark Murray verbose("Enabling compatibility mode for protocol 1.3"); 50511b41d2SMark Murray compat13 = 1; 51511b41d2SMark Murray } 52a04a10f8SKris Kennaway /* datafellows bug compatibility */ 53a04a10f8SKris Kennaway void 54a04a10f8SKris Kennaway compat_datafellows(const char *version) 55a04a10f8SKris Kennaway { 56af12a3e7SDag-Erling Smørgrav int i; 575b9b2fafSBrian Feldman static struct { 585b9b2fafSBrian Feldman char *pat; 59a04a10f8SKris Kennaway int bugs; 60a04a10f8SKris Kennaway } check[] = { 61af12a3e7SDag-Erling Smørgrav { "OpenSSH-2.0*," 62af12a3e7SDag-Erling Smørgrav "OpenSSH-2.1*," 63af12a3e7SDag-Erling Smørgrav "OpenSSH_2.1*," 64af12a3e7SDag-Erling Smørgrav "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| 6580628bacSDag-Erling Smørgrav SSH_OLD_DHGEX|SSH_BUG_NOREKEY| 6680628bacSDag-Erling Smørgrav SSH_BUG_EXTEOF}, 67af12a3e7SDag-Erling Smørgrav { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| 6880628bacSDag-Erling Smørgrav SSH_OLD_DHGEX|SSH_BUG_NOREKEY| 6980628bacSDag-Erling Smørgrav SSH_BUG_EXTEOF}, 70af12a3e7SDag-Erling Smørgrav { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| 7180628bacSDag-Erling Smørgrav SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, 72af12a3e7SDag-Erling Smørgrav { "OpenSSH_2.5.0p1*," 73af12a3e7SDag-Erling Smørgrav "OpenSSH_2.5.1p1*", 74ca3176e7SBrian Feldman SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| 7580628bacSDag-Erling Smørgrav SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, 76af12a3e7SDag-Erling Smørgrav { "OpenSSH_2.5.0*," 77af12a3e7SDag-Erling Smørgrav "OpenSSH_2.5.1*," 7880628bacSDag-Erling Smørgrav "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| 7980628bacSDag-Erling Smørgrav SSH_BUG_EXTEOF}, 8080628bacSDag-Erling Smørgrav { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, 8180628bacSDag-Erling Smørgrav { "OpenSSH_2.*," 8280628bacSDag-Erling Smørgrav "OpenSSH_3.0*," 8380628bacSDag-Erling Smørgrav "OpenSSH_3.1*", SSH_BUG_EXTEOF}, 8480628bacSDag-Erling Smørgrav { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, 85af12a3e7SDag-Erling Smørgrav { "OpenSSH*", 0 }, 86af12a3e7SDag-Erling Smørgrav { "*MindTerm*", 0 }, 87af12a3e7SDag-Erling Smørgrav { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 88ca3176e7SBrian Feldman SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 89ca3176e7SBrian Feldman SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, 90af12a3e7SDag-Erling Smørgrav { "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 91ca3176e7SBrian Feldman SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 92ca3176e7SBrian Feldman SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, 93af12a3e7SDag-Erling Smørgrav { "2.0.13*," 94af12a3e7SDag-Erling Smørgrav "2.0.14*," 95af12a3e7SDag-Erling Smørgrav "2.0.15*," 96af12a3e7SDag-Erling Smørgrav "2.0.16*," 97af12a3e7SDag-Erling Smørgrav "2.0.17*," 98af12a3e7SDag-Erling Smørgrav "2.0.18*," 99af12a3e7SDag-Erling Smørgrav "2.0.19*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 100ca3176e7SBrian Feldman SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 101ca3176e7SBrian Feldman SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| 102ca3176e7SBrian Feldman SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| 103af12a3e7SDag-Erling Smørgrav SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE| 104af12a3e7SDag-Erling Smørgrav SSH_BUG_DUMMYCHAN }, 105af12a3e7SDag-Erling Smørgrav { "2.0.11*," 106af12a3e7SDag-Erling Smørgrav "2.0.12*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 107ca3176e7SBrian Feldman SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 108ca3176e7SBrian Feldman SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| 109ca3176e7SBrian Feldman SSH_BUG_PKAUTH|SSH_BUG_PKOK| 110af12a3e7SDag-Erling Smørgrav SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| 111af12a3e7SDag-Erling Smørgrav SSH_BUG_DUMMYCHAN }, 112af12a3e7SDag-Erling Smørgrav { "2.0.*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 113af12a3e7SDag-Erling Smørgrav SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 114af12a3e7SDag-Erling Smørgrav SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| 115af12a3e7SDag-Erling Smørgrav SSH_BUG_PKAUTH|SSH_BUG_PKOK| 116af12a3e7SDag-Erling Smørgrav SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| 117af12a3e7SDag-Erling Smørgrav SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN }, 118af12a3e7SDag-Erling Smørgrav { "2.2.0*," 119af12a3e7SDag-Erling Smørgrav "2.3.0*", SSH_BUG_HMAC|SSH_BUG_DEBUG| 120ca3176e7SBrian Feldman SSH_BUG_RSASIGMD5 }, 121af12a3e7SDag-Erling Smørgrav { "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 }, 122af12a3e7SDag-Erling Smørgrav { "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */ 123af12a3e7SDag-Erling Smørgrav { "2.*", SSH_BUG_DEBUG }, 124af12a3e7SDag-Erling Smørgrav { "3.0.*", SSH_BUG_DEBUG }, 125af12a3e7SDag-Erling Smørgrav { "3.0 SecureCRT*", SSH_OLD_SESSIONID }, 126af12a3e7SDag-Erling Smørgrav { "1.7 SecureFX*", SSH_OLD_SESSIONID }, 127af12a3e7SDag-Erling Smørgrav { "1.2.18*," 128af12a3e7SDag-Erling Smørgrav "1.2.19*," 129af12a3e7SDag-Erling Smørgrav "1.2.20*," 130af12a3e7SDag-Erling Smørgrav "1.2.21*," 13180628bacSDag-Erling Smørgrav "1.2.22*", SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, 13280628bacSDag-Erling Smørgrav { "1.3.2*", /* F-Secure */ 13380628bacSDag-Erling Smørgrav SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, 13480628bacSDag-Erling Smørgrav { "1.2.1*," 13580628bacSDag-Erling Smørgrav "1.2.2*," 13680628bacSDag-Erling Smørgrav "1.2.3*", SSH_BUG_K5USER }, 137af12a3e7SDag-Erling Smørgrav { "*SSH Compatible Server*", /* Netscreen */ 138ca3176e7SBrian Feldman SSH_BUG_PASSWORDPAD }, 139af12a3e7SDag-Erling Smørgrav { "*OSU_0*," 140af12a3e7SDag-Erling Smørgrav "OSU_1.0*," 141af12a3e7SDag-Erling Smørgrav "OSU_1.1*," 142af12a3e7SDag-Erling Smørgrav "OSU_1.2*," 143af12a3e7SDag-Erling Smørgrav "OSU_1.3*," 144af12a3e7SDag-Erling Smørgrav "OSU_1.4*," 145af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha1*," 146af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha2*," 147af12a3e7SDag-Erling Smørgrav "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, 148af12a3e7SDag-Erling Smørgrav { "*SSH_Version_Mapper*", 149ca3176e7SBrian Feldman SSH_BUG_SCANNER }, 150a04a10f8SKris Kennaway { NULL, 0 } 151a04a10f8SKris Kennaway }; 152af12a3e7SDag-Erling Smørgrav 153b66f2d16SKris Kennaway /* process table, return first match */ 1545b9b2fafSBrian Feldman for (i = 0; check[i].pat; i++) { 155af12a3e7SDag-Erling Smørgrav if (match_pattern_list(version, check[i].pat, 156af12a3e7SDag-Erling Smørgrav strlen(check[i].pat), 0) == 1) { 157ca3176e7SBrian Feldman debug("match: %s pat %s", version, check[i].pat); 158a04a10f8SKris Kennaway datafellows = check[i].bugs; 159a04a10f8SKris Kennaway return; 160a04a10f8SKris Kennaway } 161a04a10f8SKris Kennaway } 1625b9b2fafSBrian Feldman debug("no match: %s", version); 163a04a10f8SKris Kennaway } 164a04a10f8SKris Kennaway 165a04a10f8SKris Kennaway #define SEP "," 166a04a10f8SKris Kennaway int 167a04a10f8SKris Kennaway proto_spec(const char *spec) 168a04a10f8SKris Kennaway { 169b66f2d16SKris Kennaway char *s, *p, *q; 170a04a10f8SKris Kennaway int ret = SSH_PROTO_UNKNOWN; 171a04a10f8SKris Kennaway 1722632b0c8SKris Kennaway if (spec == NULL) 1732632b0c8SKris Kennaway return ret; 174b66f2d16SKris Kennaway q = s = xstrdup(spec); 175b66f2d16SKris Kennaway for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { 176a04a10f8SKris Kennaway switch (atoi(p)) { 177a04a10f8SKris Kennaway case 1: 178a04a10f8SKris Kennaway if (ret == SSH_PROTO_UNKNOWN) 179a04a10f8SKris Kennaway ret |= SSH_PROTO_1_PREFERRED; 180a04a10f8SKris Kennaway ret |= SSH_PROTO_1; 181a04a10f8SKris Kennaway break; 182a04a10f8SKris Kennaway case 2: 183a04a10f8SKris Kennaway ret |= SSH_PROTO_2; 184a04a10f8SKris Kennaway break; 185a04a10f8SKris Kennaway default: 186a04a10f8SKris Kennaway log("ignoring bad proto spec: '%s'.", p); 187a04a10f8SKris Kennaway break; 188a04a10f8SKris Kennaway } 189a04a10f8SKris Kennaway } 190a04a10f8SKris Kennaway xfree(s); 191a04a10f8SKris Kennaway return ret; 192a04a10f8SKris Kennaway } 193ca3176e7SBrian Feldman 194ca3176e7SBrian Feldman char * 195ca3176e7SBrian Feldman compat_cipher_proposal(char *cipher_prop) 196ca3176e7SBrian Feldman { 197af12a3e7SDag-Erling Smørgrav Buffer b; 198ca3176e7SBrian Feldman char *orig_prop, *fix_ciphers; 199ca3176e7SBrian Feldman char *cp, *tmp; 200ca3176e7SBrian Feldman 201ca3176e7SBrian Feldman if (!(datafellows & SSH_BUG_BIGENDIANAES)) 202ca3176e7SBrian Feldman return(cipher_prop); 203ca3176e7SBrian Feldman 204af12a3e7SDag-Erling Smørgrav buffer_init(&b); 205ca3176e7SBrian Feldman tmp = orig_prop = xstrdup(cipher_prop); 206ca3176e7SBrian Feldman while ((cp = strsep(&tmp, ",")) != NULL) { 207af12a3e7SDag-Erling Smørgrav if (strncmp(cp, "aes", 3) != 0) { 208af12a3e7SDag-Erling Smørgrav if (buffer_len(&b) > 0) 209af12a3e7SDag-Erling Smørgrav buffer_append(&b, ",", 1); 210af12a3e7SDag-Erling Smørgrav buffer_append(&b, cp, strlen(cp)); 211ca3176e7SBrian Feldman } 212ca3176e7SBrian Feldman } 213af12a3e7SDag-Erling Smørgrav buffer_append(&b, "\0", 1); 214af12a3e7SDag-Erling Smørgrav fix_ciphers = xstrdup(buffer_ptr(&b)); 215af12a3e7SDag-Erling Smørgrav buffer_free(&b); 216ca3176e7SBrian Feldman xfree(orig_prop); 217ca3176e7SBrian Feldman debug2("Original cipher proposal: %s", cipher_prop); 218ca3176e7SBrian Feldman debug2("Compat cipher proposal: %s", fix_ciphers); 219ca3176e7SBrian Feldman if (!*fix_ciphers) 220ca3176e7SBrian Feldman fatal("No available ciphers found."); 221ca3176e7SBrian Feldman 222ca3176e7SBrian Feldman return(fix_ciphers); 223ca3176e7SBrian Feldman } 224