version 1.27, 2000/10/31 09:31:58 |
version 1.27.2.6, 2002/03/08 17:04:42 |
|
|
/* |
/* |
* 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 "ssh.h" |
#include "buffer.h" |
#include "packet.h" |
#include "packet.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "compat.h" |
#include "compat.h" |
#include <regex.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]", SSH_OLD_SESSIONID }, |
{ "OpenSSH-2.0*," |
{ "MindTerm", 0 }, |
"OpenSSH-2.1*," |
{ "^2\\.1\\.0 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
"OpenSSH_2.1*," |
SSH_OLD_SESSIONID }, |
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| |
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, |
SSH_OLD_SESSIONID| |
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| |
SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD }, |
SSH_OLD_DHGEX|SSH_BUG_NOREKEY}, |
{ "^2\\.[23]\\.0 ", SSH_BUG_HMAC}, |
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
{ "^2\\.[2-9]\\.", 0 }, |
SSH_BUG_NOREKEY}, |
{ "^2\\.4$", SSH_OLD_SESSIONID}, /* Van Dyke */ |
{ "OpenSSH_2.5.0p1*," |
{ "^3\\.0 SecureCRT", SSH_OLD_SESSIONID}, |
"OpenSSH_2.5.1p1*", |
{ "^1\\.7 SecureFX", SSH_OLD_SESSIONID}, |
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
{ "^2\\.", SSH_BUG_HMAC}, /* XXX fallback */ |
SSH_BUG_NOREKEY }, |
|
{ "OpenSSH_2.5.0*," |
|
"OpenSSH_2.5.1*," |
|
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, |
|
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY }, |
|
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY }, |
|
{ "OpenSSH*", 0 }, |
|
{ "*MindTerm*", 0 }, |
|
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
|
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
|
{ "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG| |
|
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, |
|
{ "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_BUG_PKSERVICE|SSH_BUG_X11FWD| |
|
SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| |
|
SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE| |
|
SSH_BUG_DUMMYCHAN }, |
|
{ "2.0.11*," |
|
"2.0.12*", 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_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 }, |
|
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 }, |
|
{ "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */ |
|
{ "2.*", SSH_BUG_DEBUG }, |
|
{ "3.0.*", SSH_BUG_DEBUG }, |
|
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID }, |
|
{ "1.7 SecureFX*", SSH_OLD_SESSIONID }, |
|
{ "1.2.18*," |
|
"1.2.19*," |
|
"1.2.20*," |
|
"1.2.21*," |
|
"1.2.22*", SSH_BUG_IGNOREMSG }, |
|
{ "1.3.2*", SSH_BUG_IGNOREMSG }, /* f-secure */ |
|
{ "*SSH Compatible Server*", /* Netscreen */ |
|
SSH_BUG_PASSWORDPAD }, |
|
{ "*OSU_0*," |
|
"OSU_1.0*," |
|
"OSU_1.1*," |
|
"OSU_1.2*," |
|
"OSU_1.3*," |
|
"OSU_1.4*," |
|
"OSU_1.5alpha1*," |
|
"OSU_1.5alpha2*," |
|
"OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, |
|
{ "*SSH_Version_Mapper*", |
|
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)); |
debug("match: %s pat %s", version, check[i].pat); |
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\n", 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; |
|
|
} |
} |
xfree(s); |
xfree(s); |
return ret; |
return ret; |
|
} |
|
|
|
char * |
|
compat_cipher_proposal(char *cipher_prop) |
|
{ |
|
Buffer b; |
|
char *orig_prop, *fix_ciphers; |
|
char *cp, *tmp; |
|
|
|
if (!(datafellows & SSH_BUG_BIGENDIANAES)) |
|
return(cipher_prop); |
|
|
|
buffer_init(&b); |
|
tmp = orig_prop = xstrdup(cipher_prop); |
|
while ((cp = strsep(&tmp, ",")) != NULL) { |
|
if (strncmp(cp, "aes", 3) != 0) { |
|
if (buffer_len(&b) > 0) |
|
buffer_append(&b, ",", 1); |
|
buffer_append(&b, cp, strlen(cp)); |
|
} |
|
} |
|
buffer_append(&b, "\0", 1); |
|
fix_ciphers = xstrdup(buffer_ptr(&b)); |
|
buffer_free(&b); |
|
xfree(orig_prop); |
|
debug2("Original cipher proposal: %s", cipher_prop); |
|
debug2("Compat cipher proposal: %s", fix_ciphers); |
|
if (!*fix_ciphers) |
|
fatal("No available ciphers found."); |
|
|
|
return(fix_ciphers); |
} |
} |