File indexing completed on 2024-05-05 17:43:14

0001 /*
0002  *   SPDX-FileCopyrightText: 2017 Ivan Cukic <ivan.cukic (at) kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "vaultcreationwizard.h"
0008 #include "ui_vaultcreationwizard.h"
0009 
0010 #include <QMap>
0011 #include <QPushButton>
0012 #include <QStackedLayout>
0013 #include <QVector>
0014 
0015 #include "dialogdsl.h"
0016 #include "vault.h"
0017 
0018 using namespace DialogDsl;
0019 using namespace DialogDsl::operators;
0020 
0021 #include "activitieslinkingwidget.h"
0022 #include "backendchooserwidget.h"
0023 #include "cryfscypherchooserwidget.h"
0024 #include "directorypairchooserwidget.h"
0025 #include "noticewidget.h"
0026 #include "offlineonlywidget.h"
0027 #include "passwordchooserwidget.h"
0028 
0029 #include "vaultwizardbase.h"
0030 
0031 class VaultCreationWizard::Private : public WBASE(VaultCreationWizard)
0032 {
0033 public:
0034     Logic logic{{"encfs" / i18n("EncFS"),
0035                  {step{notice("encfs-message", i18n("<b>Security notice:</b>\n\
0036                              According to a security audit by Taylor Hornby (Defuse Security),\n\
0037                              the current implementation of Encfs is vulnerable or potentially vulnerable\n\
0038                              to multiple types of attacks.\n\
0039                              For example, an attacker with read/write access\n\
0040                              to encrypted data might lower the decryption complexity\n\
0041                              for subsequently encrypted data without this being noticed by a legitimate user,\n\
0042                              or might use timing analysis to deduce information.\n\
0043                              <br /><br />\n\
0044                              This means that you should not synchronize\n\
0045                              the encrypted data to a cloud storage service,\n\
0046                              or use it in other circumstances where the attacker\n\
0047                              can frequently access the encrypted data.\n\
0048                              <br /><br />\n\
0049                              See <a href='https://defuse.ca/audits/encfs.htm'>defuse.ca/audits/encfs.htm</a> for more information."))},
0050                   step{passwordChooser()},
0051                   step{directoryPairChooser(DirectoryPairChooserWidget::AutoFillPaths | DirectoryPairChooserWidget::ShowMountPointPicker
0052                                             | DirectoryPairChooserWidget::RequireEmptyMountPoint)},
0053                   step{activitiesChooser(), offlineOnlyChooser()}}},
0054 
0055                 {"cryfs" / i18n("CryFS"),
0056                  {step{notice("cryfs-message", i18n("<b>Security notice:</b>\n\
0057                              CryFS encrypts your files, so you can safely store them anywhere.\n\
0058                              It works well together with cloud services like Dropbox, iCloud, OneDrive and others.\n\
0059                              <br /><br />\n\
0060                              Unlike some other file-system overlay solutions,\n\
0061                              it does not expose the directory structure,\n\
0062                              the number of files nor the file sizes\n\
0063                              through the encrypted data format.\n\
0064                              <br /><br />\n\
0065                              One important thing to note is that,\n\
0066                              while CryFS is considered safe,\n\
0067                              there is no independent security audit\n\
0068                              which confirms this."))},
0069                   step{passwordChooser()},
0070                   step{directoryPairChooser(DirectoryPairChooserWidget::AutoFillPaths | DirectoryPairChooserWidget::ShowDevicePicker
0071                                             | DirectoryPairChooserWidget::ShowMountPointPicker | DirectoryPairChooserWidget::RequireEmptyDevice
0072                                             | DirectoryPairChooserWidget::RequireEmptyMountPoint)},
0073                   step{cryfsCypherChooser(), activitiesChooser(), offlineOnlyChooser()}}},
0074 
0075                 {"gocryptfs" / i18n("gocryptfs"),
0076                  {step{notice("gocryptfs-message", i18n("<b>Security notice:</b>\n\
0077                              Gocryptfs encrypts your files, so you can safely store them anywhere.\n\
0078                              It works well together with cloud services like Dropbox, iCloud, OneDrive and others.\n\
0079                              <br /><br />\n\
0080                              A threat model for gocryptfs is provided by the author at \
0081                              <a href='https://nuetzlich.net/gocryptfs/threat_model'>nuetzlich.net/gocryptfs/threat_model</a>. \
0082                              <br /><br />\n\
0083                              According to a security audit performed in 2017 by Taylor Hornby (Defuse Security),\n\
0084                              gocryptfs keeps file contents secret against an adversary that can read and modify the \
0085                              ciphertext. \
0086                              <br /><br />\n\
0087                              See <a href='https://defuse.ca/audits/gocryptfs.htm'>defuse.ca/audits/gocryptfs.htm</a> for more information."))},
0088                   step{passwordChooser()},
0089                   step{directoryPairChooser(DirectoryPairChooserWidget::AutoFillPaths | DirectoryPairChooserWidget::ShowDevicePicker
0090                                             | DirectoryPairChooserWidget::ShowMountPointPicker | DirectoryPairChooserWidget::RequireEmptyDevice
0091                                             | DirectoryPairChooserWidget::RequireEmptyMountPoint)},
0092                   step{activitiesChooser(), offlineOnlyChooser()}}}};
0093 
0094     Private(VaultCreationWizard *parent)
0095         : WBASE(VaultCreationWizard)(parent)
0096     {
0097         initBase();
0098     }
0099 
0100     void finish()
0101     {
0102         q->setEnabled(false);
0103 
0104         auto collectedPayload = firstStepModule->fields();
0105         for (const auto *module : currentStepModules) {
0106             collectedPayload.insert(module->fields());
0107         }
0108 
0109         const auto name = collectedPayload[KEY_NAME].toString();
0110         const PlasmaVault::Device device(collectedPayload[KEY_DEVICE].toString());
0111         const PlasmaVault::MountPoint mountPoint(collectedPayload[KEY_MOUNT_POINT].toString());
0112 
0113         auto vault = new PlasmaVault::Vault(device, q);
0114 
0115         auto future = vault->create(name, mountPoint, collectedPayload);
0116 
0117         auto result = AsynQt::await(future);
0118 
0119         if (result) {
0120             Q_EMIT q->createdVault(vault);
0121             q->QDialog::accept();
0122 
0123         } else {
0124             ui.message->setText(result.error().message());
0125             ui.message->setMessageType(KMessageWidget::Error);
0126             ui.message->show();
0127             vault->scheduleDeletion();
0128         }
0129 
0130         q->setEnabled(true);
0131     }
0132 };
0133 
0134 VaultCreationWizard::VaultCreationWizard(QWidget *parent)
0135     : QDialog(parent)
0136     , d(new Private(this))
0137 {
0138     setWindowTitle(i18nc("@title:window", "Create a New Vault"));
0139 }
0140 
0141 VaultCreationWizard::~VaultCreationWizard()
0142 {
0143 }