This is an automated email from the ASF dual-hosted git repository.

sorabh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git

commit 94186fc54f2b2846955d44ced5ed06b1ae209884
Author: superbstreak <robw...@gmail.com>
AuthorDate: Mon Jul 9 12:07:22 2018 -0700

    [DRILL-6587] Added support for custom SSL CTX Options
    
    closes #1366
---
 contrib/native/client/example/querySubmitter.cpp   |  7 +++-
 contrib/native/client/src/clientlib/channel.cpp    | 14 +++++++-
 contrib/native/client/src/clientlib/channel.hpp    | 39 ++++++++++++----------
 contrib/native/client/src/clientlib/errmsgs.cpp    |  2 +-
 .../native/client/src/clientlib/userProperties.cpp |  1 +
 contrib/native/client/src/include/drill/common.hpp |  3 +-
 6 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/contrib/native/client/example/querySubmitter.cpp 
b/contrib/native/client/example/querySubmitter.cpp
index 519dd93..a84d1db 100644
--- a/contrib/native/client/example/querySubmitter.cpp
+++ b/contrib/native/client/example/querySubmitter.cpp
@@ -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){
diff --git a/contrib/native/client/src/clientlib/channel.cpp 
b/contrib/native/client/src/clientlib/channel.cpp
index e368cd0..bdc19f7 100644
--- a/contrib/native/client/src/clientlib/channel.cpp
+++ b/contrib/native/client/src/clientlib/channel.cpp
@@ -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
diff --git a/contrib/native/client/src/clientlib/channel.hpp 
b/contrib/native/client/src/clientlib/channel.hpp
index 76bedde..fec4659 100644
--- a/contrib/native/client/src/clientlib/channel.hpp
+++ b/contrib/native/client/src/clientlib/channel.hpp
@@ -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:
diff --git a/contrib/native/client/src/clientlib/errmsgs.cpp 
b/contrib/native/client/src/clientlib/errmsgs.cpp
index 37f0ac1..82f24fd 100644
--- a/contrib/native/client/src/clientlib/errmsgs.cpp
+++ b/contrib/native/client/src/clientlib/errmsgs.cpp
@@ -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"},
diff --git a/contrib/native/client/src/clientlib/userProperties.cpp 
b/contrib/native/client/src/clientlib/userProperties.cpp
index f1aa82f..0ad8af1 100644
--- a/contrib/native/client/src/clientlib/userProperties.cpp
+++ b/contrib/native/client/src/clientlib/userProperties.cpp
@@ -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)
 ;
 
diff --git a/contrib/native/client/src/include/drill/common.hpp 
b/contrib/native/client/src/include/drill/common.hpp
index 18cfc69..b5bb522 100644
--- a/contrib/native/client/src/include/drill/common.hpp
+++ b/contrib/native/client/src/include/drill/common.hpp
@@ -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. 

Reply via email to