diff --git a/CHANGES b/CHANGES index 38caac6cb..13dd3d779 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,11 @@ This release contains contributions from (alphabetically by first name): - The *keyboard* module now recognizes Turkish "F" layout and will set the vconsole keyboard layout correctly even if xkb 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) # diff --git a/src/modules/machineid/MachineIdJob.cpp b/src/modules/machineid/MachineIdJob.cpp index 302e8c308..8a33288b9 100644 --- a/src/modules/machineid/MachineIdJob.cpp +++ b/src/modules/machineid/MachineIdJob.cpp @@ -57,14 +57,13 @@ MachineIdJob::exec() QString target_systemd_machineid_file = QStringLiteral( "/etc/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(); // 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 ) { @@ -76,12 +75,18 @@ MachineIdJob::exec() } //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
%1
." ).arg( entropy_file ) ); + } auto r = MachineId::createEntropy( m_entropy_copy ? MachineId::EntropyGeneration::CopyFromHost : MachineId::EntropyGeneration::New, root, - target_entropy_file ); + entropy_file ); if ( !r ) { return r; @@ -89,6 +94,10 @@ MachineIdJob::exec() } 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 ); if ( !r ) { @@ -143,8 +152,19 @@ MachineIdJob::setConfigurationMap( const QVariantMap& map ) // ignore it, though, if dbus is false 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_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 >(); ) diff --git a/src/modules/machineid/MachineIdJob.h b/src/modules/machineid/MachineIdJob.h index b58d2f4dd..136f28ecb 100644 --- a/src/modules/machineid/MachineIdJob.h +++ b/src/modules/machineid/MachineIdJob.h @@ -11,6 +11,7 @@ #define MACHINEIDJOB_H #include +#include #include #include "CppJob.h" @@ -19,6 +20,9 @@ #include "DllMacro.h" +/** @brief Write 'random' data: machine id, entropy, UUIDs + * + */ class PLUGINDLLEXPORT MachineIdJob : public Calamares::CppJob { Q_OBJECT @@ -33,14 +37,22 @@ public: 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: bool m_systemd = false; ///< write systemd's files bool m_dbus = false; ///< write dbus files 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 + QStringList m_entropy_files; ///< names of files to write }; CALAMARES_PLUGIN_FACTORY_DECLARATION( MachineIdJobFactory ) diff --git a/src/modules/machineid/Tests.cpp b/src/modules/machineid/Tests.cpp index 45f0e6954..13cce3de7 100644 --- a/src/modules/machineid/Tests.cpp +++ b/src/modules/machineid/Tests.cpp @@ -31,6 +31,7 @@ public: private Q_SLOTS: void initTestCase(); + void testConfigEntropyFiles(); void testCopyFile(); @@ -45,6 +46,65 @@ MachineIdTests::initTestCase() 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 MachineIdTests::testCopyFile() { @@ -100,6 +160,7 @@ MachineIdTests::testJob() Logger::setupLogLevel( Logger::LOGDEBUG ); QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + // Only clean up if the tests succeed tempRoot.setAutoRemove( false ); cDebug() << "Temporary files as" << QDir::tempPath(); @@ -158,6 +219,27 @@ MachineIdTests::testJob() QCOMPARE( fi.size(), 5 ); #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 } diff --git a/src/modules/machineid/machineid.conf b/src/modules/machineid/machineid.conf index 5ebf17c8c..c6189e598 100644 --- a/src/modules/machineid/machineid.conf +++ b/src/modules/machineid/machineid.conf @@ -19,7 +19,13 @@ dbus: true # (ignored if dbus is false, or if there is no /etc/machine-id to point to). 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 # Whether to copy entropy from the host entropy-copy: false +# Which files to write (paths in the target) +entropy-files: + - /var/lib/urandom/random-seed + - /var/lib/systemd/random-seed diff --git a/src/modules/machineid/machineid.schema.yaml b/src/modules/machineid/machineid.schema.yaml index 8b84f1d22..1ae67e132 100644 --- a/src/modules/machineid/machineid.schema.yaml +++ b/src/modules/machineid/machineid.schema.yaml @@ -9,7 +9,8 @@ properties: systemd: { type: boolean, default: true } dbus: { type: boolean, default: true } "dbus-symlink": { type: boolean, default: true } - entropy: { type: boolean, default: false } "entropy-copy": { type: boolean, default: false } + "entropy-files": { type: array, items: { type: string } } # Deprecated properties symlink: { type: boolean, default: true } + entropy: { type: boolean, default: false }