From b96fdab880b6e2586404ea1c222b1a072797fc91 Mon Sep 17 00:00:00 2001 From: APTX Date: Mon, 2 Jan 2012 17:33:52 +0100 Subject: [PATCH] Make sure lib builds without encryption and that encryption failures result in connection errors. --- client.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- client.h | 4 ++-- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/client.cpp b/client.cpp index 778127a..d9bd5ea 100644 --- a/client.cpp +++ b/client.cpp @@ -547,7 +547,14 @@ qDebug() << "Entering Recieve State"; #ifdef ANIDBUDPCLIENT_CLIENT_MISC_DEBUG qDebug() << "ENCRYPED DATAGRAM = " << data; #endif - tmp = decrypt(tmp); + // If using encryption and the reply is possibly valid before encryption, process it without decrypting. + // This is mainly for server errors or cases where the session (and encryption) expires. + // TODO Drop out of encryption if this happens? + if (!possiblyValid(tmp)) + tmp = decrypt(tmp); + + if (tmp.isEmpty()) + goto endLoop; } if (authCommand.compression() && tmp.mid(0, 2) == "00") @@ -875,13 +882,21 @@ void Client::logout(bool force) enqueueControlCommand(createReply(LogoutCommand()), force); } -#ifndef ANIDBUDPCLIENT_NO_ENCRYPT QByteArray Client::encrypt(const QByteArray &data) { +#ifdef ANIDBUDPCLIENT_NO_ENCRYPT + Q_UNUSED(data); + m_error = EncryptionError; + m_errorString = tr("AniDBUDPClient built without encryption support"); + emit connectionError(); + return QByteArray(); +#else QCA::init(); if (!QCA::isSupported("aes128-ecb")) { - qDebug() << "encryption failed due to no aes128-cbc"; + m_error = EncryptionError; + m_errorString = tr("QCA missing required encryption plugins"); + emit connectionError(); return QByteArray(); } @@ -904,14 +919,19 @@ qDebug() << "PADDED DATA\n\t" << paddedData << "\n\t" << paddedData.toHex(); c.final(); // Should be empty as data is already padded // QCA::deinit(); return ret; +#endif } QByteArray Client::decrypt(const QByteArray &data) { +#ifdef ANIDBUDPCLIENT_NO_ENCRYPT + Q_UNUSED(data); + return QByteArray(); +#else QCA::init(); if (!QCA::isSupported("aes128-ecb")) { - qDebug() << "encryption failed due to no aes128-cbc"; + qDebug() << "decryption failed due to no aes128-cbc"; return QByteArray(); } @@ -933,6 +953,15 @@ qDebug() << "PART 2 = " << p2; #endif ret += p2; + if (ret.size() % 16 != 0) + { + // Should be a multiple of cipher block size. +#ifdef ANIDBUDPCLIENT_CLIENT_ENCRYPT_DEBUG +qDebug() << "Ciphertext not a multiple of cipher block size!!"; +#endif + return QByteArray(); + } + // Remove padding (and only it) char pad = ret[ret.size() - 1]; if (pad > 0 && pad < 16) @@ -954,8 +983,21 @@ qDebug() << "PART 2 = " << p2; } // QCA::deinit(); return ret; -} #endif +} + +bool Client::possiblyValid(const QByteArray &reply) const +{ + QByteArray tag = reply.left(5); + if (sentCommands.contains(tag)) + return true; + bool ok; + tag = reply.left(3); + tag.toInt(&ok); + if (ok) + return true; + return false; +} void Client::commandTimeout() { @@ -1088,6 +1130,8 @@ qDebug() << QString("SENDING datagram:\n\t%1\nto: %2 ([%3]:%4) (%5 encryption)") qDebug() << QString("ENCRYPTED datagram:\n\t%1") .arg(datagram.constData()); #endif + if (datagram.isEmpty()) + return; } socket->writeDatagram(datagram, m_hostAddress, m_hostPort); diff --git a/client.h b/client.h index 17d9b56..5cabdb5 100644 --- a/client.h +++ b/client.h @@ -164,10 +164,10 @@ private: void logout(bool force); -#ifndef ANIDBUDPCLIENT_NO_ENCRYPT QByteArray encrypt(const QByteArray &data); QByteArray decrypt(const QByteArray &data); -#endif + + bool possiblyValid(const QByteArray &reply) const; QTimer *commandTimer; QTimer *idleTimer; -- 2.52.0