Merge branch 'calamares' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Mueller 2023-06-15 20:05:16 +02:00
commit 100f408dae
7 changed files with 100 additions and 34 deletions

View File

@ -54,8 +54,9 @@ class cpuinfo(object):
self.number_of_cores = 0
cpu = self._cpuinfo()
self.is_intel = cpu['proc0']['vendor_id'].lower() == "genuineintel"
self.is_amd = cpu['proc0']['vendor_id'].lower() == "authenticamd"
if 'vendor_id' in cpu['proc0']:
self.is_intel = cpu['proc0']['vendor_id'].lower() == "genuineintel"
self.is_amd = cpu['proc0']['vendor_id'].lower() == "authenticamd"
self.number_of_cores = len(cpu)
@staticmethod

View File

@ -9,7 +9,6 @@ calamares_add_plugin(luksbootkeyfile
SOURCES
LuksBootKeyFileJob.cpp
SHARED_LIB
NO_CONFIG
)
calamares_add_test(luksbootkeyfiletest SOURCES Tests.cpp LuksBootKeyFileJob.cpp)

View File

@ -135,34 +135,64 @@ generateTargetKeyfile()
}
static bool
setupLuks( const LuksDevice& d )
setupLuks( const LuksDevice& d, const QString& luks2Hash )
{
// Sometimes this error is thrown: "All key slots full"
// luksAddKey will fail. So, remove the first slot to make room
// Get luksDump for this device
auto luks_dump = CalamaresUtils::System::instance()->targetEnvCommand(
{ "cryptsetup", "luksDump", d.device }, QString(), QString(), std::chrono::seconds( 5 ) );
if ( luks_dump.getExitCode() == 0 )
{ QStringLiteral( "cryptsetup" ), QStringLiteral( "luksDump" ), d.device },
QString(),
QString(),
std::chrono::seconds( 5 ) );
if ( luks_dump.getExitCode() != 0 )
{
QRegularExpression re( QStringLiteral( R"(\d+:\s*enabled)" ), QRegularExpression::CaseInsensitiveOption );
int count = luks_dump.getOutput().count( re );
cDebug() << "Luks Dump slot count: " << count;
if ( count >= 7 )
cWarning() << "Could not get LUKS information on " << d.device << ':' << luks_dump.getOutput() << "(exit code"
<< luks_dump.getExitCode() << ')';
return false;
}
// Check LUKS version
int luks_version = 0;
QRegularExpression version_re( QStringLiteral( R"(version:\s*([0-9]))" ),
QRegularExpression::CaseInsensitiveOption );
QRegularExpressionMatch match = version_re.match( luks_dump.getOutput() );
if ( ! match.hasMatch() )
{
cWarning() << "Could not get LUKS version on device: " << d.device;
return false;
}
bool ok;
luks_version = match.captured(1).toInt(&ok);
if( ! ok )
{
cWarning() << "Could not get LUKS version on device: " << d.device;
return false;
}
cDebug() << "LUKS" << luks_version << " found on device: " << d.device;
// Check the number of slots used for LUKS1 devices
if ( luks_version == 1 )
{
QRegularExpression slots_re( QStringLiteral( R"(\d+:\s*enabled)" ),
QRegularExpression::CaseInsensitiveOption );
if ( luks_dump.getOutput().count( slots_re ) == 8 )
{
auto r = CalamaresUtils::System::instance()->targetEnvCommand(
{ "cryptsetup", "luksKillSlot", d.device, "1" }, QString(), d.passphrase, std::chrono::seconds( 60 ) );
if ( r.getExitCode() != 0 )
{
cWarning() << "Could not kill a slot to make room on" << d.device << ':' << r.getOutput()
<< "(exit code" << r.getExitCode() << ')';
return false;
}
cWarning() << "No key slots left on LUKS1 device: " << d.device;
return false;
}
}
// Adding the key can take some times, measured around 15 seconds with
// a HDD (spinning rust) and a slow-ish computer. Give it a minute.
// Add the key to the keyfile
QStringList args = { QStringLiteral( "cryptsetup" ), QStringLiteral( "luksAddKey" ), d.device, keyfile };
if ( luks_version == 2 && luks2Hash != QString() )
{
args.insert(2, "--pbkdf");
args.insert(3, luks2Hash);
}
auto r = CalamaresUtils::System::instance()->targetEnvCommand(
{ "cryptsetup", "luksAddKey", d.device, keyfile }, QString(), d.passphrase, std::chrono::seconds( 60 ) );
args,
QString(),
d.passphrase,
std::chrono::seconds( 60 ) );
if ( r.getExitCode() != 0 )
{
cWarning() << "Could not configure LUKS keyfile on" << d.device << ':' << r.getOutput() << "(exit code"
@ -259,15 +289,15 @@ LuksBootKeyFileJob::exec()
if ( it == s.devices.begin() )
{
// Then there was no root partition
cDebug() << Logger::SubEntry << "No root partition.";
// User has configured non-root partition for encryption
cDebug() << Logger::SubEntry << "No root partition, skipping keyfile creation.";
return Calamares::JobResult::ok();
}
// /boot partition is not encrypted, keyfile must not be used
// But only if root partition is not encrypted
if ( hasUnencryptedSeparateBoot() && !hasEncryptedRoot() )
{
// /boot partition is not encrypted, keyfile must not be used
// But only if root partition is not encrypted
cDebug() << Logger::SubEntry << "/boot partition is not encrypted, skipping keyfile creation.";
return Calamares::JobResult::ok();
}
@ -295,13 +325,22 @@ LuksBootKeyFileJob::exec()
continue;
}
if ( !setupLuks( d ) )
return Calamares::JobResult::error(
tr( "Encrypted rootfs setup error" ),
tr( "Could not configure LUKS key file on partition %1." ).arg( d.device ) );
if ( !setupLuks( d, m_luks2Hash ) )
{
// Could not configure the LUKS partition
// This should not stop the installation: do not return Calamares::JobResult::error.
cError() << "Encrypted rootfs setup error: could not configure LUKS key file on partition " << d.device;
}
}
return Calamares::JobResult::ok();
}
void
LuksBootKeyFileJob::setConfigurationMap( const QVariantMap& configurationMap )
{
m_luks2Hash = CalamaresUtils::getString(
configurationMap, QStringLiteral( "luks2Hash" ), QString() );
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( LuksBootKeyFileJobFactory, registerPlugin< LuksBootKeyFileJob >(); )

View File

@ -30,6 +30,11 @@ public:
QString prettyName() const override;
Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
QString m_luks2Hash;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( LuksBootKeyFileJobFactory )

View File

@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Luksbootkeyfile configuration. A key file is created for the
# LUKS encrypted devices.
---
# Set Password-Based Key Derivation Function (PBKDF) algorithm
# for LUKS keyslot.
#
# There are three usable values: pbkdf2, argon2i or argon2id.
#
# When not set, the cryptsetup default is used
#luks2Hash: argon2id

View File

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2023 Arjen Balfoort <arjenbalfoort@hotmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
---
$schema: https://json-schema.org/schema#
$id: https://calamares.io/schemas/luksbootkeyfile
additionalProperties: false
type: object
properties:
luks2Hash: { type: string, enum: [ pbkdf2, argon2i, argon2id ] }

View File

@ -31,7 +31,7 @@
# # finally masks pacman-init (an ArchLinux-only service).
# #
# units:
# - name: "NetworkManager"
# - name: "NetworkManager.service"
# action: "enable"
# mandatory: true
#
@ -40,12 +40,12 @@
# # The property "mandatory" is taken to be false by default here
# # because it is not specified
#
# - name: "graphical"
# - name: "graphical.target"
# action: "enable"
# # The property "mandatory" is taken to be false by default here
# # because it is not specified
#
# - name: "pacman-init"
# - name: "pacman-init.service"
# action: "mask"
# # The property "mandatory" is taken to be false by default here
# # because it is not specified