File indexing completed on 2024-06-23 05:30:39
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 "encfsbackend.h" 0008 0009 #include <QDir> 0010 #include <QProcess> 0011 #include <QRegularExpression> 0012 0013 #include <KConfigGroup> 0014 #include <KLocalizedString> 0015 #include <KMountPoint> 0016 #include <KSharedConfig> 0017 0018 #include <algorithm> 0019 0020 #include <asynqt/basic/all.h> 0021 #include <asynqt/operations/collect.h> 0022 #include <asynqt/operations/transform.h> 0023 #include <asynqt/wrappers/process.h> 0024 0025 #include <singleton_p.h> 0026 0027 using namespace AsynQt; 0028 0029 namespace PlasmaVault 0030 { 0031 EncFsBackend::EncFsBackend() 0032 { 0033 } 0034 0035 EncFsBackend::~EncFsBackend() 0036 { 0037 } 0038 0039 Backend::Ptr EncFsBackend::instance() 0040 { 0041 return singleton::instance<EncFsBackend>(); 0042 } 0043 0044 FutureResult<> EncFsBackend::mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) 0045 { 0046 QDir dir; 0047 0048 const auto password = payload[KEY_PASSWORD].toString(); 0049 0050 if (!dir.mkpath(device.data()) || !dir.mkpath(mountPoint.data())) { 0051 return errorResult(Error::BackendError, i18n("Failed to create directories, check your permissions")); 0052 } 0053 removeDotDirectory(mountPoint); 0054 0055 auto process = encfs({ 0056 "-S", // read password from stdin 0057 "--standard", // If creating a file system, use the default options 0058 device.data(), // source directory to initialize encfs in 0059 mountPoint.data() // where to mount the file system 0060 }); 0061 0062 auto result = makeFuture(process, hasProcessFinishedSuccessfully); 0063 0064 // Writing the password 0065 process->write(password.toUtf8()); 0066 process->write("\n"); 0067 0068 return result; 0069 } 0070 0071 FutureResult<> EncFsBackend::validateBackend() 0072 { 0073 using namespace AsynQt::operators; 0074 0075 // We need to check whether all the commands are installed 0076 // and whether the user has permissions to run them 0077 return collect(checkVersion(encfs({"--version"}), std::make_tuple(1, 9, 1)), 0078 checkVersion(encfsctl({"--version"}), std::make_tuple(1, 9, 1)), 0079 checkVersion(fusermount({"--version"}), std::make_tuple(2, 9, 7))) 0080 0081 | transform([this](const QPair<bool, QString> &encfs, const QPair<bool, QString> &encfsctl, const QPair<bool, QString> &fusermount) { 0082 bool success = encfs.first && encfsctl.first && fusermount.first; 0083 QString message = formatMessageLine("encfs", encfs) + formatMessageLine("encfsctl", encfsctl) + formatMessageLine("fusermount", fusermount); 0084 0085 return success ? Result<>::success() : Result<>::error(Error::BackendError, message); 0086 }); 0087 } 0088 0089 bool EncFsBackend::isInitialized(const Device &device) const 0090 { 0091 auto process = encfsctl({device.data()}); 0092 0093 process->start(); 0094 process->waitForFinished(); 0095 0096 return process->exitCode() == 0; 0097 } 0098 0099 QProcess *EncFsBackend::encfs(const QStringList &arguments) const 0100 { 0101 auto config = KSharedConfig::openConfig(PLASMAVAULT_CONFIG_FILE); 0102 KConfigGroup backendConfig(config, "EncfsBackend"); 0103 0104 return process("encfs", arguments + backendConfig.readEntry("extraMountOptions", QStringList{}), {}); 0105 } 0106 0107 QProcess *EncFsBackend::encfsctl(const QStringList &arguments) const 0108 { 0109 return process("encfsctl", arguments, {}); 0110 } 0111 0112 } // namespace PlasmaVault