summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/disk.cc31
-rw-r--r--hscript/disk.hh15
-rw-r--r--hscript/script.cc33
-rw-r--r--tests/fixtures/0189-encrypt-basic.installfile9
-rw-r--r--tests/fixtures/0190-encrypt-duplicate.installfile10
-rw-r--r--tests/fixtures/0191-encrypt-invalid.installfile9
-rw-r--r--tests/fixtures/0192-encrypt-pw.installfile9
-rw-r--r--tests/spec/validator_spec.rb24
8 files changed, 139 insertions, 1 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc
index 05fb6d2..ad253b3 100644
--- a/hscript/disk.cc
+++ b/hscript/disk.cc
@@ -233,6 +233,37 @@ bool DiskLabel::execute(ScriptOptions options) const {
}
+Key *Encrypt::parseFromData(const std::string &data, int lineno, int *errors,
+ int *) {
+ std::string::size_type sep = data.find(' ');
+ std::string dev, pass;
+
+ if(sep == std::string::npos) {
+ dev = data;
+ } else {
+ dev = data.substr(0, sep);
+ pass = data.substr(sep + 1);
+ }
+
+ if(dev.size() < 6 || dev.compare(0, 5, "/dev/")) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "encrypt: expected path to block device");
+ return nullptr;
+ }
+
+ return new Encrypt(lineno, dev, pass);
+}
+
+bool Encrypt::validate(ScriptOptions) const {
+ return true;
+}
+
+bool Encrypt::execute(ScriptOptions) const {
+ return false;
+}
+
+
/*! Parse a size string into a size and type.
* @param in_size (in) The string to parse.
* @param out_size (out) Where to which to write the size in bytes or %.
diff --git a/hscript/disk.hh b/hscript/disk.hh
index f3a8a4c..7722780 100644
--- a/hscript/disk.hh
+++ b/hscript/disk.hh
@@ -114,6 +114,21 @@ public:
};
class Encrypt : public Key {
+private:
+ const std::string _block;
+ const std::string _pw;
+
+ Encrypt(int _line, const std::string &_b, const std::string &_p) :
+ Key(_line), _block(_b), _pw(_p) {}
+public:
+ /*! Retrieve the block device that this key encrypts. */
+ const std::string device() const { return this->_block; }
+ /*! Retrieve the passphrase used to encrypt the block device. */
+ const std::string passphrase() const { return this->_pw; }
+
+ static Key *parseFromData(const std::string &, int, int*, int*);
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
class LVMPhysical : public StringKey {
diff --git a/hscript/script.cc b/hscript/script.cc
index ea083a8..cc819e4 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -123,6 +123,8 @@ struct Script::ScriptPrivate {
std::vector< std::unique_ptr<LVMGroup> > lvm_vgs;
/*! LVM logical volume keys */
std::vector< std::unique_ptr<LVMVolume> > lvm_lvs;
+ /*! LUKS creation keys */
+ std::vector< std::unique_ptr<Encrypt> > luks;
/*! Filesystem creation keys */
std::vector< std::unique_ptr<Filesystem> > fses;
/*! Target system's mountpoints. */
@@ -211,6 +213,10 @@ struct Script::ScriptPrivate {
std::unique_ptr<LVMVolume> lv(dynamic_cast<LVMVolume *>(obj));
this->lvm_lvs.push_back(std::move(lv));
return true;
+ } else if(key_name == "encrypt") {
+ std::unique_ptr<Encrypt> e(dynamic_cast<Encrypt *>(obj));
+ this->luks.push_back(std::move(e));
+ return true;
} else if(key_name == "fs") {
std::unique_ptr<Filesystem> fs(dynamic_cast<Filesystem *>(obj));
this->fses.push_back(std::move(fs));
@@ -706,7 +712,8 @@ bool add_default_repos(std::vector<std::unique_ptr<Keys::Repository>> &repos) {
bool Script::validate() const {
int failures = 0;
std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_pvs,
- seen_vg_names, seen_vg_pvs, seen_lvs, seen_fses, seen_mounts;
+ seen_vg_names, seen_vg_pvs, seen_lvs, seen_fses, seen_mounts,
+ seen_luks;
std::map<const std::string, int> seen_iface;
#ifdef HAS_INSTALL_ENV
error_code ec;
@@ -1004,6 +1011,30 @@ bool Script::validate() const {
" does not exist");\
}
+ /* REQ: Runner.Validate.encrypt */
+ for(auto &crypt : this->internal->luks) {
+ if(!crypt->validate(this->opts)) {
+ failures++;
+ continue;
+ }
+
+ /* REQ: Runner.Validate.encrypt.Unique */
+ if(seen_luks.find(crypt->device()) != seen_luks.end()) {
+ failures++;
+ output_error("installfile:" + std::to_string(crypt->lineno()),
+ "encrypt: encryption is already scheduled for " +
+ crypt->device());
+ }
+ seen_luks.insert(crypt->device());
+
+ /* REQ: Runner.Validate.encrypt.Block */
+ if(opts.test(InstallEnvironment)) {
+#ifdef HAS_INSTALL_ENV
+ CHECK_EXIST_PART_LV(crypt->device(), "encrypt", crypt->lineno())
+#endif /* HAS_INSTALL_ENV */
+ }
+ }
+
/* REQ: Runner.Validate.fs */
for(auto &fs : this->internal->fses) {
if(!fs->validate(this->opts)) {
diff --git a/tests/fixtures/0189-encrypt-basic.installfile b/tests/fixtures/0189-encrypt-basic.installfile
new file mode 100644
index 0000000..e198832
--- /dev/null
+++ b/tests/fixtures/0189-encrypt-basic.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+encrypt /dev/sdb1
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0190-encrypt-duplicate.installfile b/tests/fixtures/0190-encrypt-duplicate.installfile
new file mode 100644
index 0000000..72eafec
--- /dev/null
+++ b/tests/fixtures/0190-encrypt-duplicate.installfile
@@ -0,0 +1,10 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+encrypt /dev/sdb1
+encrypt /dev/sdb1
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0191-encrypt-invalid.installfile b/tests/fixtures/0191-encrypt-invalid.installfile
new file mode 100644
index 0000000..fc0c06f
--- /dev/null
+++ b/tests/fixtures/0191-encrypt-invalid.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+encrypt sdb1
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0192-encrypt-pw.installfile b/tests/fixtures/0192-encrypt-pw.installfile
new file mode 100644
index 0000000..29612e4
--- /dev/null
+++ b/tests/fixtures/0192-encrypt-pw.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+encrypt /dev/sdb1 shhsekrit
+mount /dev/sdb1 /
diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb
index 5c78f36..a9c5fd9 100644
--- a/tests/spec/validator_spec.rb
+++ b/tests/spec/validator_spec.rb
@@ -910,6 +910,30 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
expect(last_command_started).to have_output(/error: .*lvm_lv.*volume group/)
end
end
+ context "for 'encrypt' key" do
+ it "succeeds with a simple value" do
+ use_fixture '0189-encrypt-basic.installfile'
+ run_validate
+ expect(last_command_started).to have_output(PARSER_SUCCESS)
+ expect(last_command_started).to have_output(VALIDATOR_SUCCESS)
+ end
+ it "fails with a duplicate block device" do
+ use_fixture '0190-encrypt-duplicate.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*encrypt.*already/)
+ end
+ it "fails with an invalid block device" do
+ use_fixture '0191-encrypt-invalid.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*encrypt.*expected/)
+ end
+ it "succeeds with a passphrase" do
+ use_fixture '0192-encrypt-pw.installfile'
+ run_validate
+ expect(last_command_started).to have_output(PARSER_SUCCESS)
+ expect(last_command_started).to have_output(VALIDATOR_SUCCESS)
+ end
+ end
context "for 'fs' key" do
it "succeeds with a simple value" do
use_fixture '0179-fs-basic.installfile'