1
0
Fork 0
forked from blue/squawk

cant believe it, first ever encrypted messages!

This commit is contained in:
Blue 2023-11-05 16:29:44 -03:00
parent a7d1a28f29
commit 637eb702a8
Signed by untrusted user: blue
GPG key ID: 9B203B252A63EE38
10 changed files with 190 additions and 69 deletions

View file

@ -71,26 +71,12 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) {
case QXmppMessage::GroupChat:
handled = handleGroupMessage(msg);
break;
case QXmppMessage::Error: {
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(msg.id());
if (std::get<0>(ids)) {
QString id = std::get<1>(ids);
QString jid = std::get<2>(ids);
RosterItem* cnt = acc->rh->getRosterItem(jid);
QMap<QString, QVariant> cData = {
{"state", static_cast<uint>(Shared::Message::State::error)},
{"errorText", msg.error().text()}
};
if (cnt != nullptr)
cnt->changeMessage(id, cData);
emit acc->changeMessage(jid, id, cData);
handled = true;
} else {
case QXmppMessage::Error:
handled = handlePendingMessageError(msg.id(), msg.error().text());
if (!handled)
qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping";
}
}
break;
break;
case QXmppMessage::Headline:
qDebug() << "received a message with type \"Headline\", not sure what to do with it now, skipping";
break;
@ -99,6 +85,27 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) {
logMessage(msg);
}
bool Core::MessageHandler::handlePendingMessageError(const QString& id, const QString& errorText) {
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(id);
if (std::get<0>(ids)) {
QString id = std::get<1>(ids);
QString jid = std::get<2>(ids);
RosterItem* ri = acc->rh->getRosterItem(jid);
QMap<QString, QVariant> cData = {
{"state", static_cast<uint>(Shared::Message::State::error)},
{"errorText", errorText}
};
if (ri != nullptr)
ri->changeMessage(id, cData);
emit acc->changeMessage(jid, id, cData);
return true;
}
return false;
}
bool Core::MessageHandler::handleChatMessage(const QXmppMessage& msg, bool outgoing, bool forwarded, bool guessing) {
if (msg.body().size() != 0 || msg.outOfBandUrl().size() > 0) {
Shared::Message sMsg(Shared::Message::chat);
@ -182,9 +189,9 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
QString id;
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0)
id = source.originId();
if (id.size() == 0) {
if (id.size() == 0)
id = source.id();
}
target.setStanzaId(source.stanzaId());
qDebug() << "initializing message with originId:" << source.originId() << ", id:" << source.id() << ", stansaId:" << source.stanzaId();
#else
@ -202,24 +209,19 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
target.setBody(source.body());
target.setForwarded(forwarded);
if (guessing) {
if (target.getFromJid() == acc->getBareJid()) {
outgoing = true;
} else {
outgoing = false;
}
}
if (guessing)
outgoing = target.getFromJid() == acc->getBareJid();
target.setOutgoing(outgoing);
if (time.isValid()) {
if (time.isValid())
target.setTime(time);
} else {
else
target.setCurrentTime();
}
QString oob = source.outOfBandUrl();
if (oob.size() > 0) {
if (oob.size() > 0)
target.setAttachPath(acc->network->addMessageAndCheckForPath(oob, acc->getName(), target.getPenPalJid(), messageId));
}
target.setOutOfBandUrl(oob);
}
@ -249,7 +251,7 @@ void Core::MessageHandler::onCarbonMessageSent(const QXmppMessage& msg) {
}
#endif
std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessageId(const QString& id) {
std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessageId(const QString& id, bool clear) {
std::tuple<bool, QString, QString> result({false, "", ""});
std::map<QString, QString>::const_iterator itr = pendingStateMessages.find(id);
if (itr != pendingStateMessages.end()) {
@ -263,12 +265,14 @@ std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessa
else
std::get<1>(result) = itr->first;
pendingCorrectionMessages.erase(itrC);
if (clear)
pendingCorrectionMessages.erase(itrC);
} else {
std::get<1>(result) = itr->first;
}
pendingStateMessages.erase(itr);
if (clear)
pendingStateMessages.erase(itr);
}
return result;
@ -281,9 +285,9 @@ void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString&
QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::delivered)}};
RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids));
if (ri != nullptr) {
if (ri != nullptr)
ri->changeMessage(std::get<1>(ids), cData);
}
emit acc->changeMessage(std::get<2>(ids), std::get<1>(ids), cData);
}
}
@ -302,45 +306,25 @@ void Core::MessageHandler::performSending(Shared::Message data, const QString& o
QString id = data.getId();
qDebug() << "Sending message with id:" << id;
if (originalId.size() > 0)
qDebug() << "To replace one with id:" << originalId;
qDebug() << "To replace the one with id:" << originalId;
RosterItem* ri = acc->rh->getRosterItem(jid);
bool sent = false;
if (newMessage && originalId.size() > 0)
newMessage = false;
QDateTime sendTime = QDateTime::currentDateTimeUtc();
if (acc->state == Shared::ConnectionState::connected) {
QXmppMessage msg(createPacket(data, sendTime, originalId));
sent = acc->client.sendPacket(msg);
if (sent) {
data.setState(Shared::Message::State::sent);
} else {
data.setState(Shared::Message::State::error);
data.setErrorText("Couldn't send message: internal QXMPP library error, probably need to check out the logs");
}
} else {
data.setState(Shared::Message::State::error);
data.setErrorText("You are is offline or reconnecting");
}
std::pair<Shared::Message::State, QString> result = scheduleSending(data, sendTime, originalId);
data.setState(result.first);
data.setErrorText(result.second);
QMap<QString, QVariant> changes(getChanges(data, sendTime, newMessage, originalId));
QString realId;
if (originalId.size() > 0)
realId = originalId;
else
realId = id;
if (ri != nullptr) {
if (newMessage)
ri->appendMessageToArchive(data);
else
ri->changeMessage(realId, changes);
ri->changeMessage(originalId.isEmpty() ? id : originalId, changes);
if (sent) {
if (data.getState() != Shared::Message::State::error) {
pendingStateMessages.insert(std::make_pair(id, jid));
if (originalId.size() > 0)
pendingCorrectionMessages.insert(std::make_pair(id, originalId));
@ -350,9 +334,81 @@ void Core::MessageHandler::performSending(Shared::Message data, const QString& o
}
}
emit acc->changeMessage(jid, realId, changes);
emit acc->changeMessage(jid, originalId.isEmpty() ? id : originalId, changes);
}
std::pair<Shared::Message::State, QString> Core::MessageHandler::scheduleSending(
const Shared::Message& message,
const QDateTime& sendTime,
const QString& originalId
) {
if (acc->state != Shared::ConnectionState::connected)
return {Shared::Message::State::error, "You are is offline or reconnecting"};
QXmppMessage msg = createPacket(message, sendTime, originalId);
QString id = msg.id();
#ifdef WITH_OMEMO
if (message.getEncryption() == Shared::EncryptionProtocol::omemo2) {
QXmppTask<QXmppE2eeExtension::MessageEncryptResult> task = acc->om->encryptMessage(std::move(msg), std::nullopt);
if (task.isFinished()) {
const QXmppE2eeExtension::MessageEncryptResult& res = task.result();
if (std::holds_alternative<std::unique_ptr<QXmppMessage>>(res)) {
const std::unique_ptr<QXmppMessage>& encrypted = std::get<std::unique_ptr<QXmppMessage>>(res);
bool success = acc->client.sendPacket(*encrypted.get());
if (success)
return {Shared::Message::State::sent, ""};
else
return {Shared::Message::State::error, "Error sending successfully encrypted message"};
} else if (std::holds_alternative<QXmppError>(res)) {
const QXmppError& err = std::get<QXmppError>(res);
return {Shared::Message::State::error, err.description};
} else {
return {Shared::Message::State::error, "Unexpected error ecryptng the message"};
}
} else {
task.then(this, [this, id] (QXmppE2eeExtension::MessageEncryptResult&& result) {
if (std::holds_alternative<std::unique_ptr<QXmppMessage>>(result)) {
const std::unique_ptr<QXmppMessage>& encrypted = std::get<std::unique_ptr<QXmppMessage>>(result);
encrypted->setBody("This message is encrypted with OMEMO 2 but could not be decrypted");
bool success = acc->client.sendPacket(*encrypted.get());
if (success) {
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(id, false);
if (std::get<0>(ids)) {
QString id = std::get<1>(ids);
QString jid = std::get<2>(ids);
RosterItem* ri = acc->rh->getRosterItem(jid);
QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::sent)}};
if (ri != nullptr)
ri->changeMessage(id, cData);
emit acc->changeMessage(jid, id, cData);
} else {
qDebug() << "Encrypted message has been successfully sent, but it couldn't be found to update the sate";
}
} else {
handlePendingMessageError(id, "Error sending successfully encrypted message");
}
} else if (std::holds_alternative<QXmppError>(result)) {
const QXmppError& err = std::get<QXmppError>(result);
handlePendingMessageError(id, err.description);
} else {
handlePendingMessageError(id, "Unexpected error ecryptng the message");
}
});
return {Shared::Message::State::pending, ""};
}
} else
#endif
{
bool success = acc->client.sendPacket(msg);
if (success)
return {Shared::Message::State::sent, ""};
else
return {Shared::Message::State::error, "Error sending message, internal QXMPP error"};
}
}
QMap<QString, QVariant> Core::MessageHandler::getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const {
QMap<QString, QVariant> changes;

View file

@ -23,9 +23,13 @@
#include <deque>
#include <map>
#include <functional>
#include <QXmppMessage.h>
#include <QXmppHttpUploadIq.h>
#ifdef WITH_OMEMO
#include <QXmppE2eeExtension.h>
#endif
#include <shared/message.h>
#include <shared/messageinfo.h>
@ -74,7 +78,9 @@ private:
void handleUploadError(const QString& jid, const QString& messageId, const QString& errorText);
QXmppMessage createPacket(const Shared::Message& data, const QDateTime& time, const QString& originalId) const;
QMap<QString, QVariant> getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const;
std::tuple<bool, QString, QString> getOriginalPendingMessageId(const QString& id);
std::tuple<bool, QString, QString> getOriginalPendingMessageId(const QString& id, bool clear = true);
bool handlePendingMessageError(const QString& id, const QString& errorText);
std::pair<Shared::Message::State, QString> scheduleSending(const Shared::Message& message, const QDateTime& sendTime, const QString& originalId);
private:
Account* acc;