Qt 4.8
Classes | Macros | Functions | Variables
qauthenticator.cpp File Reference
#include <qauthenticator.h>
#include <qauthenticator_p.h>
#include <qdebug.h>
#include <qhash.h>
#include <qbytearray.h>
#include <qcryptographichash.h>
#include <qhttp.h>
#include <qiodevice.h>
#include <qdatastream.h>
#include <qendian.h>
#include <qstring.h>
#include <qdatetime.h>

Go to the source code of this file.

Classes

class  QNtlmBuffer
 
class  QNtlmPhase1Block
 
class  QNtlmPhase1BlockBase
 
class  QNtlmPhase2Block
 
class  QNtlmPhase2BlockBase
 
class  QNtlmPhase3Block
 
class  QNtlmPhase3BlockBase
 

Macros

#define AVTIMESTAMP   7
 
#define NTLMSSP_NEGOTIATE_128   0x20000000
 
#define NTLMSSP_NEGOTIATE_56   0x80000000
 
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN   0x00008000
 
#define NTLMSSP_NEGOTIATE_DATAGRAM   0x00000040
 
#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED   0x00001000
 
#define NTLMSSP_NEGOTIATE_KEY_EXCHANGE   0x40000000
 
#define NTLMSSP_NEGOTIATE_LM_KEY   0x00000080
 
#define NTLMSSP_NEGOTIATE_LOCAL_CALL   0x00004000
 
#define NTLMSSP_NEGOTIATE_NTLM   0x00000200
 
#define NTLMSSP_NEGOTIATE_NTLM2   0x00080000
 
#define NTLMSSP_NEGOTIATE_OEM   0x00000002
 
#define NTLMSSP_NEGOTIATE_SEAL   0x00000020
 
#define NTLMSSP_NEGOTIATE_SIGN   0x00000010
 
#define NTLMSSP_NEGOTIATE_TARGET_INFO   0x00800000
 
#define NTLMSSP_NEGOTIATE_UNICODE   0x00000001
 
#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED   0x00002000
 
#define NTLMSSP_REQUEST_TARGET   0x00000004
 
#define NTLMSSP_TARGET_TYPE_DOMAIN   0x00010000
 
#define NTLMSSP_TARGET_TYPE_SERVER   0x00020000
 
#define NTLMSSP_TARGET_TYPE_SHARE   0x00040000
 

Functions

static QByteArray clientChallenge (const QAuthenticatorPrivate *ctx)
 
static QByteArray digestMd5ResponseHelper (const QByteArray &alg, const QByteArray &userName, const QByteArray &realm, const QByteArray &password, const QByteArray &nonce, const QByteArray &nonceCount, const QByteArray &cNonce, const QByteArray &qop, const QByteArray &method, const QByteArray &digestUri, const QByteArray &hEntity)
 
static QDataStreamoperator<< (QDataStream &s, const QNtlmBuffer &b)
 
static QDataStreamoperator<< (QDataStream &s, const QNtlmPhase1Block &b)
 
static QDataStreamoperator<< (QDataStream &s, const QNtlmPhase3Block &b)
 
static QDataStreamoperator>> (QDataStream &s, QNtlmBuffer &b)
 
static QByteArray qCreatev2Hash (const QAuthenticatorPrivate *ctx, QNtlmPhase3Block *phase3)
 
QByteArray qEncodeHmacMd5 (QByteArray &key, const QByteArray &message)
 
static QByteArray qEncodeLmv2Response (const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block &ch, QNtlmPhase3Block *phase3)
 
static int qEncodeNtlmBuffer (QNtlmBuffer &buf, int offset, const QByteArray &s)
 
static int qEncodeNtlmString (QNtlmBuffer &buf, int offset, const QString &s, bool unicode)
 
static QByteArray qEncodeNtlmv2Response (const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block &ch, QNtlmPhase3Block *phase3)
 
static QByteArray qExtractServerTime (const QByteArray &targetInfoBuff)
 
static bool qNtlmDecodePhase2 (const QByteArray &data, QNtlmPhase2Block &ch)
 
static QByteArray qNtlmPhase1 ()
 
