Merge branch 'calamares' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
100f408dae
@ -54,6 +54,7 @@ class cpuinfo(object):
|
|||||||
self.number_of_cores = 0
|
self.number_of_cores = 0
|
||||||
|
|
||||||
cpu = self._cpuinfo()
|
cpu = self._cpuinfo()
|
||||||
|
if 'vendor_id' in cpu['proc0']:
|
||||||
self.is_intel = cpu['proc0']['vendor_id'].lower() == "genuineintel"
|
self.is_intel = cpu['proc0']['vendor_id'].lower() == "genuineintel"
|
||||||
self.is_amd = cpu['proc0']['vendor_id'].lower() == "authenticamd"
|
self.is_amd = cpu['proc0']['vendor_id'].lower() == "authenticamd"
|
||||||
self.number_of_cores = len(cpu)
|
self.number_of_cores = len(cpu)
|
||||||
|
@ -9,7 +9,6 @@ calamares_add_plugin(luksbootkeyfile
|
|||||||
SOURCES
|
SOURCES
|
||||||
LuksBootKeyFileJob.cpp
|
LuksBootKeyFileJob.cpp
|
||||||
SHARED_LIB
|
SHARED_LIB
|
||||||
NO_CONFIG
|
|
||||||
)
|
)
|
||||||
|
|
||||||
calamares_add_test(luksbootkeyfiletest SOURCES Tests.cpp LuksBootKeyFileJob.cpp)
|
calamares_add_test(luksbootkeyfiletest SOURCES Tests.cpp LuksBootKeyFileJob.cpp)
|
||||||
|
@ -135,34 +135,64 @@ generateTargetKeyfile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
setupLuks( const LuksDevice& d )
|
setupLuks( const LuksDevice& d, const QString& luks2Hash )
|
||||||
{
|
{
|
||||||
// Sometimes this error is thrown: "All key slots full"
|
// Get luksDump for this device
|
||||||
// luksAddKey will fail. So, remove the first slot to make room
|
|
||||||
auto luks_dump = CalamaresUtils::System::instance()->targetEnvCommand(
|
auto luks_dump = CalamaresUtils::System::instance()->targetEnvCommand(
|
||||||
{ "cryptsetup", "luksDump", d.device }, QString(), QString(), std::chrono::seconds( 5 ) );
|
{ QStringLiteral( "cryptsetup" ), QStringLiteral( "luksDump" ), d.device },
|
||||||
if ( luks_dump.getExitCode() == 0 )
|
QString(),
|
||||||
|
QString(),
|
||||||
|
std::chrono::seconds( 5 ) );
|
||||||
|
if ( luks_dump.getExitCode() != 0 )
|
||||||
{
|
{
|
||||||
QRegularExpression re( QStringLiteral( R"(\d+:\s*enabled)" ), QRegularExpression::CaseInsensitiveOption );
|
cWarning() << "Could not get LUKS information on " << d.device << ':' << luks_dump.getOutput() << "(exit code"
|
||||||
int count = luks_dump.getOutput().count( re );
|
<< luks_dump.getExitCode() << ')';
|
||||||
cDebug() << "Luks Dump slot count: " << count;
|
return false;
|
||||||
if ( count >= 7 )
|
}
|
||||||
|
|
||||||
|
// 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() )
|
||||||
{
|
{
|
||||||
auto r = CalamaresUtils::System::instance()->targetEnvCommand(
|
cWarning() << "Could not get LUKS version on device: " << d.device;
|
||||||
{ "cryptsetup", "luksKillSlot", d.device, "1" }, QString(), d.passphrase, std::chrono::seconds( 60 ) );
|
return false;
|
||||||
if ( r.getExitCode() != 0 )
|
}
|
||||||
|
bool ok;
|
||||||
|
luks_version = match.captured(1).toInt(&ok);
|
||||||
|
if( ! ok )
|
||||||
{
|
{
|
||||||
cWarning() << "Could not kill a slot to make room on" << d.device << ':' << r.getOutput()
|
cWarning() << "Could not get LUKS version on device: " << d.device;
|
||||||
<< "(exit code" << r.getExitCode() << ')';
|
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 )
|
||||||
|
{
|
||||||
|
cWarning() << "No key slots left on LUKS1 device: " << d.device;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Adding the key can take some times, measured around 15 seconds with
|
// Add the key to the keyfile
|
||||||
// a HDD (spinning rust) and a slow-ish computer. Give it a minute.
|
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(
|
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 )
|
if ( r.getExitCode() != 0 )
|
||||||
{
|
{
|
||||||
cWarning() << "Could not configure LUKS keyfile on" << d.device << ':' << r.getOutput() << "(exit code"
|
cWarning() << "Could not configure LUKS keyfile on" << d.device << ':' << r.getOutput() << "(exit code"
|
||||||
@ -259,15 +289,15 @@ LuksBootKeyFileJob::exec()
|
|||||||
|
|
||||||
if ( it == s.devices.begin() )
|
if ( it == s.devices.begin() )
|
||||||
{
|
{
|
||||||
// Then there was no root partition
|
// User has configured non-root partition for encryption
|
||||||
cDebug() << Logger::SubEntry << "No root partition.";
|
cDebug() << Logger::SubEntry << "No root partition, skipping keyfile creation.";
|
||||||
return Calamares::JobResult::ok();
|
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() )
|
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.";
|
cDebug() << Logger::SubEntry << "/boot partition is not encrypted, skipping keyfile creation.";
|
||||||
return Calamares::JobResult::ok();
|
return Calamares::JobResult::ok();
|
||||||
}
|
}
|
||||||
@ -295,13 +325,22 @@ LuksBootKeyFileJob::exec()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !setupLuks( d ) )
|
if ( !setupLuks( d, m_luks2Hash ) )
|
||||||
return Calamares::JobResult::error(
|
{
|
||||||
tr( "Encrypted rootfs setup error" ),
|
// Could not configure the LUKS partition
|
||||||
tr( "Could not configure LUKS key file on partition %1." ).arg( d.device ) );
|
// 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();
|
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 >(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( LuksBootKeyFileJobFactory, registerPlugin< LuksBootKeyFileJob >(); )
|
||||||
|
@ -30,6 +30,11 @@ public:
|
|||||||
QString prettyName() const override;
|
QString prettyName() const override;
|
||||||
|
|
||||||
Calamares::JobResult exec() override;
|
Calamares::JobResult exec() override;
|
||||||
|
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_luks2Hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( LuksBootKeyFileJobFactory )
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( LuksBootKeyFileJobFactory )
|
||||||
|
13
src/modules/luksbootkeyfile/luksbootkeyfile.conf
Normal file
13
src/modules/luksbootkeyfile/luksbootkeyfile.conf
Normal 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
|
9
src/modules/luksbootkeyfile/luksbootkeyfile.schema.yaml
Normal file
9
src/modules/luksbootkeyfile/luksbootkeyfile.schema.yaml
Normal 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 ] }
|
@ -31,7 +31,7 @@
|
|||||||
# # finally masks pacman-init (an ArchLinux-only service).
|
# # finally masks pacman-init (an ArchLinux-only service).
|
||||||
# #
|
# #
|
||||||
# units:
|
# units:
|
||||||
# - name: "NetworkManager"
|
# - name: "NetworkManager.service"
|
||||||
# action: "enable"
|
# action: "enable"
|
||||||
# mandatory: true
|
# mandatory: true
|
||||||
#
|
#
|
||||||
@ -40,12 +40,12 @@
|
|||||||
# # The property "mandatory" is taken to be false by default here
|
# # The property "mandatory" is taken to be false by default here
|
||||||
# # because it is not specified
|
# # because it is not specified
|
||||||
#
|
#
|
||||||
# - name: "graphical"
|
# - name: "graphical.target"
|
||||||
# action: "enable"
|
# action: "enable"
|
||||||
# # The property "mandatory" is taken to be false by default here
|
# # The property "mandatory" is taken to be false by default here
|
||||||
# # because it is not specified
|
# # because it is not specified
|
||||||
#
|
#
|
||||||
# - name: "pacman-init"
|
# - name: "pacman-init.service"
|
||||||
# action: "mask"
|
# action: "mask"
|
||||||
# # The property "mandatory" is taken to be false by default here
|
# # The property "mandatory" is taken to be false by default here
|
||||||
# # because it is not specified
|
# # because it is not specified
|
||||||
|
Loading…
Reference in New Issue
Block a user