summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/script.cc9
-rw-r--r--hscript/user.cc43
-rw-r--r--tests/fixtures/0091-userpw-basic.installfile7
-rw-r--r--tests/fixtures/0092-userpw-without-pw.installfile7
-rw-r--r--tests/fixtures/0093-userpw-unknown-name.installfile8
-rw-r--r--tests/fixtures/0094-userpw-duplicate.installfile9
-rw-r--r--tests/fixtures/0095-userpw-plaintext.installfile7
-rw-r--r--tests/fixtures/0096-userpw-md5.installfile7
-rw-r--r--tests/fixtures/0097-userpw-missing.installfile6
-rw-r--r--tests/spec/validator.rb44
10 files changed, 141 insertions, 6 deletions
diff --git a/hscript/script.cc b/hscript/script.cc
index dd5e931..8dbf9e1 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -567,6 +567,15 @@ bool Script::validate() const {
failures++;
}
+ /* REQ: Runner.Validate.userpw.None */
+ if(!detail->passphrase) {
+ int line = detail->name->lineno();
+ output_warning("installfile:" + std::to_string(line),
+ "username: " + acct.first +
+ " has no set passphrase",
+ "This account will not be able to log in.");
+ }
+
/* REQ: Runner.Validate.usericon */
if(detail->icon && !detail->icon->validate(this->opts)) {
failures++;
diff --git a/hscript/user.cc b/hscript/user.cc
index 9bc6864..6081f55 100644
--- a/hscript/user.cc
+++ b/hscript/user.cc
@@ -100,14 +100,28 @@ static bool is_valid_name (const char *name)
/* End above copyright ^ */
+/*! Determine if a string is a valid crypt passphrase
+ * @param pw The string to test for validity.
+ * @param key The name of key being validated ('rootpw', 'userpw', ...)
+ * @param lineno The line number where the key occurs.
+ * @returns true if +pw+ is a valid crypt passphrase; false otherwise.
+ */
+static bool string_is_crypt(const std::string &pw, const std::string &key,
+ int lineno) {
+ if(pw.size() < 5 || pw[0] != '$' || (pw[1] != '2' && pw[1] != '6')
+ || pw[2] != '$') {
+ output_error("installfile:" + std::to_string(lineno),
+ key + ": value is not a crypt-style encrypted passphrase");
+ return false;
+ }
+ return true;
+}
+
Key *RootPassphrase::parseFromData(const std::string &data, int lineno,
int *errors, int *warnings) {
- if(data.size() < 5 || data[0] != '$' || (data[1] != '2' && data[1] != '6')
- || data[2] != '$') {
+ if(!string_is_crypt(data, "rootpw", lineno)) {
if(errors) *errors += 1;
- output_error("installfile:" + std::to_string(lineno),
- "rootpw: value is not a crypt-style encrypted passphrase");
return nullptr;
}
return new RootPassphrase(lineno, data);
@@ -219,11 +233,28 @@ bool UserAlias::execute(ScriptOptions) const {
Key *UserPassphrase::parseFromData(const std::string &data, int lineno,
int *errors, int *warnings) {
- return nullptr;
+ /* REQ: Runner.Validate.userpw.Validity */
+ const std::string::size_type sep = data.find_first_of(' ');
+ if(sep == std::string::npos || data.length() == sep + 1) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "userpw: passphrase is required",
+ "expected format is: userpw [username] [crypt...]");
+ return nullptr;
+ }
+
+ std::string passphrase = data.substr(sep + 1);
+ if(!string_is_crypt(passphrase, "userpw", lineno)) {
+ if(errors) *errors += 1;
+ return nullptr;
+ }
+
+ return new UserPassphrase(lineno, data.substr(0, sep), data.substr(sep + 1));
}
bool UserPassphrase::validate(ScriptOptions) const {
- return false;
+ /* If it's parseable, it's valid. */
+ return true;
}
bool UserPassphrase::execute(ScriptOptions) const {
diff --git a/tests/fixtures/0091-userpw-basic.installfile b/tests/fixtures/0091-userpw-basic.installfile
new file mode 100644
index 0000000..2c3e842
--- /dev/null
+++ b/tests/fixtures/0091-userpw-basic.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+userpw awilfox $6$UZJm/vBmVgyIdMZr$ppKEulz/HY0/e7RcXXujQbcqDXkUYgIqNEVPQJO6.le9kUpz8GvvRezY3ifqUUEwjhSo9tTOMG7lhqjn8gGpH0
diff --git a/tests/fixtures/0092-userpw-without-pw.installfile b/tests/fixtures/0092-userpw-without-pw.installfile
new file mode 100644
index 0000000..9b2b524
--- /dev/null
+++ b/tests/fixtures/0092-userpw-without-pw.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+userpw awilfox
diff --git a/tests/fixtures/0093-userpw-unknown-name.installfile b/tests/fixtures/0093-userpw-unknown-name.installfile
new file mode 100644
index 0000000..285a6a0
--- /dev/null
+++ b/tests/fixtures/0093-userpw-unknown-name.installfile
@@ -0,0 +1,8 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+# Intentional misspelling
+userpw awilcox $6$UZJm/vBmVgyIdMZr$ppKEulz/HY0/e7RcXXujQbcqDXkUYgIqNEVPQJO6.le9kUpz8GvvRezY3ifqUUEwjhSo9tTOMG7lhqjn8gGpH0
diff --git a/tests/fixtures/0094-userpw-duplicate.installfile b/tests/fixtures/0094-userpw-duplicate.installfile
new file mode 100644
index 0000000..6416c6f
--- /dev/null
+++ b/tests/fixtures/0094-userpw-duplicate.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+# Intentional duplication
+userpw awilfox $6$UZJm/vBmVgyIdMZr$ppKEulz/HY0/e7RcXXujQbcqDXkUYgIqNEVPQJO6.le9kUpz8GvvRezY3ifqUUEwjhSo9tTOMG7lhqjn8gGpH0
+userpw awilfox $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
diff --git a/tests/fixtures/0095-userpw-plaintext.installfile b/tests/fixtures/0095-userpw-plaintext.installfile
new file mode 100644
index 0000000..c0dce02
--- /dev/null
+++ b/tests/fixtures/0095-userpw-plaintext.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+userpw awilfox Password123
diff --git a/tests/fixtures/0096-userpw-md5.installfile b/tests/fixtures/0096-userpw-md5.installfile
new file mode 100644
index 0000000..79009bc
--- /dev/null
+++ b/tests/fixtures/0096-userpw-md5.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+userpw awilfox $1$5f4dcc3b5aa765d61d8327deb882cf99
diff --git a/tests/fixtures/0097-userpw-missing.installfile b/tests/fixtures/0097-userpw-missing.installfile
new file mode 100644
index 0000000..3811133
--- /dev/null
+++ b/tests/fixtures/0097-userpw-missing.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
diff --git a/tests/spec/validator.rb b/tests/spec/validator.rb
index 7fd8356..76f1c6f 100644
--- a/tests/spec/validator.rb
+++ b/tests/spec/validator.rb
@@ -568,6 +568,50 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
expect(last_command_started).to have_output(/error: .*duplicate.*useralias/)
end
end
+ context "'userpw'" do
+ # Runner.Validate.userpw.
+ it "succeeds with username/passphrase combinations" do
+ use_fixture '0091-userpw-basic.installfile'
+ run_validate
+ expect(last_command_started).to have_output(PARSER_SUCCESS)
+ expect(last_command_started).to have_output(VALIDATOR_SUCCESS)
+ end
+ # Runner.Validate.userpw.Validity.
+ it "requires a passphrase to be provided" do
+ use_fixture '0092-userpw-without-pw.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*userpw.*required/)
+ end
+ # Runner.Validate.userpw.Name.
+ it "fails with a username that wasn't given" do
+ use_fixture '0093-userpw-unknown-name.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*userpw.*name/)
+ end
+ # Runner.Validate.userpw.Unique.
+ it "fails with more than one passphrase for an account" do
+ use_fixture '0094-userpw-duplicate.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*duplicate.*userpw/)
+ end
+ # Runner.Validate.userpw.Crypt.
+ it "fails with a plain-text password" do
+ use_fixture '0095-userpw-plaintext.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*userpw.*crypt/)
+ end
+ it "fails with an invalid encryption algorithm" do
+ use_fixture '0096-userpw-md5.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*userpw.*crypt/)
+ end
+ # Runner.Validate.userpw.None.
+ it "warns when an account doesn't have a passphrase" do
+ use_fixture '0097-userpw-missing.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/warning: .*passphrase/)
+ end
+ end
end
context "package specifications" do
# no requirements for these, but I think obvious.