Merge branch 'entropy' into calamares

Support more than one entropy file; generate them as needed
(or copy a fixed value to all, depending). Deprecate
*entropy* as too inflexible.

See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=941301

FIXES #1512
This commit is contained in:
Adriaan de Groot 2020-09-15 16:51:32 +02:00
commit e84f446c5f
6 changed files with 135 additions and 9 deletions

View File

@ -19,6 +19,11 @@ This release contains contributions from (alphabetically by first name):
- The *keyboard* module now recognizes Turkish "F" layout and - The *keyboard* module now recognizes Turkish "F" layout and
will set the vconsole keyboard layout correctly even if xkb will set the vconsole keyboard layout correctly even if xkb
keymaps are not found. keymaps are not found.
- The *machineid* module, which generates UUIDs for systemd and dbus
and can generate entropy files (filled from `/dev/urandom` in the host
system) now supports more than one entropy file; generate them as needed
(or copy a fixed value to all, depending on *entropy-copy*). Deprecate
*entropy* (which generates a specific output file) as too inflexible.
# 3.2.30 (2020-09-03) # # 3.2.30 (2020-09-03) #

View File

@ -57,14 +57,13 @@ MachineIdJob::exec()
QString target_systemd_machineid_file = QStringLiteral( "/etc/machine-id" ); QString target_systemd_machineid_file = QStringLiteral( "/etc/machine-id" );
QString target_dbus_machineid_file = QStringLiteral( "/var/lib/dbus/machine-id" ); QString target_dbus_machineid_file = QStringLiteral( "/var/lib/dbus/machine-id" );
QString target_entropy_file = QStringLiteral( "/var/lib/urandom/random-seed" );
const CalamaresUtils::System* system = CalamaresUtils::System::instance(); const CalamaresUtils::System* system = CalamaresUtils::System::instance();
// Clear existing files // Clear existing files
if ( m_entropy ) for ( const auto& entropy_file : m_entropy_files )
{ {
system->removeTargetFile( target_entropy_file ); system->removeTargetFile( entropy_file );
} }
if ( m_dbus ) if ( m_dbus )
{ {
@ -76,12 +75,18 @@ MachineIdJob::exec()
} }
//Create new files //Create new files
if ( m_entropy ) for ( const auto& entropy_file : m_entropy_files )
{ {
if ( !CalamaresUtils::System::instance()->createTargetParentDirs( entropy_file ) )
{
return Calamares::JobResult::error(
QObject::tr( "Directory not found" ),
QObject::tr( "Could not create new random file <pre>%1</pre>." ).arg( entropy_file ) );
}
auto r = MachineId::createEntropy( m_entropy_copy ? MachineId::EntropyGeneration::CopyFromHost auto r = MachineId::createEntropy( m_entropy_copy ? MachineId::EntropyGeneration::CopyFromHost
: MachineId::EntropyGeneration::New, : MachineId::EntropyGeneration::New,
root, root,
target_entropy_file ); entropy_file );
if ( !r ) if ( !r )
{ {
return r; return r;
@ -89,6 +94,10 @@ MachineIdJob::exec()
} }
if ( m_systemd ) if ( m_systemd )
{ {
if ( !system->createTargetParentDirs( target_systemd_machineid_file ) )
{
cWarning() << "Could not create systemd data-directory.";
}
auto r = MachineId::createSystemdMachineId( root, target_systemd_machineid_file ); auto r = MachineId::createSystemdMachineId( root, target_systemd_machineid_file );
if ( !r ) if ( !r )
{ {
@ -143,8 +152,19 @@ MachineIdJob::setConfigurationMap( const QVariantMap& map )
// ignore it, though, if dbus is false // ignore it, though, if dbus is false
m_dbus_symlink = m_dbus && m_dbus_symlink; m_dbus_symlink = m_dbus && m_dbus_symlink;
m_entropy = CalamaresUtils::getBool( map, "entropy", false );
m_entropy_copy = CalamaresUtils::getBool( map, "entropy-copy", false ); m_entropy_copy = CalamaresUtils::getBool( map, "entropy-copy", false );
m_entropy_files = CalamaresUtils::getStringList( map, "entropy-files" );
if ( CalamaresUtils::getBool( map, "entropy", false ) )
{
cWarning() << "MachineId:: configuration setting *entropy* is deprecated, use *entropy-files*.";
QString target_entropy_file = QStringLiteral( "/var/lib/urandom/random-seed" );
if ( !m_entropy_files.contains( target_entropy_file ) )
{
m_entropy_files.append( target_entropy_file );
}
}
} }
CALAMARES_PLUGIN_FACTORY_DEFINITION( MachineIdJobFactory, registerPlugin< MachineIdJob >(); ) CALAMARES_PLUGIN_FACTORY_DEFINITION( MachineIdJobFactory, registerPlugin< MachineIdJob >(); )

View File

@ -11,6 +11,7 @@
#define MACHINEIDJOB_H #define MACHINEIDJOB_H
#include <QObject> #include <QObject>
#include <QStringList>
#include <QVariantMap> #include <QVariantMap>
#include "CppJob.h" #include "CppJob.h"
@ -19,6 +20,9 @@
#include "DllMacro.h" #include "DllMacro.h"
/** @brief Write 'random' data: machine id, entropy, UUIDs
*
*/
class PLUGINDLLEXPORT MachineIdJob : public Calamares::CppJob class PLUGINDLLEXPORT MachineIdJob : public Calamares::CppJob
{ {
Q_OBJECT Q_OBJECT
@ -33,14 +37,22 @@ public:
void setConfigurationMap( const QVariantMap& configurationMap ) override; void setConfigurationMap( const QVariantMap& configurationMap ) override;
/** @brief The list of filenames to write full of entropy.
*
* The list may be empty (no entropy files are configure) or
* contain one or more filenames to be interpreted within the
* target system.
*/
QStringList entropyFileNames() const { return m_entropy_files; }
private: private:
bool m_systemd = false; ///< write systemd's files bool m_systemd = false; ///< write systemd's files
bool m_dbus = false; ///< write dbus files bool m_dbus = false; ///< write dbus files
bool m_dbus_symlink = false; ///< .. or just symlink to systemd bool m_dbus_symlink = false; ///< .. or just symlink to systemd
bool m_entropy = false; ///< write an entropy file
bool m_entropy_copy = false; ///< copy from host system bool m_entropy_copy = false; ///< copy from host system
QStringList m_entropy_files; ///< names of files to write
}; };
CALAMARES_PLUGIN_FACTORY_DECLARATION( MachineIdJobFactory ) CALAMARES_PLUGIN_FACTORY_DECLARATION( MachineIdJobFactory )

View File

@ -31,6 +31,7 @@ public:
private Q_SLOTS: private Q_SLOTS:
void initTestCase(); void initTestCase();
void testConfigEntropyFiles();
void testCopyFile(); void testCopyFile();
@ -45,6 +46,65 @@ MachineIdTests::initTestCase()
Logger::setupLogLevel( Logger::LOGDEBUG ); Logger::setupLogLevel( Logger::LOGDEBUG );
} }
void
MachineIdTests::testConfigEntropyFiles()
{
static QString urandom_entropy( "/var/lib/urandom/random-seed" );
// No config at all
{
QVariantMap m;
MachineIdJob j;
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList() );
}
// No entropy, deprecated setting
{
QVariantMap m;
MachineIdJob j;
m.insert( "entropy", false );
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList() );
}
// Entropy, deprecated setting
{
QVariantMap m;
MachineIdJob j;
m.insert( "entropy", true );
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList { urandom_entropy } );
}
// Duplicate entry, with deprecated setting
{
QVariantMap m;
MachineIdJob j;
m.insert( "entropy", true );
m.insert( "entropy-files", QStringList { urandom_entropy } );
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList { urandom_entropy } );
m.clear();
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList() );
// This would be weird
m.insert( "entropy", false );
m.insert( "entropy-files", QStringList { urandom_entropy } );
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames(), QStringList { urandom_entropy } );
}
// No deprecated setting
{
QString tmp_entropy( "/tmp/entropy" );
QVariantMap m;
MachineIdJob j;
m.insert( "entropy-files", QStringList { urandom_entropy, tmp_entropy } );
j.setConfigurationMap( m );
QVERIFY( !j.entropyFileNames().isEmpty() );
QCOMPARE( j.entropyFileNames(), QStringList() << urandom_entropy << tmp_entropy );
}
}
void void
MachineIdTests::testCopyFile() MachineIdTests::testCopyFile()
{ {
@ -100,6 +160,7 @@ MachineIdTests::testJob()
Logger::setupLogLevel( Logger::LOGDEBUG ); Logger::setupLogLevel( Logger::LOGDEBUG );
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
// Only clean up if the tests succeed
tempRoot.setAutoRemove( false ); tempRoot.setAutoRemove( false );
cDebug() << "Temporary files as" << QDir::tempPath(); cDebug() << "Temporary files as" << QDir::tempPath();
@ -158,6 +219,27 @@ MachineIdTests::testJob()
QCOMPARE( fi.size(), 5 ); QCOMPARE( fi.size(), 5 );
#endif #endif
} }
{
QString tmp_entropy2( "/pineapple.random" );
QString tmp_entropy( "/tmp/entropy" );
QVariantMap m;
MachineIdJob j;
m.insert( "entropy-files", QStringList { tmp_entropy2, tmp_entropy } );
m.insert( "entropy", true );
j.setConfigurationMap( m );
QCOMPARE( j.entropyFileNames().count(), 3 ); // Because of the standard entropy entry
// Check all three are created
auto r = j.exec();
QVERIFY( r );
for ( const auto& fileName : j.entropyFileNames() )
{
cDebug() << "Verifying existence of" << fileName;
QVERIFY( QFile::exists( tempRoot.filePath( fileName.mid( 1 ) ) ) );
}
}
tempRoot.setAutoRemove( true ); // All tests succeeded tempRoot.setAutoRemove( true ); // All tests succeeded
} }

