version 1.47, 2001/04/18 23:43:25 |
version 1.47.2.3, 2002/06/02 22:56:10 |
|
|
/* |
/* |
* Copyright (c) 1999,2000 Markus Friedl. All rights reserved. |
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* modification, are permitted provided that the following conditions |
|
|
#include "includes.h" |
#include "includes.h" |
RCSID("$OpenBSD$"); |
RCSID("$OpenBSD$"); |
|
|
#include <regex.h> |
#include "buffer.h" |
|
|
#include "packet.h" |
#include "packet.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "compat.h" |
#include "compat.h" |
#include "log.h" |
#include "log.h" |
|
#include "match.h" |
|
|
int compat13 = 0; |
int compat13 = 0; |
int compat20 = 0; |
int compat20 = 0; |
|
|
void |
void |
compat_datafellows(const char *version) |
compat_datafellows(const char *version) |
{ |
{ |
int i, ret; |
int i; |
char ebuf[1024]; |
|
regex_t reg; |
|
static struct { |
static struct { |
char *pat; |
char *pat; |
int bugs; |
int bugs; |
} check[] = { |
} check[] = { |
{ "^OpenSSH[-_]2\\.[012]", |
{ "OpenSSH-2.0*," |
SSH_OLD_SESSIONID|SSH_BUG_BANNER| |
"OpenSSH-2.1*," |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, |
"OpenSSH_2.1*," |
{ "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| |
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY}, |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
{ "^OpenSSH_2\\.3\\.", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
SSH_BUG_EXTEOF}, |
SSH_BUG_NOREKEY}, |
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| |
{ "^OpenSSH_2\\.5\\.[01]p1", |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
|
SSH_BUG_EXTEOF}, |
|
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
|
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
|
{ "OpenSSH_2.5.0p1*," |
|
"OpenSSH_2.5.1p1*", |
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
SSH_BUG_NOREKEY }, |
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
{ "^OpenSSH_2\\.5\\.[012]", |
{ "OpenSSH_2.5.0*," |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, |
"OpenSSH_2.5.1*," |
{ "^OpenSSH_2\\.5\\.3", |
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
SSH_BUG_NOREKEY }, |
SSH_BUG_EXTEOF}, |
{ "^OpenSSH", 0 }, |
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
{ "MindTerm", 0 }, |
{ "OpenSSH_2.*," |
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
"OpenSSH_3.0*," |
|
"OpenSSH_3.1*", SSH_BUG_EXTEOF}, |
|
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
|
{ "OpenSSH*", 0 }, |
|
{ "*MindTerm*", 0 }, |
|
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
{ "^2\\.1 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
{ "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
{ "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
{ "2.0.13*," |
|
"2.0.14*," |
|
"2.0.15*," |
|
"2.0.16*," |
|
"2.0.17*," |
|
"2.0.18*," |
|
"2.0.19*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| |
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| |
SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| |
SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| |
SSH_BUG_HBSERVICE }, |
SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE| |
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_BUG_DUMMYCHAN }, |
|
{ "2.0.11*," |
|
"2.0.12*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| |
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| |
SSH_BUG_PKAUTH|SSH_BUG_PKOK| |
SSH_BUG_PKAUTH|SSH_BUG_PKOK| |
|
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| |
|
SSH_BUG_DUMMYCHAN }, |
|
{ "2.0.*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| |
|
SSH_BUG_PKAUTH|SSH_BUG_PKOK| |
|
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| |
|
SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN }, |
|
{ "2.2.0*," |
|
"2.3.0*", SSH_BUG_HMAC|SSH_BUG_DEBUG| |
SSH_BUG_RSASIGMD5 }, |
SSH_BUG_RSASIGMD5 }, |
{ "^2\\.[23]\\.0", SSH_BUG_HMAC|SSH_BUG_RSASIGMD5 }, |
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 }, |
{ "^2\\.3\\.", SSH_BUG_RSASIGMD5 }, |
{ "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */ |
{ "^2\\.[2-9]\\.", 0 }, |
{ "2.*", SSH_BUG_DEBUG }, |
{ "^2\\.4$", SSH_OLD_SESSIONID }, /* Van Dyke */ |
{ "3.0.*", SSH_BUG_DEBUG }, |
{ "^3\\.0 SecureCRT", SSH_OLD_SESSIONID }, |
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID }, |
{ "^1\\.7 SecureFX", SSH_OLD_SESSIONID }, |
{ "1.7 SecureFX*", SSH_OLD_SESSIONID }, |
{ "^1\\.2\\.1[89]", SSH_BUG_IGNOREMSG }, |
{ "1.2.18*," |
{ "^1\\.2\\.2[012]", SSH_BUG_IGNOREMSG }, |
"1.2.19*," |
{ "^1\\.3\\.2", SSH_BUG_IGNOREMSG }, /* f-secure */ |
"1.2.20*," |
{ "^SSH Compatible Server", /* Netscreen */ |
"1.2.21*," |
|
"1.2.22*", SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, |
|
{ "1.3.2*", /* F-Secure */ |
|
SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, |
|
{ "1.2.1*," |
|
"1.2.2*," |
|
"1.2.3*", SSH_BUG_K5USER }, |
|
{ "*SSH Compatible Server*", /* Netscreen */ |
SSH_BUG_PASSWORDPAD }, |
SSH_BUG_PASSWORDPAD }, |
{ "^OSU_0", SSH_BUG_PASSWORDPAD }, |
{ "*OSU_0*," |
{ "^OSU_1\\.[0-4]", SSH_BUG_PASSWORDPAD }, |
"OSU_1.0*," |
{ "^OSU_1\\.5alpha[1-3]", |
"OSU_1.1*," |
SSH_BUG_PASSWORDPAD }, |
"OSU_1.2*," |
{ "^SSH_Version_Mapper", |
"OSU_1.3*," |
|
"OSU_1.4*," |
|
"OSU_1.5alpha1*," |
|
"OSU_1.5alpha2*," |
|
"OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, |
|
{ "*SSH_Version_Mapper*", |
SSH_BUG_SCANNER }, |
SSH_BUG_SCANNER }, |
{ NULL, 0 } |
{ NULL, 0 } |
}; |
}; |
|
|
/* process table, return first match */ |
/* process table, return first match */ |
for (i = 0; check[i].pat; i++) { |
for (i = 0; check[i].pat; i++) { |
ret = regcomp(®, check[i].pat, REG_EXTENDED|REG_NOSUB); |
if (match_pattern_list(version, check[i].pat, |
if (ret != 0) { |
strlen(check[i].pat), 0) == 1) { |
regerror(ret, ®, ebuf, sizeof(ebuf)); |
|
ebuf[sizeof(ebuf)-1] = '\0'; |
|
error("regerror: %s", ebuf); |
|
continue; |
|
} |
|
ret = regexec(®, version, 0, NULL, 0); |
|
regfree(®); |
|
if (ret == 0) { |
|
debug("match: %s pat %s", version, check[i].pat); |
debug("match: %s pat %s", version, check[i].pat); |
datafellows = check[i].bugs; |
datafellows = check[i].bugs; |
return; |
return; |
|
|
return ret; |
return ret; |
q = s = xstrdup(spec); |
q = s = xstrdup(spec); |
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { |
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { |
switch(atoi(p)) { |
switch (atoi(p)) { |
case 1: |
case 1: |
if (ret == SSH_PROTO_UNKNOWN) |
if (ret == SSH_PROTO_UNKNOWN) |
ret |= SSH_PROTO_1_PREFERRED; |
ret |= SSH_PROTO_1_PREFERRED; |
|
|
char * |
char * |
compat_cipher_proposal(char *cipher_prop) |
compat_cipher_proposal(char *cipher_prop) |
{ |
{ |
|
Buffer b; |
char *orig_prop, *fix_ciphers; |
char *orig_prop, *fix_ciphers; |
char *cp, *tmp; |
char *cp, *tmp; |
size_t len; |
|
|
|
if (!(datafellows & SSH_BUG_BIGENDIANAES)) |
if (!(datafellows & SSH_BUG_BIGENDIANAES)) |
return(cipher_prop); |
return(cipher_prop); |
|
|
len = strlen(cipher_prop) + 1; |
buffer_init(&b); |
fix_ciphers = xmalloc(len); |
|
*fix_ciphers = '\0'; |
|
tmp = orig_prop = xstrdup(cipher_prop); |
tmp = orig_prop = xstrdup(cipher_prop); |
while((cp = strsep(&tmp, ",")) != NULL) { |
while ((cp = strsep(&tmp, ",")) != NULL) { |
if (strncmp(cp, "aes", 3) && strncmp(cp, "rijndael", 8)) { |
if (strncmp(cp, "aes", 3) != 0) { |
if (*fix_ciphers) |
if (buffer_len(&b) > 0) |
strlcat(fix_ciphers, ",", len); |
buffer_append(&b, ",", 1); |
strlcat(fix_ciphers, cp, len); |
buffer_append(&b, cp, strlen(cp)); |
} |
} |
} |
} |
|
buffer_append(&b, "\0", 1); |
|
fix_ciphers = xstrdup(buffer_ptr(&b)); |
|
buffer_free(&b); |
xfree(orig_prop); |
xfree(orig_prop); |
debug2("Original cipher proposal: %s", cipher_prop); |
debug2("Original cipher proposal: %s", cipher_prop); |
debug2("Compat cipher proposal: %s", fix_ciphers); |
debug2("Compat cipher proposal: %s", fix_ciphers); |