Skip to content
Permalink
Browse files
[DRILL-6587] Added support for custom SSL CTX Options
closes #1366
  • Loading branch information
superbstreak authored and sohami committed Jul 13, 2018
1 parent b1eb9d7 commit 94186fc54f2b2846955d44ced5ed06b1ae209884
Showing 6 changed files with 45 additions and 21 deletions.
@@ -54,7 +54,8 @@ struct Option{
{"certFilePath", "Path to SSL certificate file", false},
{"disableHostnameVerification", "disable host name verification", false},
{"disableCertVerification", "disable certificate verification", false},
{"useSystemTrustStore", "[Windows only]. Use the system truststore.", false }
{"useSystemTrustStore", "[Windows only]. Use the system truststore.", false },
{"CustomSSLCtxOptions", "The custom SSL CTX Options", false}

};

@@ -315,6 +316,7 @@ int main(int argc, char* argv[]) {
std::string disableHostnameVerification=qsOptionValues["disableHostnameVerification"];
std::string disableCertVerification=qsOptionValues["disableCertVerification"];
std::string useSystemTrustStore = qsOptionValues["useSystemTrustStore"];
std::string customSSLOptions = qsOptionValues["CustomSSLCtxOptions"];

Drill::QueryType type;

@@ -416,6 +418,9 @@ int main(int argc, char* argv[]) {
if (useSystemTrustStore.length() > 0){
props.setProperty(USERPROP_USESYSTEMTRUSTSTORE, useSystemTrustStore);
}
if (customSSLOptions.length() > 0){
props.setProperty(USERPROP_CUSTOM_SSLCTXOPTIONS, customSSLOptions);
}
}

if(client.connect(connectStr.c_str(), &props)!=Drill::CONN_SUCCESS){
@@ -210,7 +210,19 @@ ChannelContext* ChannelFactory::getChannelContext(channelType_t t, DrillUserProp
verifyMode = boost::asio::ssl::context::verify_none;
}

pChannelContext = new SSLChannelContext(props, tlsVersion, verifyMode);
long customSSLCtxOptions = 0;
std::string sslOptions;
props->getProp(USERPROP_CUSTOM_SSLCTXOPTIONS, sslOptions);
if (!sslOptions.empty()){
try{
customSSLCtxOptions = boost::lexical_cast<long>(sslOptions);
}
catch (...){
DRILL_LOG(LOG_ERROR) << "Unable to parse custom SSL CTX options." << std::endl;
}
}

pChannelContext = new SSLChannelContext(props, tlsVersion, verifyMode, customSSLCtxOptions);
}
break;
#endif
@@ -23,11 +23,10 @@
#include "streamSocket.hpp"
#include "errmsgs.hpp"

namespace
{
// The error message to indicate certificate verification failure.
#define DRILL_BOOST_SSL_CERT_VERIFY_FAILED "handshake: certificate verify failed\0"
}
#if defined(IS_SSL_ENABLED)
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif

namespace Drill {

@@ -90,7 +89,8 @@ class UserProperties;

SSLChannelContext(DrillUserProperties *props,
boost::asio::ssl::context::method tlsVersion,
boost::asio::ssl::verify_mode verifyMode) :
boost::asio::ssl::verify_mode verifyMode,
const long customSSLCtxOptions = 0) :
ChannelContext(props),
m_SSLContext(tlsVersion),
m_certHostnameVerificationStatus(true)
@@ -101,6 +101,7 @@ class UserProperties;
| boost::asio::ssl::context::no_sslv2
| boost::asio::ssl::context::no_sslv3
| boost::asio::ssl::context::single_dh_use
| customSSLCtxOptions
);
m_SSLContext.set_verify_mode(verifyMode);
};
@@ -179,11 +180,11 @@ class UserProperties;