static QByteArray qNtlmPhase3 (QAuthenticatorPrivate *ctx, const QByteArray &phase2data)
 
static void qStreamNtlmBuffer (QDataStream &ds, const QByteArray &s)
 
static void qStreamNtlmString (QDataStream &ds, const QString &s, bool unicode)
 
static QByteArray qStringAsUcs2Le (const QString &src)
 
static QString qStringFromUcs2Le (const QByteArray &src)
 

Variables

const int blockSize = 64
 
const quint8 hirespversion = 1
 
const int nDigestLen = 16
 
const quint8 respversion = 1
 

Macro Definition Documentation

◆ AVTIMESTAMP

#define AVTIMESTAMP   7

Definition at line 822 of file qauthenticator.cpp.

Referenced by qExtractServerTime().

◆ NTLMSSP_NEGOTIATE_128

#define NTLMSSP_NEGOTIATE_128   0x20000000

Definition at line 804 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_56

#define NTLMSSP_NEGOTIATE_56   0x80000000

Definition at line 817 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_ALWAYS_SIGN

#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN   0x00008000

Definition at line 765 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_DATAGRAM

#define NTLMSSP_NEGOTIATE_DATAGRAM   0x00000040

Definition at line 726 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED

#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED   0x00001000

Definition at line 745 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_KEY_EXCHANGE

#define NTLMSSP_NEGOTIATE_KEY_EXCHANGE   0x40000000

Definition at line 812 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_LM_KEY

#define NTLMSSP_NEGOTIATE_LM_KEY   0x00000080

Definition at line 732 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_LOCAL_CALL

#define NTLMSSP_NEGOTIATE_LOCAL_CALL   0x00004000

Definition at line 759 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_NTLM

#define NTLMSSP_NEGOTIATE_NTLM   0x00000200

◆ NTLMSSP_NEGOTIATE_NTLM2

#define NTLMSSP_NEGOTIATE_NTLM2   0x00080000

Definition at line 792 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_OEM

#define NTLMSSP_NEGOTIATE_OEM   0x00000002

Definition at line 703 of file qauthenticator.cpp.

Referenced by qNtlmPhase3().

◆ NTLMSSP_NEGOTIATE_SEAL

#define NTLMSSP_NEGOTIATE_SEAL   0x00000020

Definition at line 721 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_SIGN

#define NTLMSSP_NEGOTIATE_SIGN   0x00000010

Definition at line 715 of file qauthenticator.cpp.

◆ NTLMSSP_NEGOTIATE_TARGET_INFO

#define NTLMSSP_NEGOTIATE_TARGET_INFO   0x00800000

Definition at line 799 of file qauthenticator.cpp.

Referenced by QNtlmPhase3Block::QNtlmPhase3Block().

◆ NTLMSSP_NEGOTIATE_UNICODE

#define NTLMSSP_NEGOTIATE_UNICODE   0x00000001

◆ NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED

#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED   0x00002000

Definition at line 752 of file qauthenticator.cpp.

◆ NTLMSSP_REQUEST_TARGET

#define NTLMSSP_REQUEST_TARGET   0x00000004

Definition at line 709 of file qauthenticator.cpp.

Referenced by QNtlmPhase1Block::QNtlmPhase1Block().

◆ NTLMSSP_TARGET_TYPE_DOMAIN

#define NTLMSSP_TARGET_TYPE_DOMAIN   0x00010000

Definition at line 771 of file qauthenticator.cpp.

◆ NTLMSSP_TARGET_TYPE_SERVER

#define NTLMSSP_TARGET_TYPE_SERVER   0x00020000

Definition at line 777 of file qauthenticator.cpp.

◆ NTLMSSP_TARGET_TYPE_SHARE

#define NTLMSSP_TARGET_TYPE_SHARE   0x00040000

Definition at line 784 of file qauthenticator.cpp.

Function Documentation

◆ clientChallenge()

static QByteArray clientChallenge ( const QAuthenticatorPrivate ctx)
static

Definition at line 1222 of file qauthenticator.cpp.

Referenced by qEncodeLmv2Response(), and qEncodeNtlmv2Response().

