1
0
Fork 0

Added --server.jwt-secret-keyfile to arangosh. (#9184)

This commit is contained in:
Lars Maier 2019-06-05 11:43:43 +02:00 committed by Jan
parent c87e15a048
commit d07ee8f7cf
3 changed files with 49 additions and 5 deletions

View File

@ -1,6 +1,8 @@
devel devel
----- -----
* Added --server.jwt-secret-keyfile to arangosh.
* fixed `Buffer.alloc` method * fixed `Buffer.alloc` method
* `Buffer` is now iterable and accepts `ArrayBuffer` values as input * `Buffer` is now iterable and accepts `ArrayBuffer` values as input

View File

@ -31,6 +31,7 @@
#include "SimpleHttpClient/GeneralClientConnection.h" #include "SimpleHttpClient/GeneralClientConnection.h"
#include "SimpleHttpClient/SimpleHttpClient.h" #include "SimpleHttpClient/SimpleHttpClient.h"
#include "Ssl/ssl-helper.h" #include "Ssl/ssl-helper.h"
#include "Basics/FileUtils.h"
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
@ -113,6 +114,16 @@ void ClientFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
"created", "created",
new BooleanParameter(&_askJwtSecret), new BooleanParameter(&_askJwtSecret),
arangodb::options::makeFlags(arangodb::options::Flags::Hidden)); arangodb::options::makeFlags(arangodb::options::Flags::Hidden));
options->addOption("--server.jwt-secret-keyfile",
"if this option is specified, the jwt secret will be loaded "
"from the given file. This option is not compatible with "
"--server.ask-jwt-secret, --server.username or --server.password. "
"If specified, it will be used for all "
"connections - even when a new connection to another server is "
"created",
new StringParameter(&_jwtSecretFile),
arangodb::options::makeFlags(arangodb::options::Flags::Hidden));
} }
options->addOption("--server.connection-timeout", options->addOption("--server.connection-timeout",
@ -160,6 +171,8 @@ void ClientFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
_authentication = false; _authentication = false;
} }
bool hasJwtSecretFile = !_jwtSecretFile.empty();
// check timeouts // check timeouts
if (_connectionTimeout < 0.0) { if (_connectionTimeout < 0.0) {
LOG_TOPIC("81598", FATAL, arangodb::Logger::FIXME) LOG_TOPIC("81598", FATAL, arangodb::Logger::FIXME)
@ -192,15 +205,21 @@ void ClientFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
_haveServerPassword = !options->processingResult().touched("server.password"); _haveServerPassword = !options->processingResult().touched("server.password");
if (_askJwtSecret && options->processingResult().touched("server.password")) { if ((_askJwtSecret || hasJwtSecretFile) && options->processingResult().touched("server.password")) {
LOG_TOPIC("65475", FATAL, arangodb::Logger::FIXME) LOG_TOPIC("65475", FATAL, arangodb::Logger::FIXME)
<< "cannot specify both --server.password and --server.ask-jwt-token"; << "cannot specify both --server.password and jwt secret source";
FATAL_ERROR_EXIT(); FATAL_ERROR_EXIT();
} }
if (_askJwtSecret && options->processingResult().touched("server.username")) { if ((_askJwtSecret || hasJwtSecretFile) && options->processingResult().touched("server.username")) {
LOG_TOPIC("9d886", FATAL, arangodb::Logger::FIXME) LOG_TOPIC("9d886", FATAL, arangodb::Logger::FIXME)
<< "cannot specify both --server.username and --server.ask-jwt-token"; << "cannot specify both --server.username and jwt secret source";
FATAL_ERROR_EXIT();
}
if (_askJwtSecret && hasJwtSecretFile) {
LOG_TOPIC("aeaeb", FATAL, arangodb::Logger::FIXME)
<< "multiple jwt secret sources specified";
FATAL_ERROR_EXIT(); FATAL_ERROR_EXIT();
} }
@ -245,6 +264,25 @@ void ClientFeature::readJwtSecret() {
std::cout << std::endl << std::flush; std::cout << std::endl << std::flush;
} }
void ClientFeature::loadJwtSecretFile() {
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.
_jwtSecret = basics::StringUtils::trim(
basics::FileUtils::slurp(_jwtSecretFile),
" \t\n\r");
} catch (std::exception const& ex) {
LOG_TOPIC("aeaec", FATAL, Logger::STARTUP)
<< "unable to read content of jwt-secret file '"
<< _jwtSecretFile << "': " << ex.what()
<< ". please make sure the file/directory is readable for the "
"arangod process and user";
FATAL_ERROR_EXIT();
}
}
void ClientFeature::prepare() { void ClientFeature::prepare() {
if (!isEnabled()) { if (!isEnabled()) {
return; return;
@ -253,6 +291,8 @@ void ClientFeature::prepare() {
if (_askJwtSecret) { if (_askJwtSecret) {
// ask for a jwt secret // ask for a jwt secret
readJwtSecret(); readJwtSecret();
} else if(!_jwtSecretFile.empty()) {
loadJwtSecretFile();
} else if (_authentication && _haveServerPassword) { } else if (_authentication && _haveServerPassword) {
// ask for a password // ask for a password
readPassword(); readPassword();

View File

@ -108,6 +108,7 @@ class ClientFeature final : public application_features::ApplicationFeature,
private: private:
void readPassword(); void readPassword();
void readJwtSecret(); void readJwtSecret();
void loadJwtSecretFile();
std::string _databaseName; std::string _databaseName;
bool _authentication; bool _authentication;
@ -116,6 +117,7 @@ class ClientFeature final : public application_features::ApplicationFeature,
std::string _username; std::string _username;
std::string _password; std::string _password;
std::string _jwtSecret; std::string _jwtSecret;
std::string _jwtSecretFile;
double _connectionTimeout; double _connectionTimeout;
double _requestTimeout; double _requestTimeout;
uint64_t _maxPacketSize; uint64_t _maxPacketSize;