File indexing completed on 2024-11-24 03:41:07

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2021 Slava Aseev <nullptrnine@basealt.ru>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 #include "kwalletfreedesktopsession.h"
0008 
0009 #include "kwalletfreedesktopsessionadaptor.h"
0010 #include <QDBusConnection>
0011 
0012 KWalletFreedesktopSession::KWalletFreedesktopSession(KWalletFreedesktopService *service,
0013                                                      std::unique_ptr<KWalletFreedesktopSessionAlgorithm> algorithm,
0014                                                      QString sessionPath,
0015                                                      const QDBusConnection &connection,
0016                                                      const QDBusMessage &message)
0017     : m_service(service)
0018     , m_algorithm(std::move(algorithm))
0019     , m_sessionPath(std::move(sessionPath))
0020     , m_serviceBusName(message.service())
0021 {
0022     (void)new KWalletFreedesktopSessionAdaptor(this);
0023     QDBusConnection::sessionBus().registerObject(m_sessionPath, this);
0024 
0025     m_serviceWatcher.setConnection(connection);
0026     m_serviceWatcher.addWatchedService(m_serviceBusName);
0027     m_serviceWatcher.setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
0028     connect(&m_serviceWatcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &KWalletFreedesktopSession::slotServiceOwnerChanged);
0029 }
0030 
0031 void KWalletFreedesktopSession::slotServiceOwnerChanged(const QString &, const QString &, const QString &)
0032 {
0033     fdoService()->deleteSession(m_sessionPath);
0034 }
0035 
0036 void KWalletFreedesktopSession::Close()
0037 {
0038     if (message().service() != m_serviceBusName) {
0039         sendErrorReply(QDBusError::ErrorType::UnknownObject, QStringLiteral("Can't find session ") + m_sessionPath);
0040     } else {
0041         fdoService()->deleteSession(m_sessionPath);
0042     }
0043 }
0044 
0045 QByteArray KWalletFreedesktopSession::negotiationOutput() const
0046 {
0047     return m_algorithm->negotiationOutput();
0048 }
0049 
0050 bool KWalletFreedesktopSession::encrypt(const QDBusMessage &message, FreedesktopSecret &secret) const
0051 {
0052     if (message.service() != m_serviceBusName) {
0053         return false;
0054     }
0055 
0056     return m_algorithm->encrypt(secret);
0057 }
0058 
0059 bool KWalletFreedesktopSession::decrypt(const QDBusMessage &message, FreedesktopSecret &secret) const
0060 {
0061     if (message.service() != m_serviceBusName) {
0062         return false;
0063     }
0064 
0065     return m_algorithm->decrypt(secret);
0066 }
0067 
0068 KWalletFreedesktopService *KWalletFreedesktopSession::fdoService() const
0069 {
0070     return m_service;
0071 }
0072 
0073 KWalletD *KWalletFreedesktopSession::backend() const
0074 {
0075     return fdoService()->backend();
0076 }
0077 
0078 QDBusObjectPath KWalletFreedesktopSession::fdoObjectPath() const
0079 {
0080     return QDBusObjectPath(m_sessionPath);
0081 }
0082 
0083 QByteArray KWalletFreedesktopSessionAlgorithmPlain::negotiationOutput() const
0084 {
0085     return QByteArray();
0086 }
0087 
0088 bool KWalletFreedesktopSessionAlgorithmPlain::encrypt(FreedesktopSecret &secret) const
0089 {
0090     secret.parameters = QByteArray();
0091     return true;
0092 }
0093 
0094 bool KWalletFreedesktopSessionAlgorithmPlain::decrypt(FreedesktopSecret &) const
0095 {
0096     return true;
0097 }
0098 
0099 KWalletFreedesktopSessionAlgorithmDhAes::KWalletFreedesktopSessionAlgorithmDhAes(const QCA::PublicKey &publicKey, QCA::SymmetricKey symmetricKey)
0100     : m_publicKey(publicKey)
0101     , m_symmetricKey(std::move(symmetricKey))
0102 {
0103 }
0104 
0105 QByteArray KWalletFreedesktopSessionAlgorithmDhAes::negotiationOutput() const
0106 {
0107     return m_publicKey.toDH().y().toArray().toByteArray();
0108 }
0109 
0110 bool KWalletFreedesktopSessionAlgorithmDhAes::encrypt(FreedesktopSecret &secret) const
0111 {
0112     auto initVector = QCA::InitializationVector(FDO_SECRETS_CIPHER_KEY_SIZE);
0113     auto cipher = QCA::Cipher(QStringLiteral("aes128"), QCA::Cipher::CBC, QCA::Cipher::PKCS7, QCA::Encode, m_symmetricKey, initVector);
0114     QCA::SecureArray result;
0115     result.append(cipher.update(QCA::MemoryRegion(secret.value)));
0116     if (cipher.ok()) {
0117         result.append(cipher.final());
0118         if (cipher.ok()) {
0119             secret.value = std::move(result);
0120             secret.parameters = initVector;
0121             return true;
0122         }
0123     }
0124     return false;
0125 }
0126 
0127 bool KWalletFreedesktopSessionAlgorithmDhAes::decrypt(FreedesktopSecret &secret) const
0128 {
0129     auto cipher =
0130         QCA::Cipher(QStringLiteral("aes128"), QCA::Cipher::CBC, QCA::Cipher::PKCS7, QCA::Decode, m_symmetricKey, QCA::InitializationVector(secret.parameters));
0131     QCA::SecureArray result;
0132     result.append(cipher.update(QCA::MemoryRegion(secret.value)));
0133     if (cipher.ok()) {
0134         result.append(cipher.final());
0135         if (cipher.ok()) {
0136             secret.value = std::move(result);
0137             return true;
0138         }
0139     }
0140     return false;
0141 }
0142 
0143 #include "moc_kwalletfreedesktopsession.cpp"