1223 {
1224  Q_ASSERT(ctx->cnonce.size() >= 8);
1225  QByteArray clientCh = ctx->cnonce.right(8);
1226  return clientCh;
1227 }
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QByteArray right(int len) const
Returns a byte array that contains the rightmost len bytes of this byte array.
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402

◆ digestMd5ResponseHelper()

static QByteArray digestMd5ResponseHelper ( const QByteArray alg,
const QByteArray userName,
const QByteArray realm,
const QByteArray password,
const QByteArray nonce,
const QByteArray nonceCount,
const QByteArray cNonce,
const QByteArray qop,
const QByteArray method,
const QByteArray digestUri,
const QByteArray hEntity 
)
static

Definition at line 577 of file qauthenticator.cpp.

Referenced by QAuthenticatorPrivate::digestMd5Response().

590 {
592  hash.addData(userName);
593  hash.addData(":", 1);
594  hash.addData(realm);
595  hash.addData(":", 1);
596  hash.addData(password);
597  QByteArray ha1 = hash.result();
598  if (alg.toLower() == "md5-sess") {
599  hash.reset();
600  // RFC 2617 contains an error, it was:
601  // hash.addData(ha1);
602  // but according to the errata page at http://www.rfc-editor.org/errata_list.php, ID 1649, it
603  // must be the following line:
604  hash.addData(ha1.toHex());
605  hash.addData(":", 1);
606  hash.addData(nonce);
607  hash.addData(":", 1);
608  hash.addData(cNonce);
609  ha1 = hash.result();
610  };
611  ha1 = ha1.toHex();
612 
613  // calculate H(A2)
614  hash.reset();
615  hash.addData(method);
616  hash.addData(":", 1);
617  hash.addData(digestUri);
618  if (qop.toLower() == "auth-int") {
619  hash.addData(":", 1);
620  hash.addData(hEntity);
621  }
622  QByteArray ha2hex = hash.result().toHex();
623 
624  // calculate response
625  hash.reset();
626  hash.addData(ha1);
627  hash.addData(":", 1);
628  hash.addData(nonce);
629  hash.addData(":", 1);
630  if (!qop.isNull()) {
631  hash.addData(nonceCount);
632  hash.addData(":", 1);
633  hash.addData(cNonce);
634  hash.addData(":", 1);
635  hash.addData(qop);
636  hash.addData(":", 1);
637  }
638  hash.addData(ha2hex);
639  return hash.result().toHex();
640 }
static uint hash(const uchar *p, int n)
Definition: qhash.cpp:68
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray toLower() const
Returns a lowercase copy of the byte array.
QByteArray toHex() const
Returns a hex encoded copy of the byte array.
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
The QCryptographicHash class provides a way to generate cryptographic hashes.

◆ operator<<() [1/3]

static QDataStream& operator<< ( QDataStream s,
const QNtlmBuffer b 
)
static

Definition at line 938 of file qauthenticator.cpp.

939 {
940  s << b.len << b.maxLen << b.offset;
941  return s;
942 }

◆ operator<<() [2/3]

static QDataStream& operator<< ( QDataStream s,
const QNtlmPhase1Block b 
)
static

Definition at line 995 of file qauthenticator.cpp.

995  {
996  bool unicode = (b.flags & NTLMSSP_NEGOTIATE_UNICODE);
997 
998  s.writeRawData(b.magic, sizeof(b.magic));
999  s << b.type;
1000  s << b.flags;
1001  s << b.domain;
1002  s << b.workstation;
1003  if (!b.domainStr.isEmpty())
1004  qStreamNtlmString(s, b.domainStr, unicode);
1005  if (!b.workstationStr.isEmpty())
1006  qStreamNtlmString(s, b.workstationStr, unicode);
1007  return s;
1008 }
static void qStreamNtlmString(QDataStream &ds, const QString &s, bool unicode)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define NTLMSSP_NEGOTIATE_UNICODE
int writeRawData(const char *, int len)
Writes len bytes from s to the stream.

◆ operator<<() [3/3]

static QDataStream& operator<< ( QDataStream s,
const QNtlmPhase3Block b 
)
static

Definition at line 1011 of file qauthenticator.cpp.

