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 |