29 #include <QtCore/QDate>
30 #include <QtCore/QtEndian>
31 #include <QtCore/QCryptographicHash>
40 QByteArray unicode (target.length() * 2, 0);
42 for (
int i = 0; i < target.length(); i++) {
43 ((quint16 *) unicode.data()) [ i ] = qToLittleEndian (target[i].unicode());
53 for (uint i = 0; i < len; i++) {
54 ret += qFromLittleEndian (data[ i ].unicode());
63 quint16 len = qFromLittleEndian (secbuf.
len);
66 if (offset > (
quint32) buf.size() || offset + len > (
quint32) buf.size()) {
70 return QByteArray (buf.data() + offset, buf.size());
75 quint32 offset = (buf.size() + 1) & 0xfffffffe;
76 quint16 len = data.size();
77 quint16 maxlen = data.size();
80 secbuf.
len = qToLittleEndian (len);
81 secbuf.
maxlen = qToLittleEndian (maxlen);
82 buf.resize (offset + len);
83 memcpy (buf.data() + offset, data.data(), data.size());
90 quint16 len = qFromLittleEndian (secbuf.
len);
92 if (offset > (
quint32) buf.size() || offset + len > (
quint32) buf.size()) {
96 const char *c = buf.data() + offset;
102 return QString::fromLatin1 (c, len);
112 addBuf (buf, secbuf, str.toLatin1());
121 unsigned char key[8];
124 key[1] = ( (key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
125 key[2] = ( (key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
126 key[3] = ( (key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
127 key[4] = ( (key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
128 key[5] = ( (key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
129 key[6] = ( (key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
130 key[7] = (key_56[6] << 1) & 0xFF;
132 for (uint i = 0; i < 8; i++) {
133 unsigned char b = key[i];
134 bool needsParity = ((((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0);
144 memset (&key, 0,
sizeof (key));
149 QByteArray blob (
sizeof (
KNTLM::Blob) + 4 + targetinfo.size(), 0);
153 quint64 now = QDateTime::currentDateTime().toTime_t();
156 bl->timestamp = qToLittleEndian (now);
158 for (uint i = 0; i < 8; i++) {
162 memcpy (blob.data() +
sizeof (
KNTLM::Blob), targetinfo.data(), targetinfo.size());
166 static QByteArray
hmacMD5 (
const QByteArray &data,
const QByteArray &key)
168 quint8 ipad[64], opad[64];
171 memset (ipad, 0x36,
sizeof (ipad));
172 memset (opad, 0x5c,
sizeof (opad));
174 for (
int i = key.size() - 1; i >= 0; i--) {
179 QByteArray content (data.size() + 64, 0);
180 memcpy (content.data(), ipad, 64);
181 memcpy (content.data() + 64, data.data(), data.size());
183 QCryptographicHash md5 (QCryptographicHash::Md5);
184 md5.addData (content);
186 memcpy (content.data(), opad, 64);
187 content += md5.result();
190 md5.addData (content);
205 if (!domain.isEmpty()) {
210 if (!workstation.isEmpty()) {
215 ((
Negotiate *) rbuf.data())->flags = qToLittleEndian (flags);
222 const QString &workstation, AuthFlags authflags)
224 QByteArray rbuf (
sizeof (
Auth), 0);
227 uint chsize = challenge.size();
228 bool unicode =
false;
238 if (domain.isEmpty()) {
245 ((
Auth *) rbuf.data())->msgType = qToLittleEndian ( (
quint32) 3);
246 ((
Auth *) rbuf.data())->flags = ch->
flags;
256 if (targetInfo.isEmpty())
260 addBuf (rbuf, ((
Auth *) rbuf.data())->ntResponse, response);
278 addBuf (rbuf, ((
Auth *) rbuf.data())->ntResponse, response);
293 if (!dom.isEmpty()) {
294 addString (rbuf, ((
Auth *) rbuf.data())->domain, dom, unicode);
297 addString (rbuf, ((
Auth *) rbuf.data())->user, user, unicode);
299 if (!workstation.isEmpty()) {
300 addString (rbuf, ((
Auth *) rbuf.data())->workstation, workstation, unicode);
309 QByteArray hash, answer;
313 memset (hash.data() + 16, 0, 5);
321 QByteArray keyBytes (14, 0);
322 QByteArray hash (16, 0);
324 const char *magic =
"KGS!@#$%";
326 strncpy (keyBytes.data(), password.toUpper().toLatin1(), 14);
328 convertKey ( (
unsigned char *) keyBytes.data(), &ks);
331 convertKey ( (
unsigned char *) keyBytes.data() + 7, &ks);
335 memset (&ks, 0,
sizeof (ks));
343 QByteArray answer (24, 0);
345 convertKey ( (
unsigned char *) hash.data(), &ks);
348 convertKey ( (
unsigned char *) hash.data() + 7, &ks);
351 convertKey ( (
unsigned char *) hash.data() + 14, &ks);
354 memset (&ks, 0,
sizeof (ks));
360 QByteArray hash =
ntlmHash (password);
362 memset (hash.data() + 16, 0, 5);
363 QByteArray answer =
lmResponse (hash, challenge);
373 return QCryptographicHash::hash (unicode, QCryptographicHash::Md4);
377 const QString &password,
const QByteArray &targetInformation,
378 const unsigned char *challenge)
380 QByteArray hash =
ntlmv2Hash (target, user, password);
381 QByteArray blob =
createBlob (targetInformation);
386 const QString &password,
const unsigned char *challenge)
388 QByteArray hash =
ntlmv2Hash (target, user, password);
389 QByteArray clientChallenge (8, 0);
391 for (uint i = 0; i < 8; i++) {
400 const QByteArray hash =
ntlmHash (password);
406 const QByteArray &clientData,
const unsigned char *challenge)
408 QByteArray data (8 + clientData.size(), 0);
409 memcpy (data.data(), challenge, 8);
410 memcpy (data.data() + 8, clientData.data(), clientData.size());
412 QByteArray mac =
hmacMD5 (data, hash);
413 mac.resize (16 + clientData.size());
414 memcpy (mac.data() + 16, clientData.data(), clientData.size());