From e329a07e860f35c60cb575fe6fe7ee4e3a3b27e0 Mon Sep 17 00:00:00 2001 From: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com> Date: Wed, 25 Apr 2018 15:03:16 -0400 Subject: [PATCH] Forbid sending messages/calling banned contacts Also: In order to avoid crashes in the future, we check the contact index variable before using it in conversationmodel. Change-Id: I038c7049781a9bce951f09ed4a0f1d3100e6df3c Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> --- src/api/contact.h | 1 + src/bannedcontactmodel.cpp | 14 +++++++++++++- src/bannedcontactmodel.h | 1 + src/contactmodel.cpp | 9 +++++++++ src/conversationmodel.cpp | 26 ++++++++++++++++++++++++-- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/api/contact.h b/src/api/contact.h index 6a4e7535..07a6b76d 100644 --- a/src/api/contact.h +++ b/src/api/contact.h @@ -39,6 +39,7 @@ struct Info std::string registeredName; bool isTrusted = false; bool isPresent = false; + bool isBanned = false; }; } // namespace contact diff --git a/src/bannedcontactmodel.cpp b/src/bannedcontactmodel.cpp index cbe3b8f4..e4b7e881 100644 --- a/src/bannedcontactmodel.cpp +++ b/src/bannedcontactmodel.cpp @@ -137,8 +137,9 @@ BannedContactModel::columnCount( const QModelIndex& parent ) const void BannedContactModel::add(ContactMethod* cm) { - if (d_ptr->m_lBanned.contains(cm)) + if (isBanned(cm)) return; + beginInsertRows(QModelIndex(),d_ptr->m_lBanned.size(),d_ptr->m_lBanned.size()); d_ptr->m_lBanned << cm; endInsertRows(); @@ -151,6 +152,7 @@ BannedContactModel::add(ContactMethod* cm) void BannedContactModel::remove(ContactMethod* cm) { + // Do not remove contact if contact isn't banned auto rowIndex = d_ptr->m_lBanned.indexOf(cm); if (rowIndex < 0) return; @@ -166,3 +168,13 @@ BannedContactModel::remove(ContactMethod* cm) ConfigurationManager::instance().addContact(cm->account()->id(), cm->uri()); } + +/** + * this function returns whether passed ContactMethod is in the banned list or not. + * @param cm, the ContactMethod whose presence in the banned list should be checked. + */ +bool +BannedContactModel::isBanned(ContactMethod* cm) +{ + return d_ptr->m_lBanned.contains(cm); +} diff --git a/src/bannedcontactmodel.h b/src/bannedcontactmodel.h index 84ec3736..98143df0 100644 --- a/src/bannedcontactmodel.h +++ b/src/bannedcontactmodel.h @@ -45,6 +45,7 @@ public: // Helper void add(ContactMethod* cm); void remove(ContactMethod* cm); + bool isBanned(ContactMethod* cm); private: virtual ~BannedContactModel(); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index a5d0486d..9dd339c7 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -37,6 +37,7 @@ #include "contactmethod.h" #include "namedirectory.h" #include "phonedirectorymodel.h" +#include "bannedcontactmodel.h" #include "private/vcardutils.h" #include "authority/daemon.h" @@ -470,6 +471,7 @@ ContactModelPimpl::fillsWithRINGContacts() { contact::Info contactInfo; contactInfo.profileInfo = profileInfo; contactInfo.registeredName = cm->registeredName().toStdString(); + contactInfo.isBanned = account->bannedContactModel()->isBanned(cm); { std::lock_guard<std::mutex> lk(contactsMtx_); @@ -546,6 +548,13 @@ ContactModelPimpl::addToContacts(ContactMethod* cm, const profile::Type& type) auto contactInfo = database::buildContactFromProfileId(db, contactId); contactInfo.registeredName = cm->registeredName().toStdString(); + auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); + if (not account) { + qDebug() << "ContactModel::addToContacts(), nullptr"; + return; + } + + contactInfo.isBanned = account->bannedContactModel()->isBanned(cm); contactInfo.isPresent = cm->isPresent(); contactInfo.profileInfo.type = type; // Because PENDING should not be stored in the database auto iter = contacts.find(contactInfo.profileInfo.uri); diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp index 20e898cd..21fc6429 100644 --- a/src/conversationmodel.cpp +++ b/src/conversationmodel.cpp @@ -503,6 +503,12 @@ ConversationModelPimpl::placeCall(const std::string& uid, bool isAudioOnly) if (url.empty()) return; // Incorrect item + // Don't call banned contact + if (contactInfo.isBanned) { + qDebug() << "ContactModel::placeCall: denied, contact is banned"; + return; + } + sendContactRequest(participant); if (linked.owner.profileInfo.type != profile::Type::SIP) { @@ -510,8 +516,13 @@ ConversationModelPimpl::placeCall(const std::string& uid, bool isAudioOnly) } // If call is with temporary contact, conversation has been removed and must be updated + int contactIndex; + if (isTemporary && (contactIndex = indexOfContact(convId)) < 0) { + qDebug() << "Can't place call: Other participant is not a contact"; + return; + } - auto& newConv = isTemporary ? conversations.at(indexOfContact(convId)) : conversation; + auto& newConv = isTemporary ? conversations.at(contactIndex) : conversation; convId = newConv.uid; newConv.callId = linked.owner.callModel->createCall(url, isAudioOnly); @@ -556,6 +567,12 @@ ConversationModel::sendMessage(const std::string& uid, const std::string& body) auto status = interaction::Status::SENDING; for (const auto& participant: conversation.participants) { auto contactInfo = owner.contactModel->getContact(participant); + + if (contactInfo.isBanned) { + qDebug() << "ContactModel::sendMessage: denied, contact is banned"; + return; + } + pimpl_->sendContactRequest(participant); QStringList callLists = CallManager::instance().getCallList(); // no auto @@ -576,8 +593,13 @@ ConversationModel::sendMessage(const std::string& uid, const std::string& body) // If first interaction with temporary contact, we have to update the conversations info // at this stage + int contactIndex; + if (isTemporary && (contactIndex = pimpl_->indexOfContact(convId)) < 0) { + qDebug() << "Can't send message: Other participant is not a contact"; + return; + } - auto& newConv = isTemporary ? pimpl_->conversations.at(pimpl_->indexOfContact(convId)) : conversation; + auto& newConv = isTemporary ? pimpl_->conversations.at(contactIndex) : conversation; convId = newConv.uid; // Add interaction to database -- GitLab