1011  {
1012  bool unicode = (b.flags & NTLMSSP_NEGOTIATE_UNICODE);
1013  s.writeRawData(b.magic, sizeof(b.magic));
1014  s << b.type;
1015  s << b.lmResponse;
1016  s << b.ntlmResponse;
1017  s << b.domain;
1018  s << b.user;
1019  s << b.workstation;
1020  s << b.sessionKey;
1021  s << b.flags;
1022 
1023  if (!b.domainStr.isEmpty())
1024  qStreamNtlmString(s, b.domainStr, unicode);
1025 
1026  qStreamNtlmString(s, b.userStr, unicode);
1027 
1028  if (!b.workstationStr.isEmpty())
1029  qStreamNtlmString(s, b.workstationStr, unicode);
1030 
1031  // Send auth info
1034 
1035 
1036  return s;
1037 }
static void qStreamNtlmString(QDataStream &ds, const QString &s, bool unicode)
QByteArray lmResponseBuf
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QByteArray ntlmResponseBuf
#define NTLMSSP_NEGOTIATE_UNICODE
static void qStreamNtlmBuffer(QDataStream &ds, const QByteArray &s)
int writeRawData(const char *, int len)
Writes len bytes from s to the stream.

◆ operator>>()

static QDataStream& operator>> ( QDataStream s,
QNtlmBuffer b 
)
static

Definition at line 944 of file qauthenticator.cpp.

945 {
946  s >> b.len >> b.maxLen >> b.offset;
947  return s;
948 }

◆ qCreatev2Hash()

static QByteArray qCreatev2Hash ( const QAuthenticatorPrivate ctx,
QNtlmPhase3Block phase3 
)
static

Definition at line 1199 of file qauthenticator.cpp.

Referenced by qEncodeLmv2Response(), and qEncodeNtlmv2Response().

1201 {
1202  Q_ASSERT(phase3 != 0);
1203  // since v2 Hash is need for both NTLMv2 and LMv2 it is calculated
1204  // only once and stored and reused
1205  if(phase3->v2Hash.size() == 0) {
1207  QByteArray passUnicode = qStringAsUcs2Le(ctx->password);
1208  md4.addData(passUnicode.data(), passUnicode.size());
1209 
1210  QByteArray hashKey = md4.result();
1211  Q_ASSERT(hashKey.size() == 16);
1212  // Assuming the user and domain is always unicode in challenge
1213  QByteArray message =
1215  qStringAsUcs2Le(phase3->domainStr);
1216 
1217  phase3->v2Hash = qEncodeHmacMd5(hashKey, message);
1218  }
1219  return phase3->v2Hash;
1220 }
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
Definition: qstring.cpp:5483
static QByteArray qStringAsUcs2Le(const QString &src)
QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
The QCryptographicHash class provides a way to generate cryptographic hashes.

◆ qEncodeHmacMd5()

QByteArray qEncodeHmacMd5 ( QByteArray key,
const QByteArray message 
)

Definition at line 1139 of file qauthenticator.cpp.

Referenced by qCreatev2Hash(), qEncodeLmv2Response(), and qEncodeNtlmv2Response().

