File indexing completed on 2024-05-05 05:48:46
0001 /* 0002 SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de> 0003 SPDX-FileCopyrightText: 2012-2019 Andrius Štikonas <andrius@stikonas.eu> 0004 SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org> 0005 SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com> 0006 SPDX-FileCopyrightText: 2017 Christian Morlok <christianmorlok@gmail.com> 0007 SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com> 0008 SPDX-FileCopyrightText: 2020 Arnaud Ferraris <arnaud.ferraris@collabora.com> 0009 SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com> 0010 0011 SPDX-License-Identifier: GPL-3.0-or-later 0012 */ 0013 0014 #include "fs/luks.h" 0015 #include "fs/lvm2_pv.h" 0016 0017 #include "fs/filesystemfactory.h" 0018 0019 #include "util/externalcommand.h" 0020 #include "util/capacity.h" 0021 #include "util/helpers.h" 0022 #include "util/report.h" 0023 0024 #include <cmath> 0025 0026 #include <QDebug> 0027 #include <QDialog> 0028 #include <QJsonArray> 0029 #include <QJsonObject> 0030 #include <QJsonDocument> 0031 #include <QRegularExpression> 0032 #include <QPointer> 0033 #include <QStorageInfo> 0034 #include <QString> 0035 #include <QUuid> 0036 #include <QWidget> 0037 0038 #include <KLocalizedString> 0039 #include <KPasswordDialog> 0040 0041 namespace FS 0042 { 0043 FileSystem::CommandSupportType luks::m_GetUsed = FileSystem::cmdSupportNone; 0044 FileSystem::CommandSupportType luks::m_GetLabel = FileSystem::cmdSupportNone; 0045 FileSystem::CommandSupportType luks::m_Create = FileSystem::cmdSupportNone; 0046 FileSystem::CommandSupportType luks::m_Grow = FileSystem::cmdSupportNone; 0047 FileSystem::CommandSupportType luks::m_Shrink = FileSystem::cmdSupportNone; 0048 FileSystem::CommandSupportType luks::m_Move = FileSystem::cmdSupportNone; 0049 FileSystem::CommandSupportType luks::m_Check = FileSystem::cmdSupportNone; 0050 FileSystem::CommandSupportType luks::m_Copy = FileSystem::cmdSupportNone; 0051 FileSystem::CommandSupportType luks::m_Backup = FileSystem::cmdSupportNone; 0052 FileSystem::CommandSupportType luks::m_SetLabel = FileSystem::cmdSupportNone; 0053 FileSystem::CommandSupportType luks::m_UpdateUUID = FileSystem::cmdSupportNone; 0054 FileSystem::CommandSupportType luks::m_GetUUID = FileSystem::cmdSupportNone; 0055 0056 luks::luks(qint64 firstsector, 0057 qint64 lastsector, 0058 qint64 sectorsused, 0059 const QString& label, 0060 const QVariantMap& features, 0061 FileSystem::Type t) 0062 : FileSystem(firstsector, lastsector, sectorsused, label, features, t) 0063 , m_innerFs(nullptr) 0064 , m_isCryptOpen(false) 0065 , m_cryptsetupFound(m_Create != cmdSupportNone) 0066 , m_isMounted(false) 0067 , m_KeySize(-1) 0068 , m_PayloadOffset(-1) 0069 { 0070 } 0071 0072 luks::~luks() 0073 { 0074 delete m_innerFs; 0075 } 0076 0077 void luks::init() 0078 { 0079 CommandSupportType cryptsetupFound = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone; 0080 0081 m_Create = cryptsetupFound; 0082 m_UpdateUUID = cryptsetupFound; 0083 m_GetUUID = cryptsetupFound; 0084 m_Grow = cryptsetupFound; 0085 m_Shrink = cryptsetupFound; 0086 0087 m_SetLabel = cmdSupportNone; 0088 m_GetLabel = cmdSupportFileSystem; 0089 m_Check = cmdSupportCore; 0090 m_Copy = cmdSupportCore; 0091 m_Move = cmdSupportCore; 0092 m_Backup = cmdSupportCore; 0093 m_GetUsed = cmdSupportNone; // libparted does not support LUKS, we do this as a special case 0094 } 0095 0096 void luks::scan(const QString& deviceNode) 0097 { 0098 getMapperName(deviceNode); 0099 getLuksInfo(deviceNode); 0100 } 0101 0102 bool luks::supportToolFound() const 0103 { 0104 return m_cryptsetupFound && ((m_isCryptOpen && m_innerFs) ? m_innerFs->supportToolFound() : true); 0105 } 0106 0107 FileSystem::SupportTool luks::supportToolName() const 0108 { 0109 if (m_isCryptOpen && m_innerFs && m_cryptsetupFound) 0110 return m_innerFs->supportToolName(); 0111 return SupportTool(QStringLiteral("cryptsetup"), 0112 QUrl(QStringLiteral("https://code.google.com/p/cryptsetup/"))); 0113 } 0114 0115 bool luks::create(Report& report, const QString& deviceNode) 0116 { 0117 Q_ASSERT(m_innerFs); 0118 Q_ASSERT(!m_passphrase.isEmpty()); 0119 0120 ExternalCommand createCmd(report, QStringLiteral("cryptsetup"), 0121 { QStringLiteral("-s"), 0122 QStringLiteral("512"), 0123 QStringLiteral("--batch-mode"), 0124 QStringLiteral("--force-password"), 0125 QStringLiteral("--type"), QStringLiteral("luks1"), 0126 QStringLiteral("luksFormat"), 0127 deviceNode }); 0128 if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') && 0129 createCmd.start(-1) && createCmd.exitCode() == 0)) 0130 { 0131 return false; 0132 } 0133 0134 ExternalCommand openCmd(report, QStringLiteral("cryptsetup"), 0135 { QStringLiteral("open"), 0136 deviceNode, 0137 suggestedMapperName(deviceNode) }); 0138 0139 if (!( openCmd.write(m_passphrase.toLocal8Bit() + '\n') && openCmd.start(-1))) 0140 return false; 0141 0142 setPayloadSize(); 0143 scan(deviceNode); 0144 0145 if (mapperName().isEmpty()) 0146 return false; 0147 0148 if (!m_innerFs->create(report, mapperName())) 0149 return false; 0150 0151 return true; 0152 } 0153 0154 bool luks::execChangePosixPermission(Report& report, const QString&) 0155 { 0156 return FileSystem::execChangePosixPermission(report, mapperName()); 0157 } 0158 0159 QString luks::mountTitle() const 0160 { 0161 return xi18nc("@title:menu", "Mount"); 0162 } 0163 0164 QString luks::unmountTitle() const 0165 { 0166 return xi18nc("@title:menu", "Unmount"); 0167 } 0168 0169 QString luks::cryptOpenTitle() const 0170 { 0171 return xi18nc("@title:menu", "Unlock"); 0172 } 0173 0174 QString luks::cryptCloseTitle() const 0175 { 0176 return xi18nc("@title:menu", "Lock"); 0177 } 0178 0179 void luks::setPassphrase(const QString& passphrase) 0180 { 0181 m_passphrase = passphrase; 0182 } 0183 0184 QString luks::passphrase() const 0185 { 0186 return m_passphrase; 0187 } 0188 0189 bool luks::canMount(const QString&, const QString& mountPoint) const 0190 { 0191 return m_isCryptOpen && 0192 !m_isMounted && 0193 m_innerFs && 0194 m_innerFs->canMount(mapperName(), mountPoint); 0195 } 0196 0197 bool luks::canUnmount(const QString&) const 0198 { 0199 return m_isCryptOpen && 0200 m_isMounted && 0201 m_innerFs && 0202 m_innerFs->canUnmount(mapperName()); 0203 } 0204 0205 bool luks::isMounted() const 0206 { 0207 return m_isCryptOpen && m_isMounted; 0208 } 0209 0210 void luks::setMounted(bool mounted) 0211 { 0212 m_isMounted = mounted; 0213 } 0214 0215 bool luks::canCryptOpen(const QString&) const 0216 { 0217 return !m_isCryptOpen && !m_isMounted && supportToolFound(); 0218 } 0219 0220 bool luks::canCryptClose(const QString&) const 0221 { 0222 return m_isCryptOpen && !m_isMounted && m_cryptsetupFound; 0223 } 0224 0225 bool luks::isCryptOpen() const 0226 { 0227 return m_isCryptOpen; 0228 } 0229 0230 void luks::setCryptOpen(bool cryptOpen) 0231 { 0232 m_isCryptOpen = cryptOpen; 0233 } 0234 0235 bool luks::cryptOpen(QWidget* parent, const QString& deviceNode) 0236 { 0237 if (m_isCryptOpen) 0238 { 0239 if (!mapperName().isEmpty()) 0240 { 0241 qWarning() << "LUKS device" << deviceNode 0242 << "already decrypted." 0243 << "Cannot decrypt again."; 0244 return false; 0245 } 0246 else 0247 { 0248 qWarning() << "LUKS device" << deviceNode 0249 << "reportedly decrypted but mapper node not found." 0250 << "Marking device as NOT decrypted and trying to " 0251 "decrypt again anyway."; 0252 m_isCryptOpen = false; 0253 } 0254 } 0255 0256 KPasswordDialog dlg( parent ); 0257 dlg.setPrompt(i18n("Enter passphrase for %1:", deviceNode)); 0258 if( !dlg.exec() ) 0259 return false; 0260 0261 QString passphrase = dlg.password(); 0262 ExternalCommand openCmd(QStringLiteral("cryptsetup"), 0263 { QStringLiteral("open"), 0264 QStringLiteral("--tries"), QStringLiteral("1"), 0265 deviceNode, 0266 suggestedMapperName(deviceNode) }); 0267 0268 if (!( openCmd.write(passphrase.toLocal8Bit() + '\n') && 0269 openCmd.start(-1) && openCmd.exitCode() == 0) ) 0270 return false; 0271 0272 if (m_innerFs) { 0273 delete m_innerFs; 0274 m_innerFs = nullptr; 0275 } 0276 0277 scan(deviceNode); 0278 0279 if (mapperName().isEmpty()) 0280 return false; 0281 0282 loadInnerFileSystem(mapperName()); 0283 m_isCryptOpen = (m_innerFs != nullptr); 0284 0285 if (!m_isCryptOpen) 0286 return false; 0287 0288 for (auto &p : LVM::pvList::list()) 0289 if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV) 0290 p.setLuks(false); 0291 0292 m_passphrase = passphrase; 0293 return true; 0294 } 0295 0296 bool luks::cryptClose(const QString& deviceNode) 0297 { 0298 if (!m_isCryptOpen) 0299 { 0300 qWarning() << "Cannot close LUKS device" << deviceNode 0301 << "because it's not open."; 0302 return false; 0303 } 0304 0305 if (m_isMounted) 0306 { 0307 qWarning() << "Cannot close LUKS device" << deviceNode 0308 << "because the filesystem is mounted."; 0309 return false; 0310 } 0311 0312 ExternalCommand cmd(QStringLiteral("cryptsetup"), 0313 { QStringLiteral("close"), mapperName() }); 0314 if (!(cmd.run(-1) && cmd.exitCode() == 0)) 0315 return false; 0316 0317 delete m_innerFs; 0318 m_innerFs = nullptr; 0319 0320 m_passphrase.clear(); 0321 setLabel(FileSystem::readLabel(deviceNode)); 0322 setUUID(readUUID(deviceNode)); 0323 setSectorsUsed(-1); 0324 0325 m_isCryptOpen = (m_innerFs != nullptr); 0326 0327 for (auto &p : LVM::pvList::list()) 0328 if (!p.isLuks() && p.partition()->deviceNode() == deviceNode) 0329 p.setLuks(true); 0330 0331 return true; 0332 } 0333 0334 void luks::loadInnerFileSystem(const QString& mapperNode) 0335 { 0336 Q_ASSERT(!m_innerFs); 0337 FileSystem::Type innerFsType = detectFileSystem(mapperNode); 0338 m_innerFs = FileSystemFactory::cloneWithNewType(innerFsType, 0339 *this); 0340 setLabel(m_innerFs->readLabel(mapperNode)); 0341 setUUID(m_innerFs->readUUID(mapperNode)); 0342 if (m_innerFs->supportGetUsed() == FileSystem::cmdSupportFileSystem) 0343 setSectorsUsed(static_cast<qint64>(std::ceil((m_innerFs->readUsedCapacity(mapperNode) + payloadOffset()) / static_cast<double>(sectorSize()) ))); 0344 m_innerFs->scan(mapperNode); 0345 } 0346 0347 void luks::createInnerFileSystem(FileSystem::Type type) 0348 { 0349 Q_ASSERT(!m_innerFs); 0350 m_innerFs = FileSystemFactory::cloneWithNewType(type, *this); 0351 } 0352 0353 bool luks::check(Report& report, const QString&) const 0354 { 0355 Q_ASSERT(m_innerFs); 0356 0357 if (mapperName().isEmpty()) 0358 return false; 0359 0360 return m_innerFs->check(report, mapperName()); 0361 } 0362 0363 qint64 luks::readUsedCapacity(const QString& deviceNode) const 0364 { 0365 if (!m_isCryptOpen) 0366 return -1; 0367 if (m_innerFs) 0368 return m_innerFs->readUsedCapacity(deviceNode); 0369 return -1; 0370 } 0371 0372 bool luks::mount(Report& report, const QString& deviceNode, const QString& mountPoint) 0373 { 0374 if (!m_isCryptOpen) 0375 { 0376 qWarning() << "Cannot mount device" << deviceNode 0377 << "before decrypting it first."; 0378 return false; 0379 } 0380 0381 if (m_isMounted) 0382 { 0383 qWarning() << "Cannot mount device" << deviceNode 0384 << "because it's already mounted."; 0385 return false; 0386 } 0387 0388 Q_ASSERT(m_innerFs); 0389 0390 if (mapperName().isEmpty()) 0391 return false; 0392 0393 if (m_innerFs->canMount(mapperName(), mountPoint)) 0394 { 0395 if (m_innerFs->mount(report, mapperName(), mountPoint)) 0396 { 0397 m_isMounted = true; 0398 0399 const QStorageInfo storageInfo = QStorageInfo(mountPoint); 0400 if (storageInfo.isValid() && !mountPoint.isEmpty()) 0401 setSectorsUsed( (storageInfo.bytesTotal() - storageInfo.bytesFree() + payloadOffset()) / sectorSize()); 0402 0403 return true; 0404 } 0405 } 0406 else { 0407 ExternalCommand mountCmd( 0408 report, 0409 QStringLiteral("mount"), 0410 { QStringLiteral("--verbose"), mapperName(), mountPoint }); 0411 if (mountCmd.run() && mountCmd.exitCode() == 0) 0412 { 0413 m_isMounted = true; 0414 return true; 0415 } 0416 } 0417 return false; 0418 } 0419 0420 bool luks::unmount(Report& report, const QString& deviceNode) 0421 { 0422 if (!m_isCryptOpen) 0423 { 0424 qWarning() << "Cannot unmount device" << deviceNode 0425 << "before decrypting it first."; 0426 return false; 0427 } 0428 0429 if (!m_isMounted) 0430 { 0431 qWarning() << "Cannot unmount device" << deviceNode 0432 << "because it's not mounted."; 0433 return false; 0434 } 0435 0436 Q_ASSERT(m_innerFs); 0437 0438 if (mapperName().isEmpty()) 0439 return false; 0440 0441 if (m_innerFs->canUnmount(mapperName())) 0442 { 0443 if (m_innerFs->unmount(report, mapperName())) 0444 { 0445 m_isMounted = false; 0446 return true; 0447 } 0448 } 0449 else { 0450 ExternalCommand unmountCmd( report, 0451 QStringLiteral("umount"), 0452 { QStringLiteral("--verbose"), QStringLiteral("--all-targets"), mapperName() }); 0453 if (unmountCmd.run() && unmountCmd.exitCode() == 0) 0454 { 0455 m_isMounted = false; 0456 return true; 0457 } 0458 } 0459 return false; 0460 } 0461 0462 FileSystem::Type luks::type() const 0463 { 0464 if (m_isCryptOpen && m_innerFs) 0465 return m_innerFs->type(); 0466 return FileSystem::Type::Luks; 0467 } 0468 0469 QString luks::suggestedMapperName(const QString& deviceNode) const 0470 { 0471 return QStringLiteral("luks-") + readOuterUUID(deviceNode); 0472 } 0473 0474 QString luks::readLabel(const QString& deviceNode) const 0475 { 0476 if (m_isCryptOpen && m_innerFs) 0477 return m_innerFs->readLabel(mapperName()); 0478 0479 return FileSystem::readLabel(deviceNode); 0480 } 0481 0482 bool luks::writeLabel(Report& report, const QString&, const QString& newLabel) 0483 { 0484 Q_ASSERT(m_innerFs); 0485 return m_innerFs->writeLabel(report, mapperName(), newLabel); 0486 } 0487 0488 bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) const 0489 { 0490 Q_ASSERT(m_innerFs); 0491 0492 if (mapperName().isEmpty()) 0493 return false; 0494 0495 const qint64 sizeDiff = newLength - length() * sectorSize(); 0496 const qint64 newPayloadSize = m_PayloadSize + sizeDiff; 0497 if ( sizeDiff > 0 ) // grow 0498 { 0499 ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() }); 0500 report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode); 0501 0502 if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) 0503 return m_innerFs->resize(report, mapperName(), newPayloadSize); 0504 } 0505 else if (m_innerFs->resize(report, mapperName(), newPayloadSize)) // shrink 0506 { 0507 ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), 0508 { QStringLiteral("--size"), QString::number(newPayloadSize / 512), // LUKS1 payload length is specified in multiples of 512 bytes 0509 QStringLiteral("resize"), mapperName() }); 0510 report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode); 0511 if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0) 0512 return true; 0513 } 0514 report.line() << xi18nc("@info:progress", "Resizing encrypted file system on partition <filename>%1</filename> failed.", deviceNode); 0515 return false; 0516 } 0517 0518 bool luks::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const 0519 { 0520 Q_UNUSED(mountPoint) 0521 return resize(report, deviceNode, length); 0522 } 0523 0524 QString luks::readUUID(const QString& deviceNode) const 0525 { 0526 QString outerUuid = readOuterUUID(deviceNode); 0527 if (m_isCryptOpen && m_innerFs) 0528 return m_innerFs->readUUID(mapperName()); 0529 return outerUuid; 0530 } 0531 0532 QString luks::readOuterUUID(const QString &deviceNode) const 0533 { 0534 if ( deviceNode.isEmpty() ) 0535 return QString(); 0536 0537 ExternalCommand cmd(QStringLiteral("cryptsetup"), 0538 { QStringLiteral("luksUUID"), deviceNode }); 0539 if (cmd.run()) { 0540 if ( cmd.exitCode() ) 0541 { 0542 qWarning() << "Cannot get luksUUID for device" << deviceNode 0543 << "\tcryptsetup exit code" << cmd.exitCode() 0544 << "\toutput:" << cmd.output().trimmed(); 0545 return QString(); 0546 } 0547 QString outerUuid = cmd.output().trimmed(); 0548 const_cast< QString& >( m_outerUuid ) = outerUuid; 0549 return outerUuid; 0550 } 0551 return QStringLiteral("---"); 0552 } 0553 0554 bool luks::updateUUID(Report& report, const QString& deviceNode) const 0555 { 0556 const QString uuid = QUuid::createUuid().toString().remove(QRegularExpression(QStringLiteral("\\{|\\}"))); 0557 0558 ExternalCommand cmd(report, 0559 QStringLiteral("cryptsetup"), 0560 { QStringLiteral("luksUUID"), 0561 deviceNode, 0562 QStringLiteral("--uuid"), 0563 uuid }); 0564 return cmd.run(-1) && cmd.exitCode() == 0; 0565 } 0566 0567 void luks::getMapperName(const QString& deviceNode) 0568 { 0569 ExternalCommand cmd(QStringLiteral("lsblk"), 0570 { QStringLiteral("--list"), 0571 QStringLiteral("--noheadings"), 0572 QStringLiteral("--paths"), 0573 QStringLiteral("--json"), 0574 QStringLiteral("--output"), 0575 QStringLiteral("type,name"), 0576 deviceNode }); 0577 m_MapperName = QString(); 0578 0579 if (cmd.run(-1) && cmd.exitCode() == 0) { 0580 const QJsonDocument jsonDocument = QJsonDocument::fromJson(cmd.rawOutput()); 0581 QJsonObject jsonObject = jsonDocument.object(); 0582 const QJsonArray jsonArray = jsonObject[QLatin1String("blockdevices")].toArray(); 0583 for (const auto &deviceLine : jsonArray) { 0584 QJsonObject deviceObject = deviceLine.toObject(); 0585 if (deviceObject[QLatin1String("type")].toString() == QLatin1String("crypt")) { 0586 m_MapperName = deviceObject[QLatin1String("name")].toString(); 0587 break; 0588 } 0589 } 0590 } 0591 } 0592 0593 void luks::getLuksInfo(const QString& deviceNode) 0594 { 0595 ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("luksDump"), deviceNode }); 0596 if (cmd.run(-1) && cmd.exitCode() == 0) { 0597 QRegularExpression re(QStringLiteral("Cipher name:\\s+(\\w+)")); 0598 QRegularExpressionMatch rem = re.match(cmd.output()); 0599 if (rem.hasMatch()) 0600 m_CipherName = rem.captured(1); 0601 else 0602 m_CipherName = QLatin1String("---"); 0603 0604 re.setPattern(QStringLiteral("Cipher mode:\\s+(\\w+)")); 0605 rem = re.match(cmd.output()); 0606 if (rem.hasMatch()) 0607 m_CipherMode = rem.captured(1); 0608 else 0609 m_CipherMode = QLatin1String("---"); 0610 0611 re.setPattern(QStringLiteral("Hash spec:\\s+(\\w+)")); 0612 rem = re.match(cmd.output()); 0613 if (rem.hasMatch()) 0614 m_HashName = rem.captured(1); 0615 else 0616 m_HashName = QLatin1String("---"); 0617 0618 re.setPattern(QStringLiteral("MK bits:\\s+(\\d+)")); 0619 rem = re.match(cmd.output()); 0620 if (rem.hasMatch()) 0621 m_KeySize = rem.captured(1).toLongLong(); 0622 else 0623 m_KeySize = -1; 0624 0625 re.setPattern(QStringLiteral("Payload offset:\\s+(\\d+)")); 0626 rem = re.match(cmd.output()); 0627 if (rem.hasMatch()) 0628 m_PayloadOffset = rem.captured(1).toLongLong() * 512; // assuming LUKS sector size is 512; 0629 else 0630 m_PayloadOffset = -1; 0631 0632 } 0633 else { 0634 m_CipherName = QLatin1String("---"); 0635 m_CipherMode = QLatin1String("---"); 0636 m_HashName = QLatin1String("---"); 0637 m_KeySize = -1; 0638 m_PayloadOffset = -1; 0639 } 0640 } 0641 0642 QString luks::outerUuid() const 0643 { 0644 return m_outerUuid; 0645 } 0646 0647 bool luks::canEncryptType(FileSystem::Type type) 0648 { 0649 switch (type) 0650 { 0651 case Type::Btrfs: 0652 case Type::F2fs: 0653 case Type::Ext2: 0654 case Type::Ext3: 0655 case Type::Ext4: 0656 case Type::Jfs: 0657 case Type::LinuxSwap: 0658 case Type::Lvm2_PV: 0659 case Type::Nilfs2: 0660 case Type::ReiserFS: 0661 case Type::Reiser4: 0662 case Type::Xfs: 0663 case Type::Zfs: 0664 return true; 0665 default: 0666 return false; 0667 } 0668 } 0669 0670 void luks::initLUKS() 0671 { 0672 setPayloadSize(); 0673 QString mapperNode = mapperName(); 0674 bool isCryptOpen = !mapperNode.isEmpty(); 0675 setCryptOpen(isCryptOpen); 0676 if (isCryptOpen) { 0677 loadInnerFileSystem(mapperNode); 0678 setMounted(detectMountStatus(innerFS(), mapperNode)); 0679 } 0680 } 0681 0682 void luks::setPayloadSize() 0683 { 0684 ExternalCommand dmsetupCmd(QStringLiteral("dmsetup"), { QStringLiteral("table"), mapperName() }); 0685 dmsetupCmd.run(); 0686 QRegularExpression re(QStringLiteral("\\d+ (\\d+)")); 0687 QRegularExpressionMatch rem = re.match(dmsetupCmd.output()); 0688 if (rem.hasMatch()) 0689 m_PayloadSize = rem.captured(1).toLongLong() * sectorSize(); 0690 } 0691 0692 bool luks::testPassphrase(const QString& deviceNode, const QString& passphrase) const { 0693 ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), QStringLiteral("--tries"), QStringLiteral("1"), QStringLiteral("--test-passphrase"), deviceNode }); 0694 if (cmd.write(passphrase.toLocal8Bit() + '\n') && cmd.start(-1) && cmd.exitCode() == 0) 0695 return true; 0696 0697 return false; 0698 } 0699 0700 }