diff options
-rw-r--r-- | hscript/meta.cc | 21 | ||||
-rw-r--r-- | hscript/meta.hh | 9 | ||||
-rw-r--r-- | hscript/script.cc | 18 | ||||
-rw-r--r-- | tests/fixtures/0186-signingkey-basic.installfile | 8 | ||||
-rw-r--r-- | tests/fixtures/0187-signingkey-local.installfile | 8 | ||||
-rw-r--r-- | tests/fixtures/0188-signingkey-insec.installfile | 8 | ||||
-rw-r--r-- | tests/spec/validator_spec.rb | 19 |
7 files changed, 89 insertions, 2 deletions
diff --git a/hscript/meta.cc b/hscript/meta.cc index 5885c1e..640743c 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -466,3 +466,24 @@ bool Repository::execute(ScriptOptions opts) const { return false; #endif /* HAS_INSTALL_ENV */ } + + +Key *SigningKey::parseFromData(const std::string &data, int lineno, + int *errors, int *) { + if(data.empty() || (data[0] != '/' && data.compare(0, 8, "https://"))) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "signingkey: must be absolute path or HTTPS URL"); + return nullptr; + } + + return new SigningKey(lineno, data); +} + +bool SigningKey::validate(ScriptOptions) const { + return true; +} + +bool SigningKey::execute(ScriptOptions) const { + return false; +} diff --git a/hscript/meta.hh b/hscript/meta.hh index dad4cf3..547349d 100644 --- a/hscript/meta.hh +++ b/hscript/meta.hh @@ -88,7 +88,14 @@ public: bool execute(ScriptOptions) const override; }; -class SigningKey : public Key { +class SigningKey : public StringKey { +private: + SigningKey(int _line, const std::string &_path) : + StringKey(_line, _path) {} +public: + static Key *parseFromData(const std::string &, int, int *, int *); + bool validate(ScriptOptions) const override; + bool execute(ScriptOptions) const override; }; } diff --git a/hscript/script.cc b/hscript/script.cc index 319ba14..ea083a8 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -173,6 +173,10 @@ struct Script::ScriptPrivate { std::unique_ptr<Repository> repo(dynamic_cast<Repository *>(obj)); this->repos.push_back(std::move(repo)); return true; + } else if(key_name == "signingkey") { + std::unique_ptr<SigningKey> key(dynamic_cast<SigningKey *>(obj)); + this->repo_keys.push_back(std::move(key)); + return true; } else if(key_name == "username") { return store_username(obj, lineno, errors, warnings, opts); } else if(key_name == "useralias") { @@ -808,7 +812,19 @@ bool Script::validate() const { "You may only specify up to 10 repositories."); } - /* signingkey */ + /* REQ: Runner.Validate.signingkey */ + for(auto &key : this->internal->repo_keys) { + if(!key->validate(this->opts)) { + failures++; + } + } + if(this->internal->repo_keys.size() > 10) { + failures++; + output_error("installfile:" + + std::to_string(this->internal->repo_keys[11]->lineno()), + "signingkey: too many keys specified", + "You may only specify up to 10 repository keys."); + } for(auto &acct : this->internal->accounts) { UserDetail *detail = acct.second.get(); diff --git a/tests/fixtures/0186-signingkey-basic.installfile b/tests/fixtures/0186-signingkey-basic.installfile new file mode 100644 index 0000000..c81ec32 --- /dev/null +++ b/tests/fixtures/0186-signingkey-basic.installfile @@ -0,0 +1,8 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +repository https://distfiles.adelielinux.org/adelie/current/system +repository https://distfiles.adelielinux.org/adelie/current/user +signingkey https://distfiles.adelielinux.org/adelie/packages@adelielinux.org.pub diff --git a/tests/fixtures/0187-signingkey-local.installfile b/tests/fixtures/0187-signingkey-local.installfile new file mode 100644 index 0000000..1af18b5 --- /dev/null +++ b/tests/fixtures/0187-signingkey-local.installfile @@ -0,0 +1,8 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +repository https://distfiles.adelielinux.org/adelie/current/system +repository https://distfiles.adelielinux.org/adelie/current/user +signingkey /etc/apk/keys/packages@adelielinux.org.pub diff --git a/tests/fixtures/0188-signingkey-insec.installfile b/tests/fixtures/0188-signingkey-insec.installfile new file mode 100644 index 0000000..185894d --- /dev/null +++ b/tests/fixtures/0188-signingkey-insec.installfile @@ -0,0 +1,8 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +repository https://distfiles.adelielinux.org/adelie/current/system +repository https://distfiles.adelielinux.org/adelie/current/user +signingkey http://distfiles.adelielinux.org/adelie/packages@adelielinux.org.pub diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb index 96a2caf..5c78f36 100644 --- a/tests/spec/validator_spec.rb +++ b/tests/spec/validator_spec.rb @@ -562,6 +562,25 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do expect(last_command_started).to have_output(/error: .*repository/) end end + context "for 'signingkey' key" do + it "succeeds with secure key URL" do + use_fixture '0186-signingkey-basic.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "succeeds with local key URL" do + use_fixture '0187-signingkey-local.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 insecure key URL" do + use_fixture '0188-signingkey-insec.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*signingkey/) + end + end context "for 'diskid' key" do it "succeeds with basic disk identification" do use_fixture '0076-diskid-basic.installfile' |