aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2010-08-20 12:02:31 +0000
committerJeremy Lainé <jeremy.laine@m4x.org>2010-08-20 12:02:31 +0000
commit5008f4e433c305f63b6b6dbd4d8545ab4cb9d4b4 (patch)
treec07f32e1809b7c08b8929a7bb79ef10475b9cd79
parent62818276185a1737ae67c162fd9c4929f6ba9629 (diff)
downloadqxmpp-5008f4e433c305f63b6b6dbd4d8545ab4cb9d4b4.tar.gz
add and test better auth-md5 parser (not used yet)
-rw-r--r--src/QXmppUtils.cpp63
-rw-r--r--src/QXmppUtils.h5
-rw-r--r--tests/tests.cpp36
-rw-r--r--tests/tests.h1
4 files changed, 96 insertions, 9 deletions
diff --git a/src/QXmppUtils.cpp b/src/QXmppUtils.cpp
index 4f8b84f2..ec84e8c5 100644
--- a/src/QXmppUtils.cpp
+++ b/src/QXmppUtils.cpp
@@ -286,4 +286,67 @@ QString unescapeString(const QString& str)
return strOut;
}
+QMap<QByteArray, QByteArray> parseDigestMd5(const QByteArray &ba)
+{
+ QMap<QByteArray, QByteArray> map;
+ int startIndex = 0;
+ int pos = 0;
+ while ((pos = ba.indexOf("=", startIndex)) >= 0)
+ {
+ // key get name and skip equals
+ const QByteArray key = ba.mid(startIndex, pos - startIndex).trimmed();
+ pos++;
+
+ // check whether string is quoted
+ if (ba.at(pos) == '"')
+ {
+ // skip opening quote
+ pos++;
+ int endPos = ba.indexOf('"', pos);
+ if (endPos < 0)
+ {
+ qWarning("Unfinished quoted string");
+ return map;
+ }
+ map[key] = ba.mid(pos, endPos - pos);
+ // skip closing quote and comma
+ startIndex = endPos + 2;
+ } else {
+ // non-quoted string
+ int endPos = ba.indexOf(',', pos);
+ if (endPos < 0)
+ endPos = ba.size();
+ map[key] = ba.mid(pos, endPos - pos);
+ // skip comma
+ startIndex = endPos + 1;
+ }
+ }
+ return map;
+}
+QByteArray serializeDigestMd5(const QMap<QByteArray, QByteArray> &map)
+{
+ QByteArray ba;
+ foreach (const QByteArray &key, map.keys())
+ {
+ if (!ba.isEmpty())
+ ba.append(',');
+ ba.append(key + "=");
+ const QByteArray value = map[key];
+ const char *separators = "()<>@,;:\\\"/[]?={} \t";
+ bool quote = false;
+ for (const char *c = separators; *c; c++)
+ {
+ if (value.contains(*c))
+ {
+ quote = true;
+ break;
+ }
+ }
+ if (quote)
+ ba.append("\"" + value + "\"");
+ else
+ ba.append(value);
+ }
+ return ba;
+}
diff --git a/src/QXmppUtils.h b/src/QXmppUtils.h
index 919cf6be..4fc9d9c7 100644
--- a/src/QXmppUtils.h
+++ b/src/QXmppUtils.h
@@ -26,6 +26,7 @@
#ifndef QXMPPUTILS_H
#define QXMPPUTILS_H
+#include <QMap>
// forward declarations of QXmlStream* classes will not work on Mac, we need to
// include the whole header.
@@ -63,4 +64,8 @@ void helperToXmlAddNumberElement(QXmlStreamWriter* stream, const QString& name,
QString escapeString(const QString& str);
QString unescapeString(const QString& str);
+// Digest MD5 authentication
+QMap<QByteArray, QByteArray> parseDigestMd5(const QByteArray &ba);
+QByteArray serializeDigestMd5(const QMap<QByteArray, QByteArray> &map);
+
#endif // QXMPPUTILS_H
diff --git a/tests/tests.cpp b/tests/tests.cpp
index 22c3eeba..981c3abf 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -39,6 +39,33 @@
#include "QXmppUtils.h"
#include "tests.h"
+void TestUtils::testCrc32()
+{
+ quint32 crc = generateCrc32(QByteArray());
+ QCOMPARE(crc, 0u);
+
+ crc = generateCrc32(QByteArray("Hi There"));
+ QCOMPARE(crc, 0xDB143BBEu);
+}
+
+void TestUtils::testDigestMd5()
+{
+ // empty
+ QMap<QByteArray, QByteArray> empty = parseDigestMd5(QByteArray());
+ QCOMPARE(empty.size(), 0);
+ QCOMPARE(serializeDigestMd5(empty), QByteArray());
+
+ // non-empty
+ const QByteArray bytes("number=12345,quoted=\"quoted string\",string=string");
+
+ QMap<QByteArray, QByteArray> map = parseDigestMd5(bytes);
+ QCOMPARE(map.size(), 3);
+ QCOMPARE(map["number"], QByteArray("12345"));
+ QCOMPARE(map["quoted"], QByteArray("quoted string"));
+ QCOMPARE(map["string"], QByteArray("string"));
+ QCOMPARE(serializeDigestMd5(map), bytes);
+}
+
void TestUtils::testHmac()
{
QByteArray hmac = generateHmacMd5(QByteArray(16, 0x0b), QByteArray("Hi There"));
@@ -51,15 +78,6 @@ void TestUtils::testHmac()
QCOMPARE(hmac, QByteArray::fromHex("56be34521d144c88dbb8c733f0e8b3f6"));
}
-void TestUtils::testCrc32()
-{
- quint32 crc = generateCrc32(QByteArray());
- QCOMPARE(crc, 0u);
-
- crc = generateCrc32(QByteArray("Hi There"));
- QCOMPARE(crc, 0xDB143BBEu);
-}
-
template <class T>
static void parsePacket(T &packet, const QByteArray &xml)
{
diff --git a/tests/tests.h b/tests/tests.h
index 6fa076b6..05f891b6 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -29,6 +29,7 @@ class TestUtils : public QObject
private slots:
void testCrc32();
+ void testDigestMd5();
void testHmac();
};