View File

@ -19,7 +19,13 @@ dbus: true
# (ignored if dbus is false, or if there is no /etc/machine-id to point to). # (ignored if dbus is false, or if there is no /etc/machine-id to point to).
dbus-symlink: true dbus-symlink: true
# Whether to create an entropy file # Whether to create an entropy file /var/lib/urandom/random-seed
#
# DEPRECATED: list the file in entropy-files instead
entropy: false entropy: false
# Whether to copy entropy from the host # Whether to copy entropy from the host
entropy-copy: false entropy-copy: false
# Which files to write (paths in the target)
entropy-files:
- /var/lib/urandom/random-seed
- /var/lib/systemd/random-seed

View File

@ -9,7 +9,8 @@ properties:
systemd: { type: boolean, default: true } systemd: { type: boolean, default: true }
dbus: { type: boolean, default: true } dbus: { type: boolean, default: true }
"dbus-symlink": { type: boolean, default: true } "dbus-symlink": { type: boolean, default: true }
entropy: { type: boolean, default: false }
"entropy-copy": { type: boolean, default: false } "entropy-copy": { type: boolean, default: false }
"entropy-files": { type: array, items: { type: string } }
# Deprecated properties # Deprecated properties
symlink: { type: boolean, default: true } symlink: { type: boolean, default: true }
entropy: { type: boolean, default: false }