1140 {
1141  Q_ASSERT_X(!(message.isEmpty()),"qEncodeHmacMd5", "Empty message check");
1142  Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check");
1143 
1145  QByteArray hMsg;
1146 
1147  QByteArray iKeyPad(blockSize, 0x36);
1148  QByteArray oKeyPad(blockSize, 0x5c);
1149 
1150  hash.reset();
1151  // Adjust the key length to blockSize
1152 
1153  if(blockSize < key.length()) {
1154  hash.addData(key);
1155  key = hash.result(); //MD5 will always return 16 bytes length output
1156  }
1157 
1158  //Key will be <= 16 or 20 bytes as hash function (MD5 or SHA hash algorithms)
1159  //key size can be max of Block size only
1160  key = key.leftJustified(blockSize,0,true);
1161 
1162  //iKeyPad, oKeyPad and key are all of same size "blockSize"
1163 
1164  //xor of iKeyPad with Key and store the result into iKeyPad
1165  for(int i = 0; i<key.size();i++) {
1166  iKeyPad[i] = key[i]^iKeyPad[i];
1167  }
1168 
1169  //xor of oKeyPad with Key and store the result into oKeyPad
1170  for(int i = 0; i<key.size();i++) {
1171  oKeyPad[i] = key[i]^oKeyPad[i];
1172  }
1173 
1174  iKeyPad.append(message); // (K0 xor ipad) || text
1175 
1176  hash.reset();
1177  hash.addData(iKeyPad);
1178  hMsg = hash.result();
1179  //Digest gen after pass-1: H((K0 xor ipad)||text)
1180 
1181  QByteArray hmacDigest;
1182  oKeyPad.append(hMsg);
1183  hash.reset();
1184  hash.addData(oKeyPad);
1185  hmacDigest = hash.result();
1186  // H((K0 xor opad )|| H((K0 xor ipad) || text))
1187 
1188  /*hmacDigest should not be less than half the length of the HMAC output
1189  (to match the birthday attack bound) and not less than 80 bits
1190  (a suitable lower bound on the number of bits that need to be
1191  predicted by an attacker).
1192  Refer RFC 2104 for more details on truncation part */
1193 
1194  /*MD5 hash always returns 16 byte digest only and HMAC-MD5 spec
1195  (RFC 2104) also says digest length should be 16 bytes*/
1196  return hmacDigest;
1197 }
static uint hash(const uchar *p, int n)
Definition: qhash.cpp:68
const int blockSize
QByteArray & append(char c)
Appends the character ch to this byte array.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray leftJustified(int width, char fill=' ', bool truncate=false) const
Returns a byte array of size width that contains this byte array padded by the fill character...
int length() const
Same as size().
Definition: qbytearray.h:356
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QCryptographicHash class provides a way to generate cryptographic hashes.

◆ qEncodeLmv2Response()

static QByteArray qEncodeLmv2Response ( const QAuthenticatorPrivate ctx,
const QNtlmPhase2Block ch,
QNtlmPhase3Block phase3 
)
static

Definition at line 1326 of file qauthenticator.cpp.

Referenced by qNtlmPhase3().

1329 {
1330  Q_ASSERT(phase3 != 0);
1331  // return value stored in phase3
1332  qCreatev2Hash(ctx, phase3);
1333 
1334  QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
1335  QByteArray clientCh = clientChallenge(ctx);
1336 
1337  message.append(clientCh);
1338 
1339  QByteArray lmChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
1340  lmChallengeResp.append(clientCh);
1341 
1342  return lmChallengeResp;
1343 }
QByteArray & append(char c)
Appends the character ch to this byte array.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)
static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx, QNtlmPhase3Block *phase3)
unsigned char challenge[8]

◆ qEncodeNtlmBuffer()

static int qEncodeNtlmBuffer ( QNtlmBuffer buf,
int  offset,
const QByteArray s 
)
static

Definition at line 918 of file qauthenticator.cpp.

Referenced by qEncodeNtlmString(), and qNtlmPhase3().

919 {
920  buf.len = s.size();
921  buf.maxLen = buf.len;
922  buf.offset = (offset + 1) & ~1;
923  return buf.offset + buf.len;
924 }
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402

◆ qEncodeNtlmString()

static int qEncodeNtlmString ( QNtlmBuffer buf,
int  offset,
const QString s,
bool  unicode 
)
static

Definition at line 927 of file qauthenticator.cpp.

Referenced by qNtlmPhase3().

928 {
929  if (!unicode)
930  return qEncodeNtlmBuffer(buf, offset, s.toLatin1());
931  buf.len = 2 * s.length();
932  buf.maxLen = buf.len;
933  buf.offset = (offset + 1) & ~1;
934  return buf.offset + buf.len;
935 }
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
static int qEncodeNtlmBuffer(QNtlmBuffer &buf, int offset, const QByteArray &s)

◆ qEncodeNtlmv2Response()

static QByteArray qEncodeNtlmv2Response ( const QAuthenticatorPrivate ctx,
const QNtlmPhase2Block ch,
QNtlmPhase3Block phase3 
)
static

Definition at line 1255 of file qauthenticator.cpp.

Referenced by qNtlmPhase3().

