File indexing completed on 2023-12-03 08:28:36
0001 /* 0002 Copyright (C) 2014 Marcin ZiemiĆski <zieminn@gmail.com> 0003 0004 This program is free software: you can redistribute it and/or modify 0005 it under the terms of the GNU General Public License as published by 0006 the Free Software Foundation, either version 2 of the License, or 0007 (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 GNU General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <http://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "channel-adapter.h" 0019 0020 #include "channel-proxy-interface.h" 0021 #include "utils.h" 0022 #include "constants.h" 0023 0024 #include <debug.h> 0025 0026 #include <TelepathyQt/SharedPtr> 0027 #include <TelepathyQt/ReceivedMessage> 0028 #include <QMap> 0029 #include <QGenericArgument> 0030 0031 typedef QSharedPointer<KTp::Client::ChannelProxyInterfaceOTRInterface> OTRProxyPtr; 0032 0033 static int getId(const Tp::ReceivedMessage &recvMes) 0034 { 0035 return recvMes.header()[QLatin1String("pending-message-id")].variant().toUInt(nullptr); 0036 } 0037 0038 class OTRMessage : public Tp::ReceivedMessage 0039 { 0040 public: 0041 OTRMessage(const Tp::ReceivedMessage &recMes) 0042 : Tp::ReceivedMessage(recMes) 0043 { 0044 } 0045 0046 OTRMessage(const Tp::MessagePartList &message, const Tp::TextChannelPtr channel) 0047 : Tp::ReceivedMessage(message, channel) 0048 { 0049 setSender(channel->targetContact()); 0050 } 0051 0052 bool hasId() const 0053 { 0054 return header().contains(QLatin1String("pending-message-id")); 0055 } 0056 0057 int getId() const 0058 { 0059 return ::getId(*this); 0060 } 0061 0062 void setId(int id) 0063 { 0064 header()[QLatin1String("pending-message-id")] = QDBusVariant(id); 0065 } 0066 0067 void setSender(const Tp::ContactPtr &contact) 0068 { 0069 ReceivedMessage::setSender(contact); 0070 } 0071 }; 0072 0073 namespace KTp { 0074 0075 struct ChannelAdapter::Private 0076 { 0077 Private() 0078 : otrConnected(false), 0079 trustLevel(KTp::OTRTrustLevelNotPrivate) 0080 { 0081 } 0082 0083 Tp::TextChannelPtr textChannel; 0084 OTRProxyPtr otrProxy; 0085 0086 bool otrConnected; 0087 KTp::OTRTrustLevel trustLevel; 0088 QString remoteFp; 0089 0090 QMap<uint, OTRMessage> messages; 0091 QMap<uint, OTRMessage> otrEvents; 0092 }; 0093 0094 ChannelAdapter::ChannelAdapter(const Tp::TextChannelPtr &textChannel, QObject *parent) 0095 : QObject(parent), 0096 d(new Private()) 0097 { 0098 setChannel(textChannel); 0099 } 0100 0101 ChannelAdapter::~ChannelAdapter() 0102 { 0103 delete d; 0104 } 0105 0106 bool ChannelAdapter::isValid() const 0107 { 0108 return d->textChannel->isValid(); 0109 } 0110 0111 void ChannelAdapter::setChannel(const Tp::TextChannelPtr &textChannel) 0112 { 0113 d->textChannel = textChannel; 0114 QDBusConnection dbusConnection = textChannel->dbusConnection(); 0115 if(textChannel->targetHandleType() != Tp::HandleTypeContact || 0116 !dbusConnection.interface()->isServiceRegistered(KTP_PROXY_BUS_NAME)) 0117 { 0118 setupTextChannel(); 0119 return; 0120 } 0121 0122 QString otrProxyPath = KTp::Utils::getOtrProxyObjectPathFor(textChannel); 0123 d->otrProxy = OTRProxyPtr(new KTp::Client::ChannelProxyInterfaceOTRInterface(KTP_PROXY_BUS_NAME, otrProxyPath, this)); 0124 0125 if(!d->otrProxy->isValid()) { 0126 qCDebug(KTP_OTR) << "No OTR proxy available for channel: " << textChannel->objectPath(); 0127 setupTextChannel(); 0128 return; 0129 } 0130 0131 qCDebug(KTP_OTR) << "Connecting to the OTR proxy: " << d->otrProxy->path(); 0132 QDBusPendingReply<> connectResult = d->otrProxy->ConnectProxy(); 0133 connectResult.waitForFinished(); 0134 if(connectResult.isValid()) { 0135 setupOTRChannel(); 0136 } else { 0137 qCWarning(KTP_OTR) << "Could not connect to the proxy" << connectResult.error().message(); 0138 setupTextChannel(); 0139 } 0140 } 0141 0142 Tp::TextChannelPtr ChannelAdapter::textChannel() 0143 { 0144 return d->textChannel; 0145 } 0146 0147 void ChannelAdapter::setupTextChannel() 0148 { 0149 connect(d->textChannel.data(), SIGNAL(messageReceived(Tp::ReceivedMessage)), 0150 SIGNAL(messageReceived(Tp::ReceivedMessage))); 0151 connect(d->textChannel.data(), SIGNAL(pendingMessageRemoved(Tp::ReceivedMessage)), 0152 SIGNAL(pendingMessageRemoved(Tp::ReceivedMessage))); 0153 connect(d->textChannel.data(), SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString)), 0154 SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString))); 0155 } 0156 0157 void ChannelAdapter::setupOTRChannel() 0158 { 0159 d->otrConnected = true; 0160 d->trustLevel = KTp::OTRTrustLevelNotPrivate; 0161 0162 connect(d->otrProxy.data(), SIGNAL(SessionRefreshed()), SIGNAL(sessionRefreshed())); 0163 connect(d->otrProxy.data(), SIGNAL(MessageReceived(const Tp::MessagePartList&)), 0164 SLOT(onMessageReceived(const Tp::MessagePartList&))); 0165 connect(d->otrProxy.data(), SIGNAL(PendingMessagesRemoved(const Tp::UIntList&)), 0166 SLOT(onPendingMessagesRemoved(const Tp::UIntList&))); 0167 connect(d->otrProxy.data(), SIGNAL(MessageSent(const Tp::MessagePartList&, uint, const QString&)), 0168 SLOT(onMessageSent(const Tp::MessagePartList&, uint, const QString&))); 0169 connect(d->otrProxy.data(), SIGNAL(TrustLevelChanged(uint)), SLOT(onTrustLevelChanged(uint))); 0170 0171 // smp protocol 0172 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationRequested(const QString&)), 0173 SLOT(onPeerAuthenticationRequested(const QString&))); 0174 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationConcluded(bool)), 0175 SIGNAL(peerAuthenticationConcluded(bool))); 0176 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationInProgress()), 0177 SIGNAL(peerAuthenticationInProgress())); 0178 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationAborted()), 0179 SIGNAL(peerAuthenticationAborted())); 0180 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationError()), 0181 SIGNAL(peerAuthenticationError())); 0182 connect(d->otrProxy.data(), SIGNAL(PeerAuthenticationCheated()), 0183 SIGNAL(peerAuthenticationCheated())); 0184 0185 // initialize message queue; 0186 connect(d->otrProxy->requestPropertyPendingMessages(), SIGNAL(finished(Tp::PendingOperation*)), 0187 SLOT(onPendingMessagesPropertyGet(Tp::PendingOperation*))); 0188 // initialize trust level property 0189 connect(d->otrProxy->requestPropertyTrustLevel(), SIGNAL(finished(Tp::PendingOperation*)), 0190 SLOT(onTrustLevelPropertyGet(Tp::PendingOperation*))); 0191 // initialize remote fingerprint property 0192 connect(d->otrProxy->requestPropertyRemoteFingerprint(), SIGNAL(finished(Tp::PendingOperation*)), 0193 SLOT(onRemoteFingerprintPropertyGet(Tp::PendingOperation*))); 0194 } 0195 0196 KTp::OTRTrustLevel ChannelAdapter::otrTrustLevel() const 0197 { 0198 return d->trustLevel; 0199 } 0200 0201 void ChannelAdapter::onTrustLevelPropertyGet(Tp::PendingOperation *op) 0202 { 0203 if(op->isError()) { 0204 qCWarning(KTP_OTR) << "Could not get property: TrustLevel"; 0205 return; 0206 } 0207 // we must have received trust level changed signal before 0208 if(d->trustLevel != KTp::OTRTrustLevelNotPrivate) { 0209 return; 0210 } 0211 Tp::PendingVariant *pv = dynamic_cast<Tp::PendingVariant*>(op); 0212 d->trustLevel = static_cast<KTp::OTRTrustLevel>(pv->result().toUInt(nullptr)); 0213 Q_EMIT otrTrustLevelChanged(d->trustLevel, KTp::OTRTrustLevelNotPrivate); 0214 } 0215 0216 bool ChannelAdapter::isOTRsuppored() const 0217 { 0218 return d->otrConnected; 0219 } 0220 0221 void ChannelAdapter::initializeOTR() 0222 { 0223 qCDebug(KTP_OTR) << "Initializing OTR session"; 0224 d->otrProxy->Initialize(); 0225 } 0226 0227 void ChannelAdapter::stopOTR() 0228 { 0229 d->otrProxy->Stop(); 0230 } 0231 0232 QString ChannelAdapter::remoteFingerprint() const 0233 { 0234 return d->remoteFp; 0235 } 0236 0237 QDBusPendingReply<> ChannelAdapter::trustFingerprint(const QString &fingerprint, bool trust) 0238 { 0239 return d->otrProxy->TrustFingerprint(fingerprint, trust); 0240 } 0241 0242 void ChannelAdapter::acknowledge(const QList<Tp::ReceivedMessage> &messages) 0243 { 0244 if(messages.isEmpty()) { 0245 return; 0246 } 0247 0248 if(isOTRsuppored()) { 0249 QList<Tp::ReceivedMessage> toAck; 0250 QList<Tp::ReceivedMessage> eventsToRemove; 0251 0252 Q_FOREACH(const Tp::ReceivedMessage &mes, messages) { 0253 if(KTp::Utils::isOtrEvent(mes)) { 0254 d->otrEvents.remove(getId(mes)); 0255 eventsToRemove << mes; 0256 } else { 0257 toAck << mes; 0258 } 0259 } 0260 d->otrProxy->AcknowledgePendingMessages(KTp::Utils::getPendingMessagesIDs(toAck)); 0261 Q_FOREACH(const Tp::ReceivedMessage &mes, eventsToRemove) { 0262 Q_EMIT pendingMessageRemoved(mes); 0263 } 0264 } else { 0265 d->textChannel->acknowledge(messages); 0266 } 0267 } 0268 0269 void ChannelAdapter::send(const QString& text, Tp::ChannelTextMessageType type, Tp::MessageSendingFlags flags) 0270 { 0271 if(isOTRsuppored()) { 0272 Tp::MessagePartList parts; 0273 parts << Tp::MessagePart() << Tp::MessagePart(); 0274 parts[0].insert(QLatin1String("message-type"), 0275 QDBusVariant(type)); 0276 parts[1].insert(QLatin1String("content-type"), 0277 QDBusVariant(QLatin1String("text/plain"))); 0278 parts[1].insert(QLatin1String("content"), QDBusVariant(text)); 0279 0280 d->otrProxy->SendMessage(parts, (uint) flags); 0281 } else { 0282 d->textChannel->send(text, type, flags); 0283 } 0284 } 0285 0286 bool ChannelAdapter::supportsMessageType(Tp::ChannelTextMessageType messageType) const 0287 { 0288 return d->textChannel->supportsMessageType(messageType); 0289 } 0290 0291 QList<Tp::ChannelTextMessageType> ChannelAdapter::supportedMessageTypes() const 0292 { 0293 return d->textChannel->supportedMessageTypes(); 0294 } 0295 0296 QStringList ChannelAdapter::supportedContentTypes() const 0297 { 0298 return d->textChannel->supportedContentTypes(); 0299 } 0300 0301 Tp::MessagePartSupportFlags ChannelAdapter::messagePartSupport() const 0302 { 0303 return d->textChannel->messagePartSupport(); 0304 } 0305 0306 Tp::DeliveryReportingSupportFlags ChannelAdapter::deliveryReportingSupport() const 0307 { 0308 return d->textChannel->deliveryReportingSupport(); 0309 } 0310 0311 QList<Tp::ReceivedMessage> ChannelAdapter::messageQueue() const 0312 { 0313 if(isOTRsuppored()) { 0314 QList<Tp::ReceivedMessage> messages; 0315 Q_FOREACH(const Tp::ReceivedMessage &m, d->messages) { 0316 messages << m; 0317 } 0318 Q_FOREACH(const Tp::ReceivedMessage &m, d->otrEvents) { 0319 messages << m; 0320 } 0321 return messages; 0322 } else { 0323 return d->textChannel->messageQueue(); 0324 } 0325 } 0326 0327 void ChannelAdapter::onMessageReceived(const Tp::MessagePartList &message) 0328 { 0329 OTRMessage recvMes(message, d->textChannel); 0330 if(recvMes.hasId()) { 0331 const int id = recvMes.getId(); 0332 if(!d->messages.contains(id)) { 0333 d->messages.insert(id, recvMes); 0334 Q_EMIT messageReceived(recvMes); 0335 } else { 0336 qCWarning(KTP_OTR) << "Message already in the queue. Id: " << id; 0337 } 0338 } else if (KTp::Utils::isOtrEvent(recvMes)) { 0339 const int id = d->otrEvents.size(); 0340 recvMes.setId(d->otrEvents.size()); 0341 d->otrEvents.insert(id, recvMes); 0342 Q_EMIT messageReceived(recvMes); 0343 } else { 0344 qCWarning(KTP_OTR) << "Message has not id and is not an OTR event either"; 0345 } 0346 } 0347 0348 void ChannelAdapter::onPendingMessagesPropertyGet(Tp::PendingOperation *op) 0349 { 0350 Tp::PendingVariant *variant = dynamic_cast<Tp::PendingVariant*>(op); 0351 0352 if(!variant->isError()) { 0353 QDBusArgument dbusArgument = variant->result().value<QDBusArgument>(); 0354 Tp::MessagePartListList pendingMessages; 0355 dbusArgument >> pendingMessages; 0356 Q_FOREACH(const Tp::MessagePartList &message, pendingMessages) { 0357 onMessageReceived(message); 0358 } 0359 } else { 0360 qCWarning(KTP_OTR) << "Could not initialize message queue: " << variant->errorName() << " - " 0361 << variant->errorMessage(); 0362 } 0363 } 0364 0365 void ChannelAdapter::onRemoteFingerprintPropertyGet(Tp::PendingOperation *op) 0366 { 0367 Tp::PendingVariant *variant = dynamic_cast<Tp::PendingVariant*>(op); 0368 0369 if(!variant->isError()) { 0370 d->remoteFp = variant->result().toString(); 0371 } else { 0372 qCWarning(KTP_OTR) << "Could not get remote fingerprint: " << variant->errorName() << " - " 0373 << variant->errorMessage(); 0374 } 0375 } 0376 0377 void ChannelAdapter::onPendingMessagesRemoved(const Tp::UIntList &messageIDs) 0378 { 0379 Q_FOREACH(uint id, messageIDs) { 0380 const QMap<uint, OTRMessage>::Iterator mIt = d->messages.find(id); 0381 if(mIt != d->messages.end()) { 0382 OTRMessage message = *mIt; 0383 d->messages.erase(mIt); 0384 Q_EMIT pendingMessageRemoved(message); 0385 } else { 0386 qCWarning(KTP_OTR) << "No message to remove with id: " << id; 0387 } 0388 } 0389 } 0390 0391 void ChannelAdapter::onMessageSent(const Tp::MessagePartList &content, uint flags, const QString &messageToken) 0392 { 0393 OTRMessage message(content, d->textChannel); 0394 Q_EMIT messageSent(message, Tp::MessageSendingFlags(flags), messageToken); 0395 } 0396 0397 void ChannelAdapter::onTrustLevelChanged(uint trustLevel) 0398 { 0399 KTp::OTRTrustLevel oldLevel = d->trustLevel; 0400 d->trustLevel = static_cast<KTp::OTRTrustLevel>(trustLevel); 0401 // get remote's fingerprint 0402 if(oldLevel == KTp::OTRTrustLevelNotPrivate) { 0403 connect(d->otrProxy->requestPropertyRemoteFingerprint(), SIGNAL(finished(Tp::PendingOperation*)), 0404 SLOT(onRemoteFingerprintPropertyGet(Tp::PendingOperation*))); 0405 } 0406 0407 // it may be a new session and the fingerprint has to be updated 0408 if(d->trustLevel == KTp::OTRTrustLevelPrivate || d->trustLevel == KTp::OTRTrustLevelUnverified) { 0409 connect(d->otrProxy->requestPropertyRemoteFingerprint(), SIGNAL(finished(Tp::PendingOperation*)), 0410 SLOT(onRemoteFingerprintPropertyGet(Tp::PendingOperation*))); 0411 } 0412 0413 Q_EMIT otrTrustLevelChanged(d->trustLevel, oldLevel); 0414 } 0415 0416 void ChannelAdapter::onPeerAuthenticationRequested(const QString &question) 0417 { 0418 if(question.isEmpty()) { 0419 Q_EMIT peerAuthenticationRequestedSS(); 0420 } else { 0421 Q_EMIT peerAuthenticationRequestedQA(question); 0422 } 0423 } 0424 0425 void ChannelAdapter::startPeerAuthenticationQA(const QString &question, const QString &answer) 0426 { 0427 d->otrProxy->StartPeerAuthentication(question, answer); 0428 } 0429 0430 void ChannelAdapter::startPeerAuthenticationSS(const QString &secret) 0431 { 0432 startPeerAuthenticationQA(QLatin1String(""), secret); 0433 } 0434 0435 void ChannelAdapter::respondPeerAuthentication(const QString &secret) 0436 { 0437 d->otrProxy->RespondPeerAuthentication(secret); 0438 } 0439 0440 void ChannelAdapter::abortPeerAuthentication() 0441 { 0442 d->otrProxy->AbortPeerAuthentication(); 0443 } 0444 0445 } /* namespace KTp */