From d3489c52d4ad1e5b17ce88e8b0e5142b30bb324e Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 19 Oct 2019 01:43:15 -0500 Subject: hscript: Implement UserPassphrase, add tests --- hscript/script.cc | 9 +++++++++ hscript/user.cc | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 6 deletions(-) (limited to 'hscript') 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 { -- cgit v1.2.3-70-g09d2