summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-18 23:18:12 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-18 23:18:12 -0500
commitda01034909eba11be184cedb408f34732a33c4cd (patch)
treebc75474a59515f33ada34377c2e12e92bfd5e048
parent72ca6added88259f9b456810bdd7300c2037b23c (diff)
downloadhorizon-da01034909eba11be184cedb408f34732a33c4cd.tar.gz
horizon-da01034909eba11be184cedb408f34732a33c4cd.tar.bz2
horizon-da01034909eba11be184cedb408f34732a33c4cd.tar.xz
horizon-da01034909eba11be184cedb408f34732a33c4cd.zip
hscript: Implement username validity check and UserAlias code; add tests
-rw-r--r--hscript/user.cc79
-rw-r--r--tests/fixtures/0067-netssid-spaces-wpa.installfile2
-rw-r--r--tests/fixtures/0086-username-invalid.installfile6
-rw-r--r--tests/fixtures/0087-useralias-basic.installfile15
-rw-r--r--tests/fixtures/0088-useralias-without-alias.installfile7
-rw-r--r--tests/fixtures/0089-useralias-unknown-name.installfile8
-rw-r--r--tests/fixtures/0090-useralias-duplicate.installfile9
-rw-r--r--tests/spec/validator.rb32
8 files changed, 154 insertions, 4 deletions
diff --git a/hscript/user.cc b/hscript/user.cc
index 33f9789..8382f1c 100644
--- a/hscript/user.cc
+++ b/hscript/user.cc
@@ -38,6 +38,69 @@ const static std::set<std::string> system_groups = {
"qmaill", "smmsp", "locate", "abuild", "utmp", "ping", "nogroup", "nobody"
};
+
+/*
+ * is_valid_name is from shadow libmisc/chkname.c:
+ *
+ * Copyright (c) 1990 - 1994, Julianne Frances Haugh
+ * Copyright (c) 1996 - 2000, Marek Michałkiewicz
+ * Copyright (c) 2001 - 2005, Tomasz Kłoczko
+ * Copyright (c) 2005 - 2008, Nicolas François
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the copyright holders or contributors may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+static bool is_valid_name (const char *name)
+{
+ /*
+ * User/group names must match [a-z_][a-z0-9_-]*[$]
+ */
+ if (('\0' == *name) ||
+ !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
+ return false;
+ }
+
+ while ('\0' != *++name) {
+ if (!(( ('a' <= *name) && ('z' >= *name) ) ||
+ ( ('0' <= *name) && ('9' >= *name) ) ||
+ ('_' == *name) ||
+ ('-' == *name) ||
+ ('.' == *name) ||
+ ( ('$' == *name) && ('\0' == *(name + 1)) )
+ )) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* End above copyright ^ */
+
+
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')
@@ -107,7 +170,7 @@ bool RootPassphrase::execute(ScriptOptions options) const {
Key *Username::parseFromData(const std::string &data, int lineno, int *errors,
int *warnings) {
- if(data.find_first_of(' ') != std::string::npos) {
+ if(!is_valid_name(data.c_str())) {
if(errors) *errors += 1;
output_error("installfile:" + std::to_string(lineno),
"username: invalid username specified");
@@ -132,11 +195,21 @@ bool Username::execute(ScriptOptions) const {
Key *UserAlias::parseFromData(const std::string &data, int lineno, int *errors,
int *warnings) {
- return nullptr;
+ /* REQ: Runner.Validate.useralias.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),
+ "useralias: alias is required",
+ "expected format is: useralias [username] [alias...]");
+ return nullptr;
+ }
+
+ return new UserAlias(lineno, data.substr(0, sep), data.substr(sep + 1));
}
bool UserAlias::validate(ScriptOptions) const {
- return false;
+ return true;
}
bool UserAlias::execute(ScriptOptions) const {
diff --git a/tests/fixtures/0067-netssid-spaces-wpa.installfile b/tests/fixtures/0067-netssid-spaces-wpa.installfile
index e74f34c..fecebf7 100644
--- a/tests/fixtures/0067-netssid-spaces-wpa.installfile
+++ b/tests/fixtures/0067-netssid-spaces-wpa.installfile
@@ -1,5 +1,5 @@
network false
-hostname test.machine
+hostname my.test.machine
pkginstall adelie-base
rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
mount /dev/sda1 /
diff --git a/tests/fixtures/0086-username-invalid.installfile b/tests/fixtures/0086-username-invalid.installfile
new file mode 100644
index 0000000..3605860
--- /dev/null
+++ b/tests/fixtures/0086-username-invalid.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username 1AWilcox
diff --git a/tests/fixtures/0087-useralias-basic.installfile b/tests/fixtures/0087-useralias-basic.installfile
new file mode 100644
index 0000000..bb3a0e5
--- /dev/null
+++ b/tests/fixtures/0087-useralias-basic.installfile
@@ -0,0 +1,15 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username chris
+useralias chris Christopher
+username kayla
+useralias kayla Kayla
+username meg
+useralias meg Meaghan
+username steph
+useralias steph Stephanie
+username amanda
+useralias amanda Amanda Jane
diff --git a/tests/fixtures/0088-useralias-without-alias.installfile b/tests/fixtures/0088-useralias-without-alias.installfile
new file mode 100644
index 0000000..f269e2e
--- /dev/null
+++ b/tests/fixtures/0088-useralias-without-alias.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+username awilfox
+useralias awilfox
diff --git a/tests/fixtures/0089-useralias-unknown-name.installfile b/tests/fixtures/0089-useralias-unknown-name.installfile
new file mode 100644
index 0000000..b3b6d55
--- /dev/null
+++ b/tests/fixtures/0089-useralias-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 to trigger error
+useralias awilcox A. Wilcox
diff --git a/tests/fixtures/0090-useralias-duplicate.installfile b/tests/fixtures/0090-useralias-duplicate.installfile
new file mode 100644
index 0000000..5426abe
--- /dev/null
+++ b/tests/fixtures/0090-useralias-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
+useralias awilfox A. Wilcox
+useralias awilfox A. Wilcox
diff --git a/tests/spec/validator.rb b/tests/spec/validator.rb
index 2fa9c89..7fd8356 100644
--- a/tests/spec/validator.rb
+++ b/tests/spec/validator.rb
@@ -535,6 +535,38 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
run_validate
expect(last_command_started).to have_output(/error: .*username.*too many/)
end
+ it "fails with an invalid username" do
+ use_fixture '0086-username-invalid.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*username.*invalid/)
+ end
+ end
+ context "'useralias'" do
+ # Runner.Validate.useralias.
+ it "succeeds with usernames with aliases" do
+ use_fixture '0087-useralias-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.useralias.Validity.
+ it "requires an alias to be provided" do
+ use_fixture '0088-useralias-without-alias.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*useralias.*required/)
+ end
+ # Runner.Validate.useralias.Name.
+ it "fails with a username that wasn't given" do
+ use_fixture '0089-useralias-unknown-name.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*useralias.*name/)
+ end
+ # Runner.Validate.useralias.Unique.
+ it "fails with a duplicated alias" do
+ use_fixture '0090-useralias-duplicate.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*duplicate.*useralias/)
+ end
end
end
context "package specifications" do