Fix issue 1963: label encrypted partitions
This commit is contained in:
parent
9fdae8c76f
commit
9ca763127d
@ -25,6 +25,8 @@
|
||||
#include <kpmcore/fs/luks.h>
|
||||
#include <kpmcore/util/externalcommand.h>
|
||||
|
||||
#include <qregularexpression.h>
|
||||
|
||||
using CalamaresUtils::Partition::PartitionIterator;
|
||||
|
||||
namespace KPMHelpers
|
||||
@ -133,7 +135,6 @@ clonePartition( Device* device, Partition* partition )
|
||||
partition->activeFlags() );
|
||||
}
|
||||
|
||||
// Adapted from src/fs/luks.cpp cryptOpen which always opens a dialog to ask for a passphrase
|
||||
SavePassphraseValue
|
||||
savePassphrase( Partition* partition, const QString& passphrase )
|
||||
{
|
||||
@ -143,57 +144,161 @@ savePassphrase( Partition* partition, const QString& passphrase )
|
||||
return SavePassphraseValue::EmptyPassphrase;
|
||||
}
|
||||
|
||||
if ( partition->fileSystem().type() != FileSystem::Luks )
|
||||
FS::luks* luksFs = dynamic_cast< FS::luks* >( &partition->fileSystem() );
|
||||
if ( luksFs == nullptr )
|
||||
{
|
||||
// No luks device
|
||||
return SavePassphraseValue::NotLuksPartition;
|
||||
}
|
||||
|
||||
FS::luks* luksFs = dynamic_cast< FS::luks* >( &partition->fileSystem() );
|
||||
const QString deviceNode = partition->partitionPath();
|
||||
|
||||
// Test the given passphrase
|
||||
if ( !luksFs->testPassphrase( deviceNode, passphrase ) )
|
||||
if ( !luksFs->testPassphrase( partition->partitionPath(), passphrase ) )
|
||||
{
|
||||
// Save the existing passphrase
|
||||
luksFs->setPassphrase( passphrase );
|
||||
}
|
||||
else
|
||||
{
|
||||
return SavePassphraseValue::IncorrectPassphrase;
|
||||
}
|
||||
return SavePassphraseValue::NoError;
|
||||
}
|
||||
|
||||
// Adapted from src/fs/luks.cpp cryptOpen which always opens a dialog to ask for a passphrase
|
||||
QString
|
||||
cryptOpen( Partition* partition )
|
||||
{
|
||||
FS::luks* luksFs = dynamic_cast< FS::luks* >( &partition->fileSystem() );
|
||||
if ( luksFs == nullptr )
|
||||
{
|
||||
// No luks device
|
||||
return QString();
|
||||
}
|
||||
|
||||
if ( luksFs->isCryptOpen() )
|
||||
{
|
||||
if ( !luksFs->mapperName().isEmpty() )
|
||||
{
|
||||
return SavePassphraseValue::NoError;
|
||||
// Already decrypted
|
||||
return luksFs->mapperName();
|
||||
}
|
||||
else
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "No mapper node found";
|
||||
cDebug() << Logger::SubEntry << "No mapper node found - reset cryptOpen";
|
||||
luksFs->setCryptOpen( false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( luksFs->passphrase().isEmpty() )
|
||||
{
|
||||
// No passphrase for decryption
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Decrypt the partition
|
||||
const QString deviceNode = partition->partitionPath();
|
||||
ExternalCommand openCmd( QStringLiteral( "cryptsetup" ),
|
||||
{ QStringLiteral( "open" ), deviceNode, luksFs->suggestedMapperName( deviceNode ) } );
|
||||
if ( !( openCmd.write( passphrase.toLocal8Bit() + '\n' ) && openCmd.start( -1 ) && openCmd.exitCode() == 0 ) )
|
||||
if ( ( openCmd.write( luksFs->passphrase().toLocal8Bit() + '\n' ) && openCmd.start( -1 ) && openCmd.exitCode() == 0 ) )
|
||||
{
|
||||
cWarning() << Logger::SubEntry << openCmd.exitCode() << ": cryptsetup command failed";
|
||||
return SavePassphraseValue::CryptsetupError;
|
||||
luksFs->scan( deviceNode );
|
||||
if ( luksFs->mapperName().isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
luksFs->loadInnerFileSystem( luksFs->mapperName() );
|
||||
luksFs->setCryptOpen( luksFs->innerFS() != nullptr );
|
||||
if ( !luksFs->isCryptOpen() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
return luksFs->mapperName();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void
|
||||
cryptClose( Partition* partition )
|
||||
{
|
||||
FS::luks* luksFs = dynamic_cast< FS::luks* >( &partition->fileSystem() );
|
||||
if ( luksFs == nullptr )
|
||||
{
|
||||
// No luks device
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the existing passphrase
|
||||
luksFs->setPassphrase( passphrase );
|
||||
luksFs->scan( deviceNode );
|
||||
if ( luksFs->mapperName().isEmpty() )
|
||||
{
|
||||
return SavePassphraseValue::NoMapperNode;
|
||||
// Not opened
|
||||
return;
|
||||
}
|
||||
|
||||
luksFs->loadInnerFileSystem( luksFs->mapperName() );
|
||||
luksFs->setCryptOpen( luksFs->innerFS() != nullptr );
|
||||
if ( !luksFs->isCryptOpen() )
|
||||
// Close the partition
|
||||
luksFs->cryptClose( partition->partitionPath() );
|
||||
}
|
||||
|
||||
bool
|
||||
cryptLabel( Partition* partition, const QString& label )
|
||||
{
|
||||
int version = cryptVersion( partition );
|
||||
if ( version == 0 || label.isEmpty() )
|
||||
{
|
||||
return SavePassphraseValue::DeviceNotDecrypted;
|
||||
return false;
|
||||
}
|
||||
|
||||
return SavePassphraseValue::NoError;
|
||||
if ( version == 1 )
|
||||
{
|
||||
QString mappedDevice = cryptOpen( partition );
|
||||
if ( !mappedDevice.isEmpty() )
|
||||
{
|
||||
// Label mapped device
|
||||
ExternalCommand openCmd( QStringLiteral( "e2label" ),
|
||||
{ mappedDevice,
|
||||
label } );
|
||||
openCmd.start( -1 );
|
||||
cryptClose( partition );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExternalCommand openCmd( QStringLiteral( "cryptsetup" ),
|
||||
{ QStringLiteral( "config" ),
|
||||
partition->partitionPath(),
|
||||
QStringLiteral( "--label" ),
|
||||
label } );
|
||||
if ( openCmd.start( -1 ) && openCmd.exitCode() == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
cryptVersion( Partition* partition )
|
||||
{
|
||||
if ( partition->fileSystem().type() != FileSystem::Luks )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get luks version from header information
|
||||
int luksVersion = 1;
|
||||
ExternalCommand openCmd( QStringLiteral( "cryptsetup" ),
|
||||
{ QStringLiteral( "luksDump" ),
|
||||
partition->partitionPath() } );
|
||||
if ( openCmd.start( -1 ) && openCmd.exitCode() == 0 )
|
||||
{
|
||||
QRegularExpression re( QStringLiteral( R"(version:\s+(\d))" ),
|
||||
QRegularExpression::CaseInsensitiveOption );
|
||||
QRegularExpressionMatch rem = re.match( openCmd.output() );
|
||||
if ( rem.hasMatch() )
|
||||
{
|
||||
luksVersion = rem.captured( 1 ).toInt();
|
||||
}
|
||||
}
|
||||
return luksVersion;
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
|
@ -98,6 +98,27 @@ Partition* clonePartition( Device* device, Partition* partition );
|
||||
*/
|
||||
SavePassphraseValue savePassphrase( Partition* partition, const QString& passphrase );
|
||||
|
||||
/** @brief Decrypt an encrypted partition.
|
||||
*
|
||||
* Uses @p partition to decrypt the partition.
|
||||
* The passphrase saved in @p partition is used.
|
||||
* Returns the mapped device path or an empty string if it fails.
|
||||
*/
|
||||
QString cryptOpen( Partition* partition );
|
||||
void cryptClose( Partition* partition );
|
||||
|
||||
/** @brief Set label of luks encrypted partition.
|
||||
*
|
||||
* Returns true on success or false if it fails.
|
||||
*/
|
||||
bool cryptLabel( Partition* partition, const QString& label );
|
||||
|
||||
/** @brief Returns the luks version used to encrypt the partition.
|
||||
*
|
||||
* Used by cryptLabel
|
||||
*/
|
||||
int cryptVersion( Partition* partition );
|
||||
|
||||
/** @brief Return a result for an @p operation
|
||||
*
|
||||
* Executes the operation, and if successful, returns a success result.
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "ChangeFilesystemLabelJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <kpmcore/backend/corebackend.h>
|
||||
@ -58,6 +60,17 @@ ChangeFilesystemLabelJob::exec()
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
// Check for luks device
|
||||
if ( partition()->fileSystem().type() == FileSystem::Luks )
|
||||
{
|
||||
if ( KPMHelpers::cryptLabel( partition(), m_label ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
return Calamares::JobResult::error(
|
||||
tr( "The installer failed to update partition table on disk '%1'." ).arg( m_device->name() ) );
|
||||
}
|
||||
|
||||
Report report( nullptr );
|
||||
SetFileSystemLabelOperation op( *partition(), m_label );
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
Loading…
Reference in New Issue
Block a user