bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) const { Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; qint64 payloadLength = newLength - payloadOffset(); if ( newLength - length() * m_logicalSectorSize > 0 ) { ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() }); report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode); if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) return m_innerFs->resize(report, mapperName(), payloadLength); } else if (m_innerFs->resize(report, mapperName(), payloadLength)) { ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("--size"), QString::number(payloadLength / m_logicalSectorSize), // LUKS assumes 512 bytes sector QStringLiteral("resize"), mapperName() }); report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode); if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) return true; } report.line() << xi18nc("@info:progress", "Resizing encrypted file system on partition <filename>%1</filename> failed.", deviceNode); return false; }
bool luks::cryptOpen(QWidget* parent, const QString& deviceNode) { if (m_isCryptOpen) { if (!mapperName().isEmpty()) { qWarning() << "LUKS device" << deviceNode << "already decrypted." << "Cannot decrypt again."; return false; } else { qWarning() << "LUKS device" << deviceNode << "reportedly decrypted but mapper node not found." << "Marking device as NOT decrypted and trying to " "decrypt again anyway."; m_isCryptOpen = false; } } KPasswordDialog dlg( parent ); dlg.setPrompt(i18n("Enter passphrase for %1:", deviceNode)); if( !dlg.exec() ) return false; QString passphrase = dlg.password(); ExternalCommand openCmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), deviceNode, suggestedMapperName(deviceNode) }); if (!( openCmd.start(-1) && openCmd.write(passphrase.toUtf8() + '\n') == passphrase.toUtf8().length() + 1 && openCmd.waitFor() && openCmd.exitCode() == 0) ) return false; if (m_innerFs) { delete m_innerFs; m_innerFs = nullptr; } scan(deviceNode); if (mapperName().isEmpty()) return false; loadInnerFileSystem(mapperName()); m_isCryptOpen = (m_innerFs != nullptr); if (!m_isCryptOpen) return false; for (auto &p : LVM::pvList) // FIXME: qAsConst if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Lvm2_PV) p.setLuks(false); m_passphrase = passphrase; return true; }
bool luks::check(Report& report, const QString&) const { Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; return m_innerFs->check(report, mapperName()); }
bool luks::canUnmount(const QString&) const { return m_isCryptOpen && m_isMounted && m_innerFs && m_innerFs->canUnmount(mapperName()); }
bool luks::canMount(const QString&, const QString& mountPoint) const { return m_isCryptOpen && !m_isMounted && m_innerFs && m_innerFs->canMount(mapperName(), mountPoint); }
bool luks::mount(Report& report, const QString& deviceNode, const QString& mountPoint) { if (!m_isCryptOpen) { qWarning() << "Cannot mount device" << deviceNode << "before decrypting it first."; return false; } if (m_isMounted) { qWarning() << "Cannot mount device" << deviceNode << "because it's already mounted."; return false; } Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; if (m_innerFs->canMount(mapperName(), mountPoint)) { if (m_innerFs->mount(report, mapperName(), mountPoint)) { m_isMounted = true; const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint); if (freeSpaceInfo.isValid() && mountPoint != QString()) setSectorsUsed((freeSpaceInfo.used() + payloadOffset()) / m_logicalSectorSize); return true; } } else { ExternalCommand mountCmd( report, QStringLiteral("mount"), { QStringLiteral("--verbose"), mapperName(), mountPoint }); if (mountCmd.run() && mountCmd.exitCode() == 0) { m_isMounted = true; return true; } } return false; }
bool luks::unmount(Report& report, const QString& deviceNode) { if (!m_isCryptOpen) { qWarning() << "Cannot unmount device" << deviceNode << "before decrypting it first."; return false; } if (!m_isMounted) { qWarning() << "Cannot unmount device" << deviceNode << "because it's not mounted."; return false; } Q_ASSERT(m_innerFs); if (mapperName().isEmpty()) return false; if (m_innerFs->canUnmount(mapperName())) { if (m_innerFs->unmount(report, mapperName())) { m_isMounted = false; return true; } } else { ExternalCommand unmountCmd( report, QStringLiteral("umount"), { QStringLiteral("--verbose"), QStringLiteral("--all-targets"), mapperName() }); if (unmountCmd.run() && unmountCmd.exitCode() == 0) { m_isMounted = false; return true; } } return false; }
bool luks::create(Report& report, const QString& deviceNode) { Q_ASSERT(m_innerFs); Q_ASSERT(!m_passphrase.isEmpty()); ExternalCommand createCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("-s"), QStringLiteral("512"), QStringLiteral("--batch-mode"), QStringLiteral("--force-password"), QStringLiteral("luksFormat"), deviceNode }); if (!( createCmd.start(-1) && createCmd.write(m_passphrase.toUtf8() + '\n') == m_passphrase.toUtf8().length() + 1 && createCmd.waitFor() && createCmd.exitCode() == 0)) { return false; } ExternalCommand openCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("open"), deviceNode, suggestedMapperName(deviceNode) }); if (!( openCmd.start(-1) && openCmd.write(m_passphrase.toUtf8() + '\n') == m_passphrase.toUtf8().length() + 1 && openCmd.waitFor())) return false; scan(deviceNode); if (mapperName().isEmpty()) return false; if (!m_innerFs->create(report, mapperName())) return false; return true; }
bool luks::cryptClose(const QString& deviceNode) { if (!m_isCryptOpen) { qWarning() << "Cannot close LUKS device" << deviceNode << "because it's not open."; return false; } if (m_isMounted) { qWarning() << "Cannot close LUKS device" << deviceNode << "because the filesystem is mounted."; return false; } ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("close"), mapperName() }); if (!(cmd.run(-1) && cmd.exitCode() == 0)) return false; delete m_innerFs; m_innerFs = nullptr; m_passphrase.clear(); setLabel({}); setUUID(readUUID(deviceNode)); setSectorsUsed(-1); m_isCryptOpen = (m_innerFs != nullptr); for (auto &p : LVM::pvList) // FIXME: qAsConst if (!p.isLuks() && p.partition()->deviceNode() == deviceNode) p.setLuks(true); return true; }
bool luks::writeLabel(Report& report, const QString&, const QString& newLabel) { Q_ASSERT(m_innerFs); return m_innerFs->writeLabel(report, mapperName(), newLabel); }
QString luks::readLabel(const QString&) const { if (m_isCryptOpen && m_innerFs) return m_innerFs->readLabel(mapperName()); return QString(); }
bool luks::unmount(const QString& deviceNode) { ExternalCommand cmd(QStringLiteral("cryptsetup"), QStringList() << QStringLiteral("luksClose") << mapperName(deviceNode)); return cmd.run(-1) && cmd.exitCode() == 0; }