mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
11f2afad44
|
@ -89,22 +89,17 @@ endif ()
|
|||
set(SKIP_INSTALL_ALL ON)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/zlib/zlib-1.2.8)
|
||||
|
||||
################################################################################
|
||||
## SNAPPY
|
||||
################################################################################
|
||||
|
||||
|
||||
################################################################################
|
||||
## ROCKSDB
|
||||
################################################################################
|
||||
|
||||
if (USE_ROCKSDB)
|
||||
if (${JEMALLOC_FOUND})
|
||||
# set(USE_JEMALLOC_DEFAULT 1)
|
||||
# set(USE_JEMALLOC_DEFAULT 1)
|
||||
endif()
|
||||
set(SKIP_INSTALL_ALL ON)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/snappy/google-snappy-d53de18)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/rocksdb/)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/rocksdb)
|
||||
endif ()
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -364,6 +364,11 @@ else ()
|
|||
set(V8_CXXFLAGS "$ENV{V8_CXXFLAGS}")
|
||||
set(V8_LDFLAGS "$ENV{V8_LDFLAGS}")
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
set(V8_CFLAGS "${V8_CFLAGS} -fno-delete-null-pointer-checks")
|
||||
set(V8_CXXFLAGS "${V8_CXXFLAGS} -fno-delete-null-pointer-checks")
|
||||
endif ()
|
||||
|
||||
if (USE_DEBUG_V8)
|
||||
set(V8_TARGET_ARCH "${V8_PROC_ARCH}.debug")
|
||||
else ()
|
||||
|
|
|
@ -155,11 +155,12 @@ option(USE_ROCKSDB
|
|||
|
||||
if (USE_ROCKSDB)
|
||||
add_definitions("-DARANGODB_ENABLE_ROCKSDB=1")
|
||||
add_definitions(-DARANGODB_ROCKSDB_VERSION=\"${ROCKSDB_VERSION}\")
|
||||
include_directories(${ROCKSDB_INCLUDE_DIR})
|
||||
else ()
|
||||
set(ROCKSDB_LIBS "")
|
||||
endif ()
|
||||
|
||||
|
||||
################################################################################
|
||||
## EXTERNAL PROGRAMS
|
||||
################################################################################
|
||||
|
@ -670,15 +671,6 @@ endif ()
|
|||
include_directories(${Boost_INCLUDE_DIR})
|
||||
add_definitions(-DARANGODB_BOOST_VERSION=\"${Boost_VERSION}\")
|
||||
|
||||
################################################################################
|
||||
## ROCKSDB
|
||||
################################################################################
|
||||
|
||||
if (USE_ROCKSDB)
|
||||
include_directories(${ROCKSDB_INCLUDE_DIR})
|
||||
add_definitions(-DARANGODB_ROCKSDB_VERSION=\"${ROCKSDB_VERSION}\")
|
||||
endif ()
|
||||
|
||||
################################################################################
|
||||
## ICU
|
||||
################################################################################
|
||||
|
@ -799,7 +791,6 @@ endif ()
|
|||
list(INSERT SYSTEM_LIBRARIES 0
|
||||
${BT_LIBS}
|
||||
${ZLIB_LIBS}
|
||||
${SNAPPY_LIBS}
|
||||
${ICU_LIBS}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${BASE_LIBS}
|
||||
|
|
|
@ -43,7 +43,7 @@ inline void makeReport (query_t& envelope, Builder const& report) {
|
|||
envelope->close();
|
||||
}
|
||||
|
||||
template<> struct Job<FAILED_LEADER> {
|
||||
template<> struct Job<arangodb::consensus::FAILED_LEADER> {
|
||||
|
||||
Job (Node const& snapshot, Agent* agent, uint64_t jobId,
|
||||
std::string const& failed) {
|
||||
|
|
|
@ -47,7 +47,7 @@ struct JobCallback {
|
|||
};
|
||||
|
||||
enum JOB_CASE {FAILED_LEADER};
|
||||
template<enum JOB_CASE> struct Job {};
|
||||
template<enum arangodb::consensus::JOB_CASE> struct Job {};
|
||||
|
||||
struct check_t {
|
||||
bool good;
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#include "RestServer/QueryRegistryFeature.h"
|
||||
#include "RestServer/ServerFeature.h"
|
||||
#include "Scheduler/SchedulerFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
#include "Ssl/SslServerFeature.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/server.h"
|
||||
|
||||
|
@ -250,8 +250,8 @@ void RestServerFeature::buildServers() {
|
|||
|
||||
// ssl endpoints
|
||||
if (endpointList.hasSsl()) {
|
||||
SslFeature* ssl =
|
||||
application_features::ApplicationServer::getFeature<SslFeature>("Ssl");
|
||||
SslServerFeature* ssl =
|
||||
application_features::ApplicationServer::getFeature<SslServerFeature>("SslServer");
|
||||
|
||||
// check the ssl context
|
||||
if (ssl->sslContext() == nullptr) {
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "RestServer/UpgradeFeature.h"
|
||||
#include "Scheduler/SchedulerFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
#include "Ssl/SslServerFeature.h"
|
||||
#include "Statistics/StatisticsFeature.h"
|
||||
#include "V8Server/FoxxQueuesFeature.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
@ -136,7 +137,7 @@ static int runServer(int argc, char** argv) {
|
|||
"Cluster", "Daemon", "Dispatcher",
|
||||
"Endpoint", "FoxxQueues", "LoggerBufferFeature",
|
||||
"RestServer", "Server", "Scheduler",
|
||||
"Ssl", "Statistics", "Supervisor"};
|
||||
"SslServer", "Statistics", "Supervisor"};
|
||||
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
|
@ -173,6 +174,7 @@ static int runServer(int argc, char** argv) {
|
|||
server.addFeature(new ServerFeature(&server, &ret));
|
||||
server.addFeature(new ShutdownFeature(&server, {"UnitTests", "Script"}));
|
||||
server.addFeature(new SslFeature(&server));
|
||||
server.addFeature(new SslServerFeature(&server));
|
||||
server.addFeature(new StatisticsFeature(&server));
|
||||
server.addFeature(new TempFeature(&server, name));
|
||||
server.addFeature(new UnitTestsFeature(&server, &ret));
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "Logger/LoggerFeature.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "Random/RandomFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::application_features;
|
||||
|
@ -56,6 +57,7 @@ int main(int argc, char* argv[]) {
|
|||
server.addFeature(new LoggerFeature(&server, false));
|
||||
server.addFeature(new RandomFeature(&server));
|
||||
server.addFeature(new ShutdownFeature(&server, {"Bench"}));
|
||||
server.addFeature(new SslFeature(&server));
|
||||
server.addFeature(new TempFeature(&server, "arangobench"));
|
||||
server.addFeature(new VersionFeature(&server));
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Logger/LoggerFeature.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "Random/RandomFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::application_features;
|
||||
|
@ -53,6 +54,7 @@ int main(int argc, char* argv[]) {
|
|||
server.addFeature(new LoggerFeature(&server, false));
|
||||
server.addFeature(new RandomFeature(&server));
|
||||
server.addFeature(new ShutdownFeature(&server, {"Dump"}));
|
||||
server.addFeature(new SslFeature(&server));
|
||||
server.addFeature(new VersionFeature(&server));
|
||||
|
||||
try {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "Logger/LoggerFeature.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "Random/RandomFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::application_features;
|
||||
|
@ -54,6 +55,7 @@ int main(int argc, char* argv[]) {
|
|||
server.addFeature(new LoggerFeature(&server, false));
|
||||
server.addFeature(new RandomFeature(&server));
|
||||
server.addFeature(new ShutdownFeature(&server, {"Import"}));
|
||||
server.addFeature(new SslFeature(&server));
|
||||
server.addFeature(new TempFeature(&server, "arangoimp"));
|
||||
server.addFeature(new VersionFeature(&server));
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "Random/RandomFeature.h"
|
||||
#include "Shell/ShellFeature.h"
|
||||
#include "Shell/V8ShellFeature.h"
|
||||
#include "Ssl/SslFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::application_features;
|
||||
|
@ -62,6 +63,7 @@ int main(int argc, char* argv[]) {
|
|||
server.addFeature(new RandomFeature(&server));
|
||||
server.addFeature(new ShellFeature(&server, &ret));
|
||||
server.addFeature(new ShutdownFeature(&server, {"Shell"}));
|
||||
server.addFeature(new SslFeature(&server));
|
||||
server.addFeature(new TempFeature(&server, name));
|
||||
server.addFeature(new V8PlatformFeature(&server));
|
||||
server.addFeature(new V8ShellFeature(&server, name));
|
||||
|
|
|
@ -215,6 +215,7 @@ add_library(${LIB_ARANGO} STATIC
|
|||
SimpleHttpClient/SslClientConnection.cpp
|
||||
Ssl/SslFeature.cpp
|
||||
Ssl/SslInterface.cpp
|
||||
Ssl/SslServerFeature.cpp
|
||||
Ssl/ssl-helper.cpp
|
||||
Utilities/LineEditor.cpp
|
||||
Utilities/ScriptLoader.cpp
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
|
||||
#include "SslFeature.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define OPENSSL_THREAD_DEFINES
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
|
@ -133,55 +130,12 @@ void opensslCleanup() {
|
|||
}
|
||||
|
||||
SslFeature::SslFeature(application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "Ssl"),
|
||||
_cafile(),
|
||||
_keyfile(),
|
||||
_sessionCache(false),
|
||||
_cipherList(),
|
||||
_protocol(TLS_V1),
|
||||
_options(
|
||||
(long)(SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_CIPHER_SERVER_PREFERENCE)),
|
||||
_ecdhCurve("prime256v1"),
|
||||
_sslContext(nullptr) {
|
||||
: ApplicationFeature(server, "Ssl") {
|
||||
setOptional(true);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Logger");
|
||||
}
|
||||
|
||||
void SslFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
options->addSection("ssl", "Configure SSL communication");
|
||||
|
||||
options->addOption("--ssl.cafile", "ca file used for secure connections",
|
||||
new StringParameter(&_cafile));
|
||||
|
||||
options->addOption("--ssl.keyfile", "key-file used for secure connections",
|
||||
new StringParameter(&_keyfile));
|
||||
|
||||
options->addOption("--ssl.session-cache",
|
||||
"enable the session cache for connections",
|
||||
new BooleanParameter(&_sessionCache));
|
||||
|
||||
options->addOption("--ssl.chipher-list",
|
||||
"ssl chipers to use, see OpenSSL documentation",
|
||||
new StringParameter(&_cipherList));
|
||||
|
||||
std::unordered_set<uint64_t> sslProtocols = {1, 2, 3, 4};
|
||||
|
||||
options->addOption("--ssl.protocol",
|
||||
"ssl protocol (1 = SSLv2, 2 = SSLv23, 3 = SSLv3, 4 = "
|
||||
"TLSv1, 5 = TLSV1.2 (recommended)",
|
||||
new UInt64Parameter(&_protocol));
|
||||
|
||||
options->addHiddenOption(
|
||||
"--ssl.options", "ssl connection options, see OpenSSL documentation",
|
||||
new DiscreteValuesParameter<UInt64Parameter>(&_options, sslProtocols));
|
||||
|
||||
options->addOption(
|
||||
"--ssl.ecdh-curve",
|
||||
"SSL ECDH Curve, see the output of \"openssl ecparam -list_curves\"",
|
||||
new StringParameter(&_ecdhCurve));
|
||||
}
|
||||
|
||||
void SslFeature::prepare() {
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
@ -189,411 +143,12 @@ void SslFeature::prepare() {
|
|||
ERR_load_crypto_strings();
|
||||
|
||||
opensslSetup();
|
||||
|
||||
createSslContext();
|
||||
}
|
||||
|
||||
void SslFeature::start() {
|
||||
LOG(INFO) << "using SSL options: " << stringifySslOptions(_options);
|
||||
|
||||
if (!_cipherList.empty()) {
|
||||
LOG(INFO) << "using SSL cipher-list '" << _cipherList << "'";
|
||||
}
|
||||
}
|
||||
|
||||
void SslFeature::stop() {
|
||||
if (_sslContext != nullptr) {
|
||||
SSL_CTX_free(_sslContext);
|
||||
_sslContext = nullptr;
|
||||
}
|
||||
|
||||
opensslCleanup();
|
||||
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
}
|
||||
|
||||
namespace {
|
||||
class BIOGuard {
|
||||
public:
|
||||
explicit BIOGuard(BIO* bio) : _bio(bio) {}
|
||||
|
||||
~BIOGuard() { BIO_free(_bio); }
|
||||
|
||||
public:
|
||||
BIO* _bio;
|
||||
};
|
||||
}
|
||||
|
||||
void SslFeature::createSslContext() {
|
||||
// check keyfile
|
||||
if (_keyfile.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// validate protocol
|
||||
if (_protocol <= SSL_UNKNOWN || _protocol >= SSL_LAST) {
|
||||
LOG(FATAL) << "invalid SSL protocol version specified. Please use a valid "
|
||||
"value for '--ssl.protocol.'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "using SSL protocol version '"
|
||||
<< protocolName((protocol_e)_protocol) << "'";
|
||||
|
||||
if (!FileUtils::exists(_keyfile)) {
|
||||
LOG(FATAL) << "unable to find SSL keyfile '" << _keyfile << "'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// create context
|
||||
_sslContext = ::sslContext(protocol_e(_protocol), _keyfile);
|
||||
|
||||
if (_sslContext == nullptr) {
|
||||
LOG(FATAL) << "failed to create SSL context, cannot create HTTPS server";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// set cache mode
|
||||
SSL_CTX_set_session_cache_mode(
|
||||
_sslContext, _sessionCache ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_OFF);
|
||||
|
||||
if (_sessionCache) {
|
||||
LOG(TRACE) << "using SSL session caching";
|
||||
}
|
||||
|
||||
// set options
|
||||
SSL_CTX_set_options(_sslContext, (long)_options);
|
||||
|
||||
if (!_cipherList.empty()) {
|
||||
if (SSL_CTX_set_cipher_list(_sslContext, _cipherList.c_str()) != 1) {
|
||||
LOG(FATAL) << "cannot set SSL cipher list '" << _cipherList
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
|
||||
int sslEcdhNid;
|
||||
EC_KEY* ecdhKey;
|
||||
sslEcdhNid = OBJ_sn2nid(_ecdhCurve.c_str());
|
||||
|
||||
if (sslEcdhNid == 0) {
|
||||
LOG(FATAL) << "SSL error: " << lastSSLError()
|
||||
<< " Unknown curve name: " << _ecdhCurve;
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// https://www.openssl.org/docs/manmaster/apps/ecparam.html
|
||||
ecdhKey = EC_KEY_new_by_curve_name(sslEcdhNid);
|
||||
if (ecdhKey == nullptr) {
|
||||
LOG(FATAL) << "SSL error: " << lastSSLError()
|
||||
<< " Unable to create curve by name: " << _ecdhCurve;
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
SSL_CTX_set_tmp_ecdh(_sslContext, ecdhKey);
|
||||
SSL_CTX_set_options(_sslContext, SSL_OP_SINGLE_ECDH_USE);
|
||||
EC_KEY_free(ecdhKey);
|
||||
#endif
|
||||
|
||||
// set ssl context
|
||||
UniformCharacter r(
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
_rctx = r.random(SSL_MAX_SSL_SESSION_ID_LENGTH);
|
||||
|
||||
int res = SSL_CTX_set_session_id_context(
|
||||
_sslContext, (unsigned char const*)_rctx.c_str(), (int)_rctx.size());
|
||||
|
||||
if (res != 1) {
|
||||
LOG(FATAL) << "cannot set SSL session id context '" << _rctx
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// check CA
|
||||
if (!_cafile.empty()) {
|
||||
LOG(TRACE) << "trying to load CA certificates from '" << _cafile << "'";
|
||||
|
||||
int res = SSL_CTX_load_verify_locations(_sslContext, _cafile.c_str(), 0);
|
||||
|
||||
if (res == 0) {
|
||||
LOG(FATAL) << "cannot load CA certificates from '" << _cafile
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) * certNames;
|
||||
|
||||
certNames = SSL_load_client_CA_file(_cafile.c_str());
|
||||
|
||||
if (certNames == nullptr) {
|
||||
LOG(FATAL) << "cannot load CA certificates from '" << _cafile
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (Logger::logLevel() == arangodb::LogLevel::TRACE) {
|
||||
for (int i = 0; i < sk_X509_NAME_num(certNames); ++i) {
|
||||
X509_NAME* cert = sk_X509_NAME_value(certNames, i);
|
||||
|
||||
if (cert) {
|
||||
BIOGuard bout(BIO_new(BIO_s_mem()));
|
||||
|
||||
X509_NAME_print_ex(bout._bio, cert, 0,
|
||||
(XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV |
|
||||
ASN1_STRFLGS_UTF8_CONVERT) &
|
||||
~ASN1_STRFLGS_ESC_MSB);
|
||||
|
||||
char* r;
|
||||
long len = BIO_get_mem_data(bout._bio, &r);
|
||||
|
||||
LOG(TRACE) << "name: " << std::string(r, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_client_CA_list(_sslContext, certNames);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SslFeature::stringifySslOptions(
|
||||
uint64_t opts) const {
|
||||
std::string result;
|
||||
|
||||
#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
|
||||
if (opts & SSL_OP_MICROSOFT_SESS_ID_BUG) {
|
||||
result.append(", SSL_OP_MICROSOFT_SESS_ID_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_CHALLENGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_CHALLENGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
if (opts & SSL_OP_LEGACY_SERVER_CONNECT) {
|
||||
result.append(", SSL_OP_LEGACY_SERVER_CONNECT");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLSEXT_PADDING
|
||||
if (opts & SSL_OP_TLSEXT_PADDING) {
|
||||
result.append(", SSL_OP_TLSEXT_PADDING");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
|
||||
if (opts & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
|
||||
result.append(", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
|
||||
if (opts & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) {
|
||||
result.append(", SSL_OP_SAFARI_ECDHE_ECDSA_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
|
||||
if (opts & SSL_OP_SSLEAY_080_CLIENT_DH_BUG) {
|
||||
result.append(", SSL_OP_SSLEAY_080_CLIENT_DH_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_D5_BUG
|
||||
if (opts & SSL_OP_TLS_D5_BUG) {
|
||||
result.append(", SSL_OP_TLS_D5_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
|
||||
if (opts & SSL_OP_TLS_BLOCK_PADDING_BUG) {
|
||||
result.append(", SSL_OP_TLS_BLOCK_PADDING_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
|
||||
if (opts & SSL_OP_MSIE_SSLV2_RSA_PADDING) {
|
||||
result.append(", SSL_OP_MSIE_SSLV2_RSA_PADDING");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
|
||||
if (opts & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG) {
|
||||
result.append(", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
if (opts & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) {
|
||||
result.append(", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_QUERY_MTU
|
||||
if (opts & SSL_OP_NO_QUERY_MTU) {
|
||||
result.append(", SSL_OP_NO_QUERY_MTU");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_COOKIE_EXCHANGE
|
||||
if (opts & SSL_OP_COOKIE_EXCHANGE) {
|
||||
result.append(", SSL_OP_COOKIE_EXCHANGE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
if (opts & SSL_OP_NO_TICKET) {
|
||||
result.append(", SSL_OP_NO_TICKET");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CISCO_ANYCONNECT
|
||||
if (opts & SSL_OP_CISCO_ANYCONNECT) {
|
||||
result.append(", SSL_OP_CISCO_ANYCONNECT");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||
if (opts & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) {
|
||||
result.append(", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
if (opts & SSL_OP_NO_COMPRESSION) {
|
||||
result.append(", SSL_OP_NO_COMPRESSION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
||||
if (opts & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) {
|
||||
result.append(", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
if (opts & SSL_OP_SINGLE_ECDH_USE) {
|
||||
result.append(", SSL_OP_SINGLE_ECDH_USE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SINGLE_DH_USE
|
||||
if (opts & SSL_OP_SINGLE_DH_USE) {
|
||||
result.append(", SSL_OP_SINGLE_DH_USE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_EPHEMERAL_RSA
|
||||
if (opts & SSL_OP_EPHEMERAL_RSA) {
|
||||
result.append(", SSL_OP_EPHEMERAL_RSA");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
if (opts & SSL_OP_CIPHER_SERVER_PREFERENCE) {
|
||||
result.append(", SSL_OP_CIPHER_SERVER_PREFERENCE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_ROLLBACK_BUG
|
||||
if (opts & SSL_OP_TLS_ROLLBACK_BUG) {
|
||||
result.append(", SSL_OP_TLS_ROLLBACK_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSLv2
|
||||
if (opts & SSL_OP_NO_SSLv2) {
|
||||
result.append(", SSL_OP_NO_SSLv2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSLv3
|
||||
if (opts & SSL_OP_NO_SSLv3) {
|
||||
result.append(", SSL_OP_NO_SSLv3");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1
|
||||
if (opts & SSL_OP_NO_TLSv1) {
|
||||
result.append(", SSL_OP_NO_TLSv1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1_2
|
||||
if (opts & SSL_OP_NO_TLSv1_2) {
|
||||
result.append(", SSL_OP_NO_TLSv1_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1_1
|
||||
if (opts & SSL_OP_NO_TLSv1_1) {
|
||||
result.append(", SSL_OP_NO_TLSv1_1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_DTLSv1
|
||||
if (opts & SSL_OP_NO_DTLSv1) {
|
||||
result.append(", SSL_OP_NO_DTLSv1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_DTLSv1_2
|
||||
if (opts & SSL_OP_NO_DTLSv1_2) {
|
||||
result.append(", SSL_OP_NO_DTLSv1_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSL_MASK
|
||||
if (opts & SSL_OP_NO_SSL_MASK) {
|
||||
result.append(", SSL_OP_NO_SSL_MASK");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_PKCS1_CHECK_1
|
||||
if (opts & SSL_OP_PKCS1_CHECK_1) {
|
||||
result.append(", SSL_OP_PKCS1_CHECK_1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_PKCS1_CHECK_2
|
||||
if (opts & SSL_OP_PKCS1_CHECK_2) {
|
||||
result.append(", SSL_OP_PKCS1_CHECK_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_CA_DN_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_CA_DN_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
if (opts & SSL_OP_CRYPTOPRO_TLSEXT_BUG) {
|
||||
result.append(", SSL_OP_CRYPTOPRO_TLSEXT_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// strip initial comma
|
||||
return result.substr(2);
|
||||
}
|
||||
|
|
|
@ -33,30 +33,8 @@ class SslFeature final : public application_features::ApplicationFeature {
|
|||
explicit SslFeature(application_features::ApplicationServer* server);
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override final;
|
||||
void prepare() override final;
|
||||
void start() override final;
|
||||
void stop() override final;
|
||||
|
||||
public:
|
||||
SSL_CTX* sslContext() const { return _sslContext; }
|
||||
|
||||
public:
|
||||
std::string _cafile;
|
||||
std::string _keyfile;
|
||||
bool _sessionCache;
|
||||
std::string _cipherList;
|
||||
uint64_t _protocol;
|
||||
uint64_t _options;
|
||||
std::string _ecdhCurve;
|
||||
|
||||
private:
|
||||
void createSslContext();
|
||||
std::string stringifySslOptions(uint64_t opts) const;
|
||||
|
||||
private:
|
||||
SSL_CTX* _sslContext;
|
||||
std::string _rctx;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,489 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SslServerFeature.h"
|
||||
|
||||
#include "Basics/FileUtils.h"
|
||||
#include "Basics/locks.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
#include "Random/UniformCharacter.h"
|
||||
#include "Ssl/ssl-helper.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::options;
|
||||
|
||||
SslServerFeature::SslServerFeature(application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "SslServer"),
|
||||
_cafile(),
|
||||
_keyfile(),
|
||||
_sessionCache(false),
|
||||
_cipherList(),
|
||||
_protocol(TLS_V1),
|
||||
_options(
|
||||
(long)(SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_CIPHER_SERVER_PREFERENCE)),
|
||||
_ecdhCurve("prime256v1"),
|
||||
_sslContext(nullptr) {
|
||||
setOptional(true);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Ssl");
|
||||
startsAfter("Logger");
|
||||
}
|
||||
|
||||
void SslServerFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
options->addSection("ssl", "Configure SSL communication");
|
||||
|
||||
options->addOption("--ssl.cafile", "ca file used for secure connections",
|
||||
new StringParameter(&_cafile));
|
||||
|
||||
options->addOption("--ssl.keyfile", "key-file used for secure connections",
|
||||
new StringParameter(&_keyfile));
|
||||
|
||||
options->addOption("--ssl.session-cache",
|
||||
"enable the session cache for connections",
|
||||
new BooleanParameter(&_sessionCache));
|
||||
|
||||
options->addOption("--ssl.chipher-list",
|
||||
"ssl chipers to use, see OpenSSL documentation",
|
||||
new StringParameter(&_cipherList));
|
||||
|
||||
std::unordered_set<uint64_t> sslProtocols = {1, 2, 3, 4};
|
||||
|
||||
options->addOption("--ssl.protocol",
|
||||
"ssl protocol (1 = SSLv2, 2 = SSLv23, 3 = SSLv3, 4 = "
|
||||
"TLSv1, 5 = TLSV1.2 (recommended)",
|
||||
new UInt64Parameter(&_protocol));
|
||||
|
||||
options->addHiddenOption(
|
||||
"--ssl.options", "ssl connection options, see OpenSSL documentation",
|
||||
new DiscreteValuesParameter<UInt64Parameter>(&_options, sslProtocols));
|
||||
|
||||
options->addOption(
|
||||
"--ssl.ecdh-curve",
|
||||
"SSL ECDH Curve, see the output of \"openssl ecparam -list_curves\"",
|
||||
new StringParameter(&_ecdhCurve));
|
||||
}
|
||||
|
||||
void SslServerFeature::prepare() {
|
||||
createSslContext();
|
||||
}
|
||||
|
||||
void SslServerFeature::start() {
|
||||
LOG(INFO) << "using SSL options: " << stringifySslOptions(_options);
|
||||
|
||||
if (!_cipherList.empty()) {
|
||||
LOG(INFO) << "using SSL cipher-list '" << _cipherList << "'";
|
||||
}
|
||||
}
|
||||
|
||||
void SslServerFeature::stop() {
|
||||
if (_sslContext != nullptr) {
|
||||
SSL_CTX_free(_sslContext);
|
||||
_sslContext = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class BIOGuard {
|
||||
public:
|
||||
explicit BIOGuard(BIO* bio) : _bio(bio) {}
|
||||
|
||||
~BIOGuard() { BIO_free(_bio); }
|
||||
|
||||
public:
|
||||
BIO* _bio;
|
||||
};
|
||||
}
|
||||
|
||||
void SslServerFeature::createSslContext() {
|
||||
// check keyfile
|
||||
if (_keyfile.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// validate protocol
|
||||
if (_protocol <= SSL_UNKNOWN || _protocol >= SSL_LAST) {
|
||||
LOG(FATAL) << "invalid SSL protocol version specified. Please use a valid "
|
||||
"value for '--ssl.protocol.'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "using SSL protocol version '"
|
||||
<< protocolName((protocol_e)_protocol) << "'";
|
||||
|
||||
if (!FileUtils::exists(_keyfile)) {
|
||||
LOG(FATAL) << "unable to find SSL keyfile '" << _keyfile << "'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// create context
|
||||
_sslContext = ::sslContext(protocol_e(_protocol), _keyfile);
|
||||
|
||||
if (_sslContext == nullptr) {
|
||||
LOG(FATAL) << "failed to create SSL context, cannot create HTTPS server";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// set cache mode
|
||||
SSL_CTX_set_session_cache_mode(
|
||||
_sslContext, _sessionCache ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_OFF);
|
||||
|
||||
if (_sessionCache) {
|
||||
LOG(TRACE) << "using SSL session caching";
|
||||
}
|
||||
|
||||
// set options
|
||||
SSL_CTX_set_options(_sslContext, (long)_options);
|
||||
|
||||
if (!_cipherList.empty()) {
|
||||
if (SSL_CTX_set_cipher_list(_sslContext, _cipherList.c_str()) != 1) {
|
||||
LOG(FATAL) << "cannot set SSL cipher list '" << _cipherList
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
|
||||
int sslEcdhNid;
|
||||
EC_KEY* ecdhKey;
|
||||
sslEcdhNid = OBJ_sn2nid(_ecdhCurve.c_str());
|
||||
|
||||
if (sslEcdhNid == 0) {
|
||||
LOG(FATAL) << "SSL error: " << lastSSLError()
|
||||
<< " Unknown curve name: " << _ecdhCurve;
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// https://www.openssl.org/docs/manmaster/apps/ecparam.html
|
||||
ecdhKey = EC_KEY_new_by_curve_name(sslEcdhNid);
|
||||
if (ecdhKey == nullptr) {
|
||||
LOG(FATAL) << "SSL error: " << lastSSLError()
|
||||
<< " Unable to create curve by name: " << _ecdhCurve;
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
SSL_CTX_set_tmp_ecdh(_sslContext, ecdhKey);
|
||||
SSL_CTX_set_options(_sslContext, SSL_OP_SINGLE_ECDH_USE);
|
||||
EC_KEY_free(ecdhKey);
|
||||
#endif
|
||||
|
||||
// set ssl context
|
||||
UniformCharacter r(
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
_rctx = r.random(SSL_MAX_SSL_SESSION_ID_LENGTH);
|
||||
|
||||
int res = SSL_CTX_set_session_id_context(
|
||||
_sslContext, (unsigned char const*)_rctx.c_str(), (int)_rctx.size());
|
||||
|
||||
if (res != 1) {
|
||||
LOG(FATAL) << "cannot set SSL session id context '" << _rctx
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// check CA
|
||||
if (!_cafile.empty()) {
|
||||
LOG(TRACE) << "trying to load CA certificates from '" << _cafile << "'";
|
||||
|
||||
int res = SSL_CTX_load_verify_locations(_sslContext, _cafile.c_str(), 0);
|
||||
|
||||
if (res == 0) {
|
||||
LOG(FATAL) << "cannot load CA certificates from '" << _cafile
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) * certNames;
|
||||
|
||||
certNames = SSL_load_client_CA_file(_cafile.c_str());
|
||||
|
||||
if (certNames == nullptr) {
|
||||
LOG(FATAL) << "cannot load CA certificates from '" << _cafile
|
||||
<< "': " << lastSSLError();
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (Logger::logLevel() == arangodb::LogLevel::TRACE) {
|
||||
for (int i = 0; i < sk_X509_NAME_num(certNames); ++i) {
|
||||
X509_NAME* cert = sk_X509_NAME_value(certNames, i);
|
||||
|
||||
if (cert) {
|
||||
BIOGuard bout(BIO_new(BIO_s_mem()));
|
||||
|
||||
X509_NAME_print_ex(bout._bio, cert, 0,
|
||||
(XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV |
|
||||
ASN1_STRFLGS_UTF8_CONVERT) &
|
||||
~ASN1_STRFLGS_ESC_MSB);
|
||||
|
||||
char* r;
|
||||
long len = BIO_get_mem_data(bout._bio, &r);
|
||||
|
||||
LOG(TRACE) << "name: " << std::string(r, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_client_CA_list(_sslContext, certNames);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SslServerFeature::stringifySslOptions(
|
||||
uint64_t opts) const {
|
||||
std::string result;
|
||||
|
||||
#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
|
||||
if (opts & SSL_OP_MICROSOFT_SESS_ID_BUG) {
|
||||
result.append(", SSL_OP_MICROSOFT_SESS_ID_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_CHALLENGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_CHALLENGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
if (opts & SSL_OP_LEGACY_SERVER_CONNECT) {
|
||||
result.append(", SSL_OP_LEGACY_SERVER_CONNECT");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLSEXT_PADDING
|
||||
if (opts & SSL_OP_TLSEXT_PADDING) {
|
||||
result.append(", SSL_OP_TLSEXT_PADDING");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
|
||||
if (opts & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
|
||||
result.append(", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
|
||||
if (opts & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) {
|
||||
result.append(", SSL_OP_SAFARI_ECDHE_ECDSA_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
|
||||
if (opts & SSL_OP_SSLEAY_080_CLIENT_DH_BUG) {
|
||||
result.append(", SSL_OP_SSLEAY_080_CLIENT_DH_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_D5_BUG
|
||||
if (opts & SSL_OP_TLS_D5_BUG) {
|
||||
result.append(", SSL_OP_TLS_D5_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
|
||||
if (opts & SSL_OP_TLS_BLOCK_PADDING_BUG) {
|
||||
result.append(", SSL_OP_TLS_BLOCK_PADDING_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
|
||||
if (opts & SSL_OP_MSIE_SSLV2_RSA_PADDING) {
|
||||
result.append(", SSL_OP_MSIE_SSLV2_RSA_PADDING");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
|
||||
if (opts & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG) {
|
||||
result.append(", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
if (opts & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) {
|
||||
result.append(", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_QUERY_MTU
|
||||
if (opts & SSL_OP_NO_QUERY_MTU) {
|
||||
result.append(", SSL_OP_NO_QUERY_MTU");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_COOKIE_EXCHANGE
|
||||
if (opts & SSL_OP_COOKIE_EXCHANGE) {
|
||||
result.append(", SSL_OP_COOKIE_EXCHANGE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
if (opts & SSL_OP_NO_TICKET) {
|
||||
result.append(", SSL_OP_NO_TICKET");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CISCO_ANYCONNECT
|
||||
if (opts & SSL_OP_CISCO_ANYCONNECT) {
|
||||
result.append(", SSL_OP_CISCO_ANYCONNECT");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||
if (opts & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) {
|
||||
result.append(", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
if (opts & SSL_OP_NO_COMPRESSION) {
|
||||
result.append(", SSL_OP_NO_COMPRESSION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
||||
if (opts & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) {
|
||||
result.append(", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
if (opts & SSL_OP_SINGLE_ECDH_USE) {
|
||||
result.append(", SSL_OP_SINGLE_ECDH_USE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_SINGLE_DH_USE
|
||||
if (opts & SSL_OP_SINGLE_DH_USE) {
|
||||
result.append(", SSL_OP_SINGLE_DH_USE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_EPHEMERAL_RSA
|
||||
if (opts & SSL_OP_EPHEMERAL_RSA) {
|
||||
result.append(", SSL_OP_EPHEMERAL_RSA");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
if (opts & SSL_OP_CIPHER_SERVER_PREFERENCE) {
|
||||
result.append(", SSL_OP_CIPHER_SERVER_PREFERENCE");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_TLS_ROLLBACK_BUG
|
||||
if (opts & SSL_OP_TLS_ROLLBACK_BUG) {
|
||||
result.append(", SSL_OP_TLS_ROLLBACK_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSLv2
|
||||
if (opts & SSL_OP_NO_SSLv2) {
|
||||
result.append(", SSL_OP_NO_SSLv2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSLv3
|
||||
if (opts & SSL_OP_NO_SSLv3) {
|
||||
result.append(", SSL_OP_NO_SSLv3");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1
|
||||
if (opts & SSL_OP_NO_TLSv1) {
|
||||
result.append(", SSL_OP_NO_TLSv1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1_2
|
||||
if (opts & SSL_OP_NO_TLSv1_2) {
|
||||
result.append(", SSL_OP_NO_TLSv1_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_TLSv1_1
|
||||
if (opts & SSL_OP_NO_TLSv1_1) {
|
||||
result.append(", SSL_OP_NO_TLSv1_1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_DTLSv1
|
||||
if (opts & SSL_OP_NO_DTLSv1) {
|
||||
result.append(", SSL_OP_NO_DTLSv1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_DTLSv1_2
|
||||
if (opts & SSL_OP_NO_DTLSv1_2) {
|
||||
result.append(", SSL_OP_NO_DTLSv1_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_SSL_MASK
|
||||
if (opts & SSL_OP_NO_SSL_MASK) {
|
||||
result.append(", SSL_OP_NO_SSL_MASK");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_PKCS1_CHECK_1
|
||||
if (opts & SSL_OP_PKCS1_CHECK_1) {
|
||||
result.append(", SSL_OP_PKCS1_CHECK_1");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_PKCS1_CHECK_2
|
||||
if (opts & SSL_OP_PKCS1_CHECK_2) {
|
||||
result.append(", SSL_OP_PKCS1_CHECK_2");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_CA_DN_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_CA_DN_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
|
||||
if (opts & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) {
|
||||
result.append(", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
if (opts & SSL_OP_CRYPTOPRO_TLSEXT_BUG) {
|
||||
result.append(", SSL_OP_CRYPTOPRO_TLSEXT_BUG");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// strip initial comma
|
||||
return result.substr(2);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_APPLICATION_FEATURES_SSL_SERVER_FEATURE_H
|
||||
#define ARANGODB_APPLICATION_FEATURES_SSL_SERVER_FEATURE_H 1
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace arangodb {
|
||||
class SslServerFeature final : public application_features::ApplicationFeature {
|
||||
public:
|
||||
explicit SslServerFeature(application_features::ApplicationServer* server);
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override final;
|
||||
void prepare() override final;
|
||||
void start() override final;
|
||||
void stop() override final;
|
||||
|
||||
public:
|
||||
SSL_CTX* sslContext() const { return _sslContext; }
|
||||
|
||||
public:
|
||||
std::string _cafile;
|
||||
std::string _keyfile;
|
||||
bool _sessionCache;
|
||||
std::string _cipherList;
|
||||
uint64_t _protocol;
|
||||
uint64_t _options;
|
||||
std::string _ecdhCurve;
|
||||
|
||||
private:
|
||||
void createSslContext();
|
||||
std::string stringifySslOptions(uint64_t opts) const;
|
||||
|
||||
private:
|
||||
SSL_CTX* _sslContext;
|
||||
std::string _rctx;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@
|
|||
#include "Basics/Common.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
|
|
Loading…
Reference in New Issue