1258 {
1259  Q_ASSERT(phase3 != 0);
1260  // return value stored in phase3
1261  qCreatev2Hash(ctx, phase3);
1262 
1263  QByteArray temp;
1264  QDataStream ds(&temp, QIODevice::WriteOnly);
1265  ds.setByteOrder(QDataStream::LittleEndian);
1266 
1267  ds << respversion;
1268  ds << hirespversion;
1269 
1270  //Reserved
1271  QByteArray reserved1(6, 0);
1272  ds.writeRawData(reserved1.constData(), reserved1.size());
1273 
1274  quint64 time = 0;
1275  QByteArray timeArray;
1276 
1277  if(ch.targetInfo.len)
1278  {
1279  timeArray = qExtractServerTime(ch.targetInfoBuff);
1280  }
1281 
1282  //if server sends time, use it instead of current time
1283  if(timeArray.size()) {
1284  ds.writeRawData(timeArray.constData(), timeArray.size());
1285  } else {
1286  QDateTime currentTime(QDate::currentDate(),
1288 
1289  // number of seconds between 1601 and epoc(1970)
1290  // 369 years, 89 leap years
1291  // ((369 * 365) + 89) * 24 * 3600 = 11644473600
1292 
1293  time = Q_UINT64_C(currentTime.toTime_t() + 11644473600);
1294 
1295  // represented as 100 nano seconds
1296  time = Q_UINT64_C(time * 10000000);
1297  ds << time;
1298  }
1299 
1300  //8 byte client challenge
1301  QByteArray clientCh = clientChallenge(ctx);
1302  ds.writeRawData(clientCh.constData(), clientCh.size());
1303 
1304  //Reserved
1305  QByteArray reserved2(4, 0);
1306  ds.writeRawData(reserved2.constData(), reserved2.size());
1307 
1308  if (ch.targetInfo.len > 0) {
1309  ds.writeRawData(ch.targetInfoBuff.constData(),
1310  ch.targetInfoBuff.size());
1311  }
1312 
1313  //Reserved
1314  QByteArray reserved3(4, 0);
1315  ds.writeRawData(reserved3.constData(), reserved3.size());
1316 
1317  QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
1318  message.append(temp);
1319 
1320  QByteArray ntChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
1321  ntChallengeResp.append(temp);
1322 
1323  return ntChallengeResp;
1324 }
QByteArray & append(char c)
Appends the character ch to this byte array.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QByteArray targetInfoBuff
const quint8 respversion
unsigned __int64 quint64
Definition: qglobal.h:943
static QDate currentDate()
Returns the current date, as reported by the system clock.
Definition: qdatetime.cpp:3115
static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)
static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx, QNtlmPhase3Block *phase3)
const quint8 hirespversion
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
unsigned char challenge[8]
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
static QTime currentTime()
Returns the current time as reported by the system clock.
Definition: qdatetime.cpp:3125
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
#define Q_UINT64_C(c)
Definition: qglobal.h:941
static QByteArray qExtractServerTime(const QByteArray &targetInfoBuff)

◆ qExtractServerTime()

static QByteArray qExtractServerTime ( const QByteArray targetInfoBuff)
static

Definition at line 1230 of file qauthenticator.cpp.

Referenced by qEncodeNtlmv2Response().

1231 {
1232  QByteArray timeArray;
1233  QDataStream ds(targetInfoBuff);
1234  ds.setByteOrder(QDataStream::LittleEndian);
1235 
1236  quint16 avId;
1237  quint16 avLen;
1238 
1239  ds >> avId;
1240  ds >> avLen;
1241  while(avId != 0) {
1242  if(avId == AVTIMESTAMP) {
1243  timeArray.resize(avLen);
1244  //avLen size of QByteArray is allocated
1245  ds.readRawData(timeArray.data(), avLen);
1246  break;
1247  }
1248  ds.skipRawData(avLen);
1249  ds >> avId;
1250  ds >> avLen;
1251  }
1252  return timeArray;
1253 }
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
unsigned short quint16
Definition: qglobal.h:936
#define AVTIMESTAMP
void resize(int size)
Sets the size of the byte array to size bytes.
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71

◆ qNtlmDecodePhase2()

