Summary: | kntlm broken on big-endian systems | ||
---|---|---|---|
Product: | [Unmaintained] kio | Reporter: | Aaron Williams <aaronw> |
Component: | general | Assignee: | Szombathelyi György <gyurco> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | NOR | ||
Version First Reported In: | unspecified | ||
Target Milestone: | --- | ||
Platform: | unspecified | ||
OS: | Solaris | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
Patch to fix big endian support for kntlm.cpp
Patch that fixes Solaris and bug 93454 Patch that fixes Solaris and bug 93454 |
Description
Aaron Williams
2005-08-18 02:31:50 UTC
I have made some changes to kntlm.cpp which appears to fix the endian issues, however, I am still having problems, but the problem is identical to what I am seeing on Linux X86 and is not endian specific (see bug 93454 which should be reopened). I will attach my patch shortly. Created attachment 12335 [details]
Patch to fix big endian support for kntlm.cpp
Here is my patch so far to fix the endian problems with kntlm.cpp.
Created attachment 12338 [details] Patch that fixes Solaris and bug 93454 This patch got connectivity working from my big-endian Solaris box to our Exchange server. This also makes bug 93454 work but is a quick hack to just work around NTLMv2 not working properly. Note that NTLMv2 does not work on a little endian system either (i586 SuSE Linux KDE 3.4.2) Created attachment 12353 [details] Patch that fixes Solaris and bug 93454 This patch got connectivity working from my big-endian Solaris box to our Exchange server. This also makes bug 93454 work but is a quick hack to just work around NTLMv2 not working properly. Note that NTLMv2 does not work on a little endian system either (i586 SuSE Linux KDE 3.4.2) SVN commit 454038 by gyurco: Fixes for big-endian archs. However, NTLMv2 problems needs a fix, too. BUG: 110980 M +31 -17 kntlm.cpp --- branches/KDE/3.5/kdelibs/kio/misc/kntlm/kntlm.cpp #454037:454038 @@ -34,17 +34,21 @@ QString KNTLM::getString( const QByteArray &buf, const SecBuf &secbuf, bool unicode ) { + Q_UINT32 offset; + Q_UINT16 len; + offset = KFromToLittleEndian((Q_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); //watch for buffer overflows - if ( secbuf.offset > buf.size() || - secbuf.offset + secbuf.len > buf.size() ) return QString::null; + if ( offset > buf.size() || + offset + len > buf.size() ) return QString::null; QString str; - const char *c = buf.data() + secbuf.offset; + const char *c = buf.data() + offset; if ( unicode ) { - str = UnicodeLE2QString( (QChar*) c, secbuf.len >> 1 ); + str = UnicodeLE2QString( (QChar*) c, len >> 1 ); } else { - str = QString::fromLatin1( c, secbuf.len ); + str = QString::fromLatin1( c, len ); } return str; } @@ -52,10 +56,14 @@ QByteArray KNTLM::getBuf( const QByteArray &buf, const SecBuf &secbuf ) { QByteArray ret; + Q_UINT32 offset; + Q_UINT16 len; + offset = KFromToLittleEndian((Q_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); //watch for buffer overflows - if ( secbuf.offset > buf.size() || - secbuf.offset + secbuf.len > buf.size() ) return ret; - ret.duplicate( buf.data() + secbuf.offset, buf.size() ); + if ( offset > buf.size() || + offset + len > buf.size() ) return ret; + ret.duplicate( buf.data() + offset, buf.size() ); return ret; } @@ -77,11 +85,17 @@ void KNTLM::addBuf( QByteArray &buf, SecBuf &secbuf, QByteArray &data ) { - secbuf.offset = (buf.size() + 1) & 0xfffffffe; - secbuf.len = data.size(); - secbuf.maxlen = data.size(); - buf.resize( secbuf.offset + data.size() ); - memcpy( buf.data() + secbuf.offset, data.data(), data.size() ); + Q_UINT32 offset; + Q_UINT16 len, maxlen; + offset = (buf.size() + 1) & 0xfffffffe; + len = data.size(); + maxlen = data.size(); + + secbuf.offset = KFromToLittleEndian((Q_UINT32)offset); + secbuf.len = KFromToLittleEndian(len); + secbuf.maxlen = KFromToLittleEndian(maxlen); + buf.resize( offset + len ); + memcpy( buf.data() + offset, data.data(), data.size() ); } bool KNTLM::getNegotiate( QByteArray &negotiate, const QString &domain, const QString &workstation, Q_UINT32 flags ) @@ -118,7 +132,7 @@ //challenge structure too small if ( chsize < 32 ) return false; - unicode = ch->flags & Negotiate_Unicode; + unicode = KFromToLittleEndian(ch->flags) & Negotiate_Unicode; if ( domain.isEmpty() ) dom = getString( challenge, ch->targetName, unicode ); else @@ -130,8 +144,8 @@ ((Auth*) rbuf.data())->flags = ch->flags; QByteArray targetInfo = getBuf( challenge, ch->targetInfo ); - if ( forceNTLMv2 || (!targetInfo.isEmpty() && (ch->flags & Negotiate_Target_Info)) /* may support NTLMv2 */ ) { - if ( ch->flags & Negotiate_NTLM ) { + if ( forceNTLMv2 || (!targetInfo.isEmpty() && (KFromToLittleEndian(ch->flags) & Negotiate_Target_Info)) /* may support NTLMv2 */ ) { + if ( KFromToLittleEndian(ch->flags) & Negotiate_NTLM ) { if ( targetInfo.isEmpty() ) return false; response = getNTLMv2Response( dom, user, password, targetInfo, ch->challengeData ); addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); @@ -143,7 +157,7 @@ return false; } } else { //if no targetinfo structure and NTLMv2 or LMv2 not forced, try the older methods - if ( ch->flags & Negotiate_NTLM ) { + if ( KFromToLittleEndian(ch->flags) & Negotiate_NTLM ) { response = getNTLMResponse( password, ch->challengeData ); addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); } else { SVN commit 454042 by gyurco: Backport fix for #110980 (endiannes problem) CCBUG: 110980 M +31 -17 kntlm.cpp --- branches/KDE/3.4/kdelibs/kio/misc/kntlm/kntlm.cpp #454041:454042 @@ -35,16 +35,20 @@ QString KNTLM::getString( const QByteArray &buf, const SecBuf &secbuf, bool unicode ) { //watch for buffer overflows - if ( secbuf.offset > buf.size() || - secbuf.offset + secbuf.len > buf.size() ) return QString::null; + Q_UINT32 offset; + Q_UINT16 len; + offset = KFromToLittleEndian((Q_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); + if ( offset > buf.size() || + offset + len > buf.size() ) return QString::null; QString str; - const char *c = buf.data() + secbuf.offset; + const char *c = buf.data() + offset; if ( unicode ) { - str = UnicodeLE2QString( (QChar*) c, secbuf.len >> 1 ); + str = UnicodeLE2QString( (QChar*) c, len >> 1 ); } else { - str = QString::fromLatin1( c, secbuf.len ); + str = QString::fromLatin1( c, len ); } return str; } @@ -52,10 +56,14 @@ QByteArray KNTLM::getBuf( const QByteArray &buf, const SecBuf &secbuf ) { QByteArray ret; + Q_UINT32 offset; + Q_UINT16 len; + offset = KFromToLittleEndian((Q_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); //watch for buffer overflows - if ( secbuf.offset > buf.size() || - secbuf.offset + secbuf.len > buf.size() ) return ret; - ret.duplicate( buf.data() + secbuf.offset, buf.size() ); + if ( offset > buf.size() || + offset + len > buf.size() ) return ret; + ret.duplicate( buf.data() + offset, buf.size() ); return ret; } @@ -77,11 +85,17 @@ void KNTLM::addBuf( QByteArray &buf, SecBuf &secbuf, QByteArray &data ) { - secbuf.offset = (buf.size() + 1) & 0xfffffffe; - secbuf.len = data.size(); - secbuf.maxlen = data.size(); - buf.resize( secbuf.offset + data.size() ); - memcpy( buf.data() + secbuf.offset, data.data(), data.size() ); + Q_UINT32 offset; + Q_UINT16 len, maxlen; + offset = (buf.size() + 1) & 0xfffffffe; + len = data.size(); + maxlen = data.size(); + + secbuf.offset = KFromToLittleEndian((Q_UINT32)offset); + secbuf.len = KFromToLittleEndian(len); + secbuf.maxlen = KFromToLittleEndian(maxlen); + buf.resize( offset + len ); + memcpy( buf.data() + offset, data.data(), data.size() ); } bool KNTLM::getNegotiate( QByteArray &negotiate, const QString &domain, const QString &workstation, Q_UINT32 flags ) @@ -118,7 +132,7 @@ //challenge structure too small if ( chsize < 32 ) return false; - unicode = ch->flags & Negotiate_Unicode; + unicode = KFromToLittleEndian(ch->flags) & Negotiate_Unicode; if ( domain.isEmpty() ) dom = getString( challenge, ch->targetName, unicode ); else @@ -130,8 +144,8 @@ ((Auth*) rbuf.data())->flags = ch->flags; QByteArray targetInfo = getBuf( challenge, ch->targetInfo ); - if ( forceNTLMv2 || (!targetInfo.isEmpty() && (ch->flags & Negotiate_Target_Info)) /* may support NTLMv2 */ ) { - if ( ch->flags & Negotiate_NTLM ) { + if ( forceNTLMv2 || (!targetInfo.isEmpty() && (KFromToLittleEndian(ch->flags) & Negotiate_Target_Info)) /* may support NTLMv2 */ ) { + if ( KFromToLittleEndian(ch->flags) & Negotiate_NTLM ) { if ( targetInfo.isEmpty() ) return false; response = getNTLMv2Response( dom, user, password, targetInfo, ch->challengeData ); addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); @@ -143,7 +157,7 @@ return false; } } else { //if no targetinfo structure and NTLMv2 or LMv2 not forced, try the older methods - if ( ch->flags & Negotiate_NTLM ) { + if ( KFromToLittleEndian(ch->flags) & Negotiate_NTLM ) { response = getNTLMResponse( password, ch->challengeData ); addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); } else { |