/// @brief Handle protocol handshake exceptions.
///
/// @param in_errmsg The error message.
/// @param in_err The error.
///
/// @return the connectionStatus.
virtual connectionStatus_t HandleProtocolHandshakeException(const char* in_errmsg){
return handleError(CONN_HANDSHAKE_FAILED, in_errmsg);
virtual connectionStatus_t HandleProtocolHandshakeException(const boost::system::system_error& in_err){
return handleError(CONN_HANDSHAKE_FAILED, in_err.what());
}

boost::asio::io_service& m_ioService;
@@ -206,7 +207,7 @@ class UserProperties;
try{
m_pSocket->protocolHandshake(useSystemConfig);
} catch (boost::system::system_error e) {
status = HandleProtocolHandshakeException(e.what());
status = HandleProtocolHandshakeException(e);
}
return status;
}
@@ -236,28 +237,32 @@ class UserProperties;
}
connectionStatus_t init();
protected:
#if defined(IS_SSL_ENABLED)
/// @brief Handle protocol handshake exceptions for SSL specific failures.
///
/// @param in_errmsg The error message.
/// @param in_err The error.
///
/// @return the connectionStatus.
connectionStatus_t HandleProtocolHandshakeException(const char* errmsg) {
connectionStatus_t HandleProtocolHandshakeException(const boost::system::system_error& in_err) {
const boost::system::error_code& errcode = in_err.code();
if (!(((SSLChannelContext_t *)m_pContext)->GetCertificateHostnameVerificationStatus())){
return handleError(
CONN_HANDSHAKE_FAILED,
getMessage(ERR_CONN_SSL_CN));
getMessage(ERR_CONN_SSL_CN, in_err.what()));
}
else if (0 == strcmp(errmsg, DRILL_BOOST_SSL_CERT_VERIFY_FAILED)){
else if (boost::asio::error::get_ssl_category() == errcode.category() &&
SSL_R_CERTIFICATE_VERIFY_FAILED == ERR_GET_REASON(errcode.value())){
return handleError(
CONN_HANDSHAKE_FAILED,
getMessage(ERR_CONN_SSL_CERTVERIFY, errmsg));
getMessage(ERR_CONN_SSL_CERTVERIFY, in_err.what()));
}
else{
return handleError(
CONN_HANDSHAKE_FAILED,
getMessage(ERR_CONN_SSL_GENERAL, errmsg));
getMessage(ERR_CONN_SSL_GENERAL, in_err.what()));
}
}
#endif
};

class ChannelFactory{
@@ -312,7 +317,7 @@ class UserProperties;

// Sets the result back to the context.
context->SetCertHostnameVerificationStatus(verified);
return verified && in_preverified;
return verified;
}

private:
@@ -58,7 +58,7 @@ static Drill::ErrorMessages errorMessages[]={
" Please check connection parameters or contact administrator. [Warn: This"
" could be due to a bad configuration or a security attack is in progress.]"},
{ERR_CONN_SSL_GENERAL, ERR_CATEGORY_CONN, 0, "Encountered an exception during SSL handshake. [Details: %s]"},
{ERR_CONN_SSL_CN, ERR_CATEGORY_CONN, 0, "SSL certificate host name verification failure." },
{ERR_CONN_SSL_CN, ERR_CATEGORY_CONN, 0, "SSL certificate host name verification failure. [Details: %s]" },
{ERR_CONN_SSL_CERTVERIFY, ERR_CATEGORY_CONN, 0, "SSL certificate verification failed. [Details: %s]"},
{ERR_QRY_OUTOFMEM, ERR_CATEGORY_QRY, 0, "Out of memory."},
{ERR_QRY_COMMERR, ERR_CATEGORY_QRY, 0, "Communication error. %s"},
@@ -35,6 +35,7 @@ const std::map<std::string, uint32_t> DrillUserProperties::USER_PROPERTIES=boos
( USERPROP_DISABLE_HOSTVERIFICATION, USERPROP_FLAGS_BOOLEAN|USERPROP_FLAGS_SSLPROP)
( USERPROP_DISABLE_CERTVERIFICATION, USERPROP_FLAGS_BOOLEAN|USERPROP_FLAGS_SSLPROP)
( USERPROP_USESYSTEMTRUSTSTORE, USERPROP_FLAGS_BOOLEAN|USERPROP_FLAGS_SSLPROP)
( USERPROP_CUSTOM_SSLCTXOPTIONS, USERPROP_FLAGS_STRING|USERPROP_FLAGS_SSLPROP)
( USERPROP_SASL_ENCRYPT, USERPROP_FLAGS_STRING)
;

@@ -173,7 +173,8 @@ typedef enum{
#define USERPROP_PASSWORD "password"
#define USERPROP_SCHEMA "schema"
#define USERPROP_USESSL "enableTLS"
#define USERPROP_TLSPROTOCOL "TLSProtocol" //TLS version
#define USERPROP_TLSPROTOCOL "TLSProtocol" //TLS version. The exact TLS version.
#define USERPROP_CUSTOM_SSLCTXOPTIONS "CustomSSLCtxOptions" // The custom SSL CTX options.
#define USERPROP_CERTFILEPATH "certFilePath" // pem file path and name
// TODO: support truststore protected by password.
// #define USERPROP_CERTPASSWORD "certPassword" // Password for certificate file.

0 comments on commit 94186fc

Please sign in to comment.