static bool qNtlmDecodePhase2 ( const QByteArray data,
QNtlmPhase2Block ch 
)
static

Definition at line 1345 of file qauthenticator.cpp.

Referenced by qNtlmPhase3().

1346 {
1348  if (data.size() < QNtlmPhase2BlockBase::Size)
1349  return false;
1350 
1351 
1352  QDataStream ds(data);
1353  ds.setByteOrder(QDataStream::LittleEndian);
1354  if (ds.readRawData(ch.magic, 8) < 8)
1355  return false;
1356  if (strncmp(ch.magic, "NTLMSSP", 8) != 0)
1357  return false;
1358 
1359  ds >> ch.type;
1360  if (ch.type != 2)
1361  return false;
1362 
1363  ds >> ch.targetName;
1364  ds >> ch.flags;
1365  if (ds.readRawData((char *)ch.challenge, 8) < 8)
1366  return false;
1367  ds >> ch.context[0] >> ch.context[1];
1368  ds >> ch.targetInfo;
1369 
1370  if (ch.targetName.len > 0) {
1371  if (ch.targetName.len + ch.targetName.offset >= (unsigned)data.size())
1372  return false;
1373 
1375  }
1376 
1377  if (ch.targetInfo.len > 0) {
1378  if (ch.targetInfo.len + ch.targetInfo.offset > (unsigned)data.size())
1379  return false;
1380 
1381  ch.targetInfoBuff = data.mid(ch.targetInfo.offset, ch.targetInfo.len);
1382  }
1383 
1384  return true;
1385 }
static QString qStringFromUcs2Le(const QByteArray &src)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QByteArray targetInfoBuff
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
unsigned char challenge[8]
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71

◆ qNtlmPhase1()

static QByteArray qNtlmPhase1 ( )
static

Definition at line 1040 of file qauthenticator.cpp.

Referenced by QAuthenticatorPrivate::calculateResponse().

1041 {
1042  QByteArray rc;
1044  ds.setByteOrder(QDataStream::LittleEndian);
1045  QNtlmPhase1Block pb;
1046  ds << pb;
1047  return rc;
1048 }
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71

◆ qNtlmPhase3()

static QByteArray qNtlmPhase3 ( QAuthenticatorPrivate ctx,
const QByteArray phase2data 
)
static

Definition at line 1388 of file qauthenticator.cpp.

Referenced by QAuthenticatorPrivate::calculateResponse().

1389 {
1390  QNtlmPhase2Block ch;
1391  if (!qNtlmDecodePhase2(phase2data, ch))
1392  return QByteArray();
1393 
1394  QByteArray rc;
1396  ds.setByteOrder(QDataStream::LittleEndian);
1397  QNtlmPhase3Block pb;
1398 
1399  bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE;
1400 
1402  if (unicode)
1404  else
1406 
1407 
1408  int offset = QNtlmPhase3BlockBase::Size;
1410 
1411  // for kerberos style user@domain logins, NTLM domain string should be left empty
1412  if (ctx->userDomain.isEmpty() && !ctx->extractedUser.contains(QLatin1Char('@'))) {
1413  offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode);
1414  pb.domainStr = ch.targetNameStr;
1415  } else {
1416  offset = qEncodeNtlmString(pb.domain, offset, ctx->userDomain, unicode);
1417  pb.domainStr = ctx->userDomain;
1418  }
1419 
1420  offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode);
1421  pb.userStr = ctx->extractedUser;
1422 
1423  offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode);
1424  pb.workstationStr = ctx->workstation;
1425 
1426  // Get LM response
1427 #ifdef NTLMV1_CLIENT
1428  pb.lmResponseBuf = qEncodeLmResponse(ctx, ch);
1429 #else
1430  if (ch.targetInfo.len > 0) {
1431  pb.lmResponseBuf = QByteArray();
1432  } else {
1433  pb.lmResponseBuf = qEncodeLmv2Response(ctx, ch, &pb);
1434  }
1435 #endif
1436  offset = qEncodeNtlmBuffer(pb.lmResponse, offset, pb.lmResponseBuf);
1437 
1438  // Get NTLM response
1439 #ifdef NTLMV1_CLIENT
1440  pb.ntlmResponseBuf = qEncodeNtlmResponse(ctx, ch);
1441 #else
1442  pb.ntlmResponseBuf = qEncodeNtlmv2Response(ctx, ch, &pb);
1443 #endif
1444  offset = qEncodeNtlmBuffer(pb.ntlmResponse, offset, pb.ntlmResponseBuf);
1445 
1446 
1447  // Encode and send
1448  ds << pb;
1449 
1450  return rc;
1451 }
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
#define NTLMSSP_NEGOTIATE_OEM
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray lmResponseBuf
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QByteArray ntlmResponseBuf
#define NTLMSSP_NEGOTIATE_UNICODE
#define NTLMSSP_NEGOTIATE_NTLM
static bool qNtlmDecodePhase2(const QByteArray &data, QNtlmPhase2Block &ch)
static int qEncodeNtlmString(QNtlmBuffer &buf, int offset, const QString &s, bool unicode)
static int qEncodeNtlmBuffer(QNtlmBuffer &buf, int offset, const QByteArray &s)
static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block &ch, QNtlmPhase3Block *phase3)
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block &ch, QNtlmPhase3Block *phase3)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55

