diff --git a/CHANGELOG b/CHANGELOG index ca3b10b82b..7865a11f9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ v3.3.22 (XXXX-XX-XX) -------------------- +* Added --server.jwt-secret-keyfile option. + * validate uniqueness of attribute names in AQL in cases in which it was not done before. When constructing AQL objects via object literals, there was no validation about object attribute names being unique. For example, it was @@ -37,7 +39,6 @@ v3.3.22 (XXXX-XX-XX) * fixed issue #7834: AQL Query crashes instance - v3.3.21 (2018-12-13) -------------------- diff --git a/arangod/GeneralServer/AuthenticationFeature.cpp b/arangod/GeneralServer/AuthenticationFeature.cpp index c818fed254..a65a23fd03 100644 --- a/arangod/GeneralServer/AuthenticationFeature.cpp +++ b/arangod/GeneralServer/AuthenticationFeature.cpp @@ -30,6 +30,8 @@ #include "ProgramOptions/ProgramOptions.h" #include "Random/RandomGenerator.h" #include "RestServer/QueryRegistryFeature.h" +#include "Basics/FileUtils.h" +#include "Basics/StringUtils.h" #if USE_ENTERPRISE #include "Enterprise/Ldap/LdapAuthenticationHandler.h" @@ -106,13 +108,39 @@ void AuthenticationFeature::collectOptions(std::shared_ptr optio new BooleanParameter(&_authenticationUnixSockets)); #endif + // Maybe deprecate this option in devel options->addOption("--server.jwt-secret", "secret to use when doing jwt authentication", new StringParameter(&_jwtSecretProgramOption)); + + options->addOption("--server.jwt-secret-keyfile", + "file containing jwt secret to use when doing jwt authentication.", + new StringParameter(&_jwtSecretKeyfileProgramOption)); } void AuthenticationFeature::validateOptions(std::shared_ptr) { - if (!_jwtSecretProgramOption.empty()) { + if (!_jwtSecretKeyfileProgramOption.empty()) { + + try { + // Note that the secret is trimmed for whitespace, because whitespace + // at the end of a file can easily happen. We do not base64-encode, + // though, so the bytes count as given. Zero bytes might be a problem + // here. + _jwtSecretProgramOption = basics::StringUtils::trim( + basics::FileUtils::slurp(_jwtSecretKeyfileProgramOption), + " \t\n\r"); + } catch (std::exception const& ex) { + LOG_TOPIC(FATAL, Logger::STARTUP) + << "unable to read content of jwt-secret file '" + << _jwtSecretKeyfileProgramOption << "': " << ex.what() + << ". please make sure the file/directory is readable for the " + "arangod process and user"; + FATAL_ERROR_EXIT(); + } + + } else if (!_jwtSecretProgramOption.empty()) { + LOG_TOPIC(WARN, arangodb::Logger::FIXME) + << "--server.jwt-secret is insecure. Use --server.jwt-secret-keyfile instead."; if (_jwtSecretProgramOption.length() > _maxSecretLength) { LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Given JWT secret too long. Max length is " << _maxSecretLength; diff --git a/arangod/GeneralServer/AuthenticationFeature.h b/arangod/GeneralServer/AuthenticationFeature.h index 17c184e9f1..68b50868e8 100644 --- a/arangod/GeneralServer/AuthenticationFeature.h +++ b/arangod/GeneralServer/AuthenticationFeature.h @@ -81,6 +81,7 @@ class AuthenticationFeature final : public application_features::ApplicationFeat bool _localAuthentication; std::string _jwtSecretProgramOption; + std::string _jwtSecretKeyfileProgramOption; bool _active; static AuthenticationFeature* INSTANCE;