src/network/kernel/qauthenticator.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    50 #include <qdatastream.h>
    50 #include <qdatastream.h>
    51 #include <qendian.h>
    51 #include <qendian.h>
    52 #include <qstring.h>
    52 #include <qstring.h>
    53 #include <qdatetime.h>
    53 #include <qdatetime.h>
    54 
    54 
       
    55 //#define NTLMV1_CLIENT
    55 
    56 
    56 QT_BEGIN_NAMESPACE
    57 QT_BEGIN_NAMESPACE
    57 
    58 
       
    59 #ifdef NTLMV1_CLIENT
    58 #include "../../3rdparty/des/des.cpp"
    60 #include "../../3rdparty/des/des.cpp"
       
    61 #endif
    59 
    62 
    60 static QByteArray qNtlmPhase1();
    63 static QByteArray qNtlmPhase1();
    61 static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
    64 static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
    62 
    65 
    63 /*!
    66 /*!
   201   Sets the \a user used for authentication.
   204   Sets the \a user used for authentication.
   202 */
   205 */
   203 void QAuthenticator::setUser(const QString &user)
   206 void QAuthenticator::setUser(const QString &user)
   204 {
   207 {
   205     detach();
   208     detach();
   206 
       
   207     int separatorPosn = 0;
   209     int separatorPosn = 0;
   208     separatorPosn = user.indexOf(QLatin1String("\\"));
   210 
   209 
   211     switch(d->method) {
   210     if (separatorPosn == -1) {
   212     case QAuthenticatorPrivate::DigestMd5:
   211         //No domain name present
   213     case QAuthenticatorPrivate::Ntlm:
       
   214         if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1)
       
   215         {
       
   216             //domain name is present
       
   217             d->realm = user.left(separatorPosn);
       
   218             d->user = user.mid(separatorPosn + 1);
       
   219         } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
       
   220             //domain name is present
       
   221             d->realm = user.mid(separatorPosn + 1);
       
   222             d->user = user.left(separatorPosn);
       
   223         } else {
       
   224             d->user = user;
       
   225             d->realm.clear();
       
   226         }
       
   227         break;
       
   228     // For other auth mechanisms, domain name will be part of username
       
   229     default:
   212         d->user = user;
   230         d->user = user;
   213     } else {
   231         break;
   214         //domain name is present
       
   215         d->realm = user.left(separatorPosn);
       
   216         d->user = user.mid(separatorPosn+1);
       
   217     }
   232     }
   218 }
   233 }
   219 
   234 
   220 /*!
   235 /*!
   221   returns the password used for authentication.
   236   returns the password used for authentication.
  1176     QByteArray clientCh = ctx->cnonce.right(8);
  1191     QByteArray clientCh = ctx->cnonce.right(8);
  1177     return clientCh;
  1192     return clientCh;
  1178 }
  1193 }
  1179 
  1194 
  1180 // caller has to ensure a valid targetInfoBuff
  1195 // caller has to ensure a valid targetInfoBuff
  1181 static bool qExtractServerTime(const QByteArray& targetInfoBuff,
  1196 static QByteArray qExtractServerTime(const QByteArray& targetInfoBuff)
  1182                                quint64 *serverTime)
  1197 {
  1183 {
  1198     QByteArray timeArray;
  1184     Q_ASSERT(serverTime != 0);
       
  1185     bool retValue = false;
       
  1186     QDataStream ds(targetInfoBuff);
  1199     QDataStream ds(targetInfoBuff);
  1187     ds.setByteOrder(QDataStream::LittleEndian);
  1200     ds.setByteOrder(QDataStream::LittleEndian);
  1188 
  1201 
  1189     quint16 avId;
  1202     quint16 avId;
  1190     quint16 avLen;
  1203     quint16 avLen;
  1191 
  1204 
  1192     ds >> avId;
  1205     ds >> avId;
  1193     ds >> avLen;
  1206     ds >> avLen;
  1194     while(avId != 0) {
  1207     while(avId != 0) {
  1195         if(avId == AVTIMESTAMP) {
  1208         if(avId == AVTIMESTAMP) {
  1196             QByteArray timeArray(avLen, 0);
  1209             timeArray.resize(avLen);
  1197             //avLen size of QByteArray is allocated
  1210             //avLen size of QByteArray is allocated
  1198             ds.readRawData(timeArray.data(), avLen);
  1211             ds.readRawData(timeArray.data(), avLen);
  1199             bool ok;
       
  1200             *serverTime = timeArray.toHex().toLongLong(&ok, 16);
       
  1201             retValue = true;
       
  1202             break;
  1212             break;
  1203         }
  1213         }
  1204         ds.skipRawData(avLen);
  1214         ds.skipRawData(avLen);
  1205         ds >> avId;
  1215         ds >> avId;
  1206         ds >> avLen;
  1216         ds >> avLen;
  1207     }
  1217     }
  1208     return retValue;
  1218     return timeArray;
  1209 }
  1219 }
  1210 
  1220 
  1211 static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
  1221 static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
  1212                                         const QNtlmPhase2Block& ch,
  1222                                         const QNtlmPhase2Block& ch,
  1213                                         QNtlmPhase3Block *phase3)
  1223                                         QNtlmPhase3Block *phase3)
  1226     //Reserved
  1236     //Reserved
  1227     QByteArray reserved1(6, 0);
  1237     QByteArray reserved1(6, 0);
  1228     ds.writeRawData(reserved1.constData(), reserved1.size());
  1238     ds.writeRawData(reserved1.constData(), reserved1.size());
  1229 
  1239 
  1230     quint64 time = 0;
  1240     quint64 time = 0;
       
  1241     QByteArray timeArray;
       
  1242 
       
  1243     if(ch.targetInfo.len)
       
  1244     {
       
  1245         timeArray = qExtractServerTime(ch.targetInfoBuff);
       
  1246     }
  1231 
  1247 
  1232     //if server sends time, use it instead of current time
  1248     //if server sends time, use it instead of current time
  1233     if(!(ch.targetInfo.len && qExtractServerTime(ch.targetInfoBuff, &time))) {
  1249     if(timeArray.size()) {
       
  1250         ds.writeRawData(timeArray.constData(), timeArray.size());
       
  1251     } else {
  1234         QDateTime currentTime(QDate::currentDate(),
  1252         QDateTime currentTime(QDate::currentDate(),
  1235                               QTime::currentTime(), Qt::UTC);
  1253                               QTime::currentTime(), Qt::UTC);
  1236 
  1254 
  1237         // number of seconds between 1601 and epoc(1970)
  1255         // number of seconds between 1601 and epoc(1970)
  1238         // 369 years, 89 leap years
  1256         // 369 years, 89 leap years
  1240 
  1258 
  1241         time = Q_UINT64_C(currentTime.toTime_t() + 11644473600);
  1259         time = Q_UINT64_C(currentTime.toTime_t() + 11644473600);
  1242 
  1260 
  1243         // represented as 100 nano seconds
  1261         // represented as 100 nano seconds
  1244         time = Q_UINT64_C(time * 10000000);
  1262         time = Q_UINT64_C(time * 10000000);
  1245     }
  1263         ds << time;
  1246     ds << time;
  1264     }
  1247 
  1265 
  1248     //8 byte client challenge
  1266     //8 byte client challenge
  1249     QByteArray clientCh = clientChallenge(ctx);
  1267     QByteArray clientCh = clientChallenge(ctx);
  1250     ds.writeRawData(clientCh.constData(), clientCh.size());
  1268     ds.writeRawData(clientCh.constData(), clientCh.size());
  1251 
  1269