◆ qStreamNtlmBuffer()

static void qStreamNtlmBuffer ( QDataStream ds,
const QByteArray s 
)
static

Definition at line 899 of file qauthenticator.cpp.

Referenced by operator<<(), and qStreamNtlmString().

900 {
901  ds.writeRawData(s.constData(), s.size());
902 }
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
int writeRawData(const char *, int len)
Writes len bytes from s to the stream.

◆ qStreamNtlmString()

static void qStreamNtlmString ( QDataStream ds,
const QString s,
bool  unicode 
)
static

Definition at line 905 of file qauthenticator.cpp.

Referenced by operator<<().

906 {
907  if (!unicode) {
908  qStreamNtlmBuffer(ds, s.toLatin1());
909  return;
910  }
911  const ushort *d = s.utf16();
912  for (int i = 0; i < s.length(); ++i)
913  ds << d[i];
914 }
double d
Definition: qnumeric_p.h:62
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
unsigned short ushort
Definition: qglobal.h:995
static void qStreamNtlmBuffer(QDataStream &ds, const QByteArray &s)
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290

◆ qStringAsUcs2Le()

static QByteArray qStringAsUcs2Le ( const QString src)
static

Definition at line 1051 of file qauthenticator.cpp.

Referenced by qCreatev2Hash(), and qStringFromUcs2Le().

1052 {
1053  QByteArray rc(2*src.length(), 0);
1054  const unsigned short *s = src.utf16();
1055  unsigned short *d = (unsigned short*)rc.data();
1056  for (int i = 0; i < src.length(); ++i) {
1057  d[i] = qToLittleEndian(s[i]);
1058  }
1059  return rc;
1060 }
double d
Definition: qnumeric_p.h:62
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
T qToLittleEndian(T source)
Definition: qendian.h:341
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290

◆ qStringFromUcs2Le()

static QString qStringFromUcs2Le ( const QByteArray src)
static

Definition at line 1063 of file qauthenticator.cpp.

Referenced by qNtlmDecodePhase2().

1064 {
1065  Q_ASSERT(src.size() % 2 == 0);
1066  unsigned short *d = (unsigned short*)src.data();
1067  for (int i = 0; i < src.length() / 2; ++i) {
1068  d[i] = qFromLittleEndian(d[i]);
1069  }
1070  return QString((const QChar *)src.data(), src.size()/2);
1071 }
double d
Definition: qnumeric_p.h:62
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
int length() const
Same as size().
Definition: qbytearray.h:356
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
T qFromLittleEndian(const uchar *src)

Variable Documentation

◆ blockSize

const int blockSize = 64

◆ hirespversion

const quint8 hirespversion = 1

Definition at line 832 of file qauthenticator.cpp.

Referenced by qEncodeNtlmv2Response().

◆ nDigestLen

const int nDigestLen = 16

Definition at line 830 of file qauthenticator.cpp.

◆ respversion

const quint8 respversion = 1

Definition at line 831 of file qauthenticator.cpp.

Referenced by qEncodeNtlmv2Response().