aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSorabh Hamirwasia <shamirwasia@maprtech.com>2017-03-06 00:19:50 -0800
committerAman Sinha <asinha@maprtech.com>2017-05-20 16:17:19 -0700
commitd11aba2e55323bb5a6a9deb5bb09fd87470dcedf (patch)
tree60e61ce8fa7db70deeaeb09733a7f86864434516
parentce8bbc01cfde7d714185919be2ca2923d19ea890 (diff)
DRILL-4335: Apache Drill should support network encryption.
NOTE: This pull request provides support for on-wire encryption using SASL framework. Communication channel covered is: 1) C++ Drill Client and Drillbit channel. close apache/drill#809
-rw-r--r--contrib/native/client/example/querySubmitter.cpp25
-rw-r--r--contrib/native/client/readme.macos6
-rw-r--r--contrib/native/client/src/clientlib/drillClient.cpp1
-rw-r--r--contrib/native/client/src/clientlib/drillClientImpl.cpp694
-rw-r--r--contrib/native/client/src/clientlib/drillClientImpl.hpp41
-rw-r--r--contrib/native/client/src/clientlib/rpcMessage.cpp2
-rw-r--r--contrib/native/client/src/clientlib/rpcMessage.hpp1
-rw-r--r--contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp119
-rw-r--r--contrib/native/client/src/clientlib/saslAuthenticatorImpl.hpp12
-rw-r--r--contrib/native/client/src/clientlib/utils.cpp49
-rw-r--r--contrib/native/client/src/clientlib/utils.hpp32
-rw-r--r--contrib/native/client/src/include/drill/common.hpp2
-rw-r--r--contrib/native/client/src/protobuf/User.pb.cc463
-rw-r--r--contrib/native/client/src/protobuf/User.pb.h71
14 files changed, 1194 insertions, 324 deletions
diff --git a/contrib/native/client/example/querySubmitter.cpp b/contrib/native/client/example/querySubmitter.cpp
index 599089786..47e55de2d 100644
--- a/contrib/native/client/example/querySubmitter.cpp
+++ b/contrib/native/client/example/querySubmitter.cpp
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -24,7 +25,7 @@
#include <boost/algorithm/string/join.hpp>
#include "drill/drillc.hpp"
-int nOptions=15;
+int nOptions=19;
struct Option{
char name[32];
@@ -45,7 +46,11 @@ struct Option{
{"heartbeatFrequency", "Heartbeat frequency (second). Disabled if set to 0.", false},
{"user", "Username", false},
{"password", "Password", false},
- {"saslPluginPath", "Path to where SASL plugins are installed", false}
+ {"saslPluginPath", "Path to where SASL plugins are installed", false},
+ {"service_host", "Service host for Kerberos", false},
+ {"service_name", "Service name for Kerberos", false},
+ {"auth", "Authentication mechanism to use", false},
+ {"sasl_encrypt", "Negotiate for encrypted connection", false}
};
std::map<std::string, std::string> qsOptionValues;
@@ -295,6 +300,10 @@ int main(int argc, char* argv[]) {
std::string user=qsOptionValues["user"];
std::string password=qsOptionValues["password"];
std::string saslPluginPath=qsOptionValues["saslPluginPath"];
+ std::string sasl_encrypt=qsOptionValues["sasl_encrypt"];
+ std::string serviceHost=qsOptionValues["service_host"];
+ std::string serviceName=qsOptionValues["service_name"];
+ std::string auth=qsOptionValues["auth"];
Drill::QueryType type;
@@ -371,6 +380,18 @@ int main(int argc, char* argv[]) {
if(password.length()>0){
props.setProperty(USERPROP_PASSWORD, password);
}
+ if(sasl_encrypt.length()>0){
+ props.setProperty(USERPROP_SASL_ENCRYPT, sasl_encrypt);
+ }
+ if(serviceHost.length()>0){
+ props.setProperty(USERPROP_SERVICE_HOST, serviceHost);
+ }
+ if(serviceName.length()>0){
+ props.setProperty(USERPROP_SERVICE_NAME, serviceName);
+ }
+ if(auth.length()>0){
+ props.setProperty(USERPROP_AUTH_MECHANISM, auth);
+ }
if(client.connect(connectStr.c_str(), &props)!=Drill::CONN_SUCCESS){
std::cerr<< "Failed to connect with error: "<< client.getError() << " (Using:"<<connectStr<<")"<<std::endl;
diff --git a/contrib/native/client/readme.macos b/contrib/native/client/readme.macos
index 4785e87df..eee017ef5 100644
--- a/contrib/native/client/readme.macos
+++ b/contrib/native/client/readme.macos
@@ -35,6 +35,8 @@ Install Prerequisites
or use brew to install
$> brew install cmake
+2.0) Install cppunit
+ $> brew install cppunit
2.1) Install protobuf 2.5.0 (or higher)
$> brew install protobuf
@@ -54,7 +56,7 @@ Install Prerequisites
When changes have been introduced to the protocol module, you might need to refresh the protobuf C++ source files too.
$> cd DRILL_DIR/contrib/native/client
$> mkdir build
- $> cd build && cmake3 -G "XCode" -D CMAKE_BUILD_TYPE=Debug ..
+ $> cd build && cmake -G "Xcode" -D CMAKE_BUILD_TYPE=Debug ..
$> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target fixProtobufs
$> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target cpProtobufs
@@ -64,7 +66,7 @@ Build drill client
-------------------
$> cd DRILL_DIR/contrib/native/client
$> mkdir build
- $> cd build && cmake3 -G "XCode" -D CMAKE_BUILD_TYPE=Debug ..
+ $> cd build && cmake -G "Xcode" -D CMAKE_BUILD_TYPE=Debug ..
$> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target ALL_BUILD
diff --git a/contrib/native/client/src/clientlib/drillClient.cpp b/contrib/native/client/src/clientlib/drillClient.cpp
index 70002721c..8eb909b49 100644
--- a/contrib/native/client/src/clientlib/drillClient.cpp
+++ b/contrib/native/client/src/clientlib/drillClient.cpp
@@ -181,6 +181,7 @@ const std::map<std::string, uint32_t> DrillUserProperties::USER_PROPERTIES=boos
( USERPROP_USESSL, USERPROP_FLAGS_BOOLEAN|USERPROP_FLAGS_SSLPROP)
( USERPROP_FILEPATH, USERPROP_FLAGS_STRING|USERPROP_FLAGS_SSLPROP|USERPROP_FLAGS_FILEPATH)
( USERPROP_FILENAME, USERPROP_FLAGS_STRING|USERPROP_FLAGS_SSLPROP|USERPROP_FLAGS_FILENAME)
+ ( USERPROP_SASL_ENCRYPT, USERPROP_FLAGS_STRING)
;
bool DrillUserProperties::validate(std::string& err){
diff --git a/contrib/native/client/src/clientlib/drillClientImpl.cpp b/contrib/native/client/src/clientlib/drillClientImpl.cpp
index 30a354e47..0dee309a6 100644
--- a/contrib/native/client/src/clientlib/drillClientImpl.cpp
+++ b/contrib/native/client/src/clientlib/drillClientImpl.cpp
@@ -30,7 +30,6 @@
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
-
#include "drill/drillClient.hpp"
#include "drill/fieldmeta.hpp"
#include "drill/recordBatch.hpp"
@@ -193,7 +192,7 @@ connectionStatus_t DrillClientImpl::sendHeartbeat(){
boost::lock_guard<boost::mutex> prLock(this->m_prMutex);
boost::lock_guard<boost::mutex> lock(m_dcMutex);
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Heartbeat sent." << std::endl;)
- status=sendSync(heartbeatMsg);
+ status=sendSyncCommon(heartbeatMsg);
status=status==CONN_SUCCESS?status:CONN_DEAD;
//If the server sends responses to a heartbeat, we need to increment the pending requests counter.
if(m_pendingRequests++==0){
@@ -233,18 +232,125 @@ void DrillClientImpl::Close() {
shutdownSocket();
}
+/*
+ * Write bytesToWrite length data bytes pointed by dataPtr. It handles EINTR error
+ * occurred during write_some sys call and does a retry on that.
+ *
+ * Parameters:
+ * dataPtr - in param - Pointer to data bytes to write on socket.
+ * bytesToWrite - in param - Length of data bytes to write from dataPtr.
+ * errorCode - out param - Error code set by boost.
+ */
+void DrillClientImpl::doWriteToSocket(const char* dataPtr, size_t bytesToWrite,
+ boost::system::error_code& errorCode) {
+ if(0 == bytesToWrite) {
+ return;
+ }
+
+ // Write all the bytes to socket. In case of error when all bytes are not successfully written
+ // proper errorCode will be set.
+ while(1) {
+ size_t bytesWritten = m_socket.write_some(boost::asio::buffer(dataPtr, bytesToWrite), errorCode);
+
+ // Update the state
+ bytesToWrite -= bytesWritten;
+ dataPtr += bytesWritten;
+
+ if(EINTR != errorCode.value()) break;
+
+ // Check if all the data is written then break from loop
+ if(0 == bytesToWrite) break;
+ }
+}
-connectionStatus_t DrillClientImpl::sendSync(rpc::OutBoundRpcMessage& msg){
+/*
+ * Common wrapper to take care of sending both plain or encrypted message. It creates a send buffer from an
+ * OutboundRPCMessage and then call the send handler pointing to either sendSyncPlain or sendSyncEncrypted
+ *
+ * Return:
+ * connectionStatus_t - CONN_SUCCESS - In case of successful send
+ * - CONN_FAILURE - In case of failure to send
+ */
+connectionStatus_t DrillClientImpl::sendSyncCommon(rpc::OutBoundRpcMessage& msg) {
encode(m_wbuf, msg);
+ return (this->*m_fpCurrentSendHandler)();
+}
+
+/*
+ * Send handler for sending plain messages over wire
+ *
+ * Return:
+ * connectionStatus_t - CONN_SUCCESS - In case of successful send
+ * - CONN_FAILURE - In case of failure to send
+ */
+connectionStatus_t DrillClientImpl::sendSyncPlain(){
+
boost::system::error_code ec;
- size_t s=m_socket.write_some(boost::asio::buffer(m_wbuf), ec);
- if(!ec && s!=0){
+ doWriteToSocket(reinterpret_cast<char*>(m_wbuf.data()), m_wbuf.size(), ec);
+
+ if(!ec) {
return CONN_SUCCESS;
- }else{
+ } else {
return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, ec.message().c_str()));
}
}
+/*
+ * Send handler for sending encrypted messages over wire. It encrypts the send buffer using wrap api provided by
+ * saslAuthenticatorImpl and then transmit the encrypted bytes over wire.
+ *
+ * Return:
+ * connectionStatus_t - CONN_SUCCESS - In case of successful send
+ * - CONN_FAILURE - In case of failure to send
+ */
+connectionStatus_t DrillClientImpl::sendSyncEncrypted() {
+
+ boost::system::error_code ec;
+
+ // Encoded message is encrypted into chunks of size <= WrapSizeLimit. Each encrypted chunk along with
+ // its encrypted length in network order (added by Cyrus-SASL plugin) is sent over wire.
+ const int wrapChunkSize = m_encryptionCtxt.getWrapSizeLimit();
+ int lengthToEncrypt = m_wbuf.size();
+
+ int currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt);
+ uint32_t currentChunkOffset = 0;
+ std::stringstream errorMsg;
+
+ // Encrypt and send each chunk
+ while(lengthToEncrypt != 0) {
+ const char* wrappedChunk = NULL;
+ uint32_t wrappedLen = 0;
+ const int wrapResult = m_saslAuthenticator->wrap(reinterpret_cast<const char*>(m_wbuf.data() + currentChunkOffset),
+ currentChunkLen, &wrappedChunk, wrappedLen);
+ if(SASL_OK != wrapResult) {
+ errorMsg << "Sasl wrap failed while encrypting chunk of length: " << currentChunkLen << " , EncodeError: "
+ << wrapResult;
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str()
+ << " ,ChunkOffset: " << currentChunkOffset << ", Message Len: " << m_wbuf.size()
+ << ", Closing connection.";)
+ return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, errorMsg.str().c_str()));
+ }
+
+ // Send the encrypted chunk.
+ doWriteToSocket(wrappedChunk, wrappedLen, ec);
+
+ if(ec) {
+ errorMsg << "Failure while sending encrypted chunk. Error: " << ec.message().c_str();
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::sendSyncEncrypted - " << errorMsg.str()
+ << ", Chunk Length: " << currentChunkLen << ", ChunkOffset:" << currentChunkOffset
+ << ", Message Len: " << m_wbuf.size() << ", Closing connection.";)
+ return handleConnError(CONN_FAILURE, getMessage(ERR_CONN_WFAIL, errorMsg.str().c_str()));
+ }
+
+ // Update variables after sending each encrypted chunk
+ lengthToEncrypt -= currentChunkLen;
+ currentChunkOffset += currentChunkLen;
+ currentChunkLen = std::min(wrapChunkSize, lengthToEncrypt);
+ }
+
+ return CONN_SUCCESS;
+}
+
connectionStatus_t DrillClientImpl::recvHandshake(){
if(m_rbuf==NULL){
m_rbuf = Utils::allocateBuffer(MAX_SOCK_RD_BUFSIZE);
@@ -289,7 +395,41 @@ connectionStatus_t DrillClientImpl::recvHandshake(){
return CONN_SUCCESS;
}
-void DrillClientImpl::handleHandshake(ByteBuf_t _buf,
+/*
+ * Read bytesToRead length data bytes from socket into inBuf. It handles EINTR error
+ * occurred during read_some sys call and does a retry on that.
+ *
+ * Parameters:
+ * inBuf - out param - Pointer to buffer to read data into from socket.
+ * bytesToRead - in param - Length of data bytes to read from socket.
+ * errorCode - out param - Error code set by boost.
+ */
+void DrillClientImpl::doReadFromSocket(ByteBuf_t inBuf, size_t bytesToRead,
+ boost::system::error_code& errorCode) {
+
+ // Check if bytesToRead is zero
+ if(0 == bytesToRead) {
+ return;
+ }
+
+ // Read all the bytes. In case when all the bytes were not read the proper
+ // errorCode will be set.
+ while(1){
+ size_t dataBytesRead = m_socket.read_some(boost::asio::buffer(inBuf, bytesToRead),
+ errorCode);
+ // Update the state
+ bytesToRead -= dataBytesRead;
+ inBuf += dataBytesRead;
+
+ // Check if errorCode is EINTR then just retry otherwise break from loop
+ if(EINTR != errorCode.value()) break;
+
+ // Check if all the data is read then break from loop
+ if(0 == bytesToRead) break;
+ }
+}
+
+void DrillClientImpl::handleHandshake(ByteBuf_t inBuf,
const boost::system::error_code& err,
size_t bytes_transferred) {
boost::system::error_code error=err;
@@ -299,21 +439,23 @@ void DrillClientImpl::handleHandshake(ByteBuf_t _buf,
if(!error){
rpc::InBoundRpcMessage msg;
uint32_t length = 0;
- std::size_t bytes_read = rpc::lengthDecode(m_rbuf, length);
+ std::size_t bytes_read = rpcLengthDecode(m_rbuf, length);
if(length>0){
- size_t leftover = LEN_PREFIX_BUFLEN - bytes_read;
- ByteBuf_t b=m_rbuf + LEN_PREFIX_BUFLEN;
- size_t bytesToRead=length - leftover;
- while(1){
- size_t dataBytesRead=m_socket.read_some(
- boost::asio::buffer(b, bytesToRead),
- error);
- if(err) break;
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Handshake Message: actual bytes read = " << dataBytesRead << std::endl;)
- if(dataBytesRead==bytesToRead) break;
- bytesToRead-=dataBytesRead;
- b+=dataBytesRead;
+ const size_t leftover = LEN_PREFIX_BUFLEN - bytes_read;
+ const ByteBuf_t b = m_rbuf + LEN_PREFIX_BUFLEN;
+ const size_t bytesToRead=length - leftover;
+ doReadFromSocket(b, bytesToRead, error);
+
+ // Check if any error happen while reading the message bytes. If yes then return before decoding the Msg
+ if(error) {
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::handleHandshake: ERR_CONN_RDFAIL. "
+ << " Failed to read entire handshake message. with error: "
+ << error.message().c_str() << "\n";)
+ handleConnError(CONN_FAILURE, getMessage(ERR_CONN_RDFAIL, "Failed to read entire handshake message"));
+ return;
}
+
+ // Decode the bytes into a valid RPC Message
if (!decode(m_rbuf+bytes_read, length, msg)) {
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::handleHandshake: ERR_CONN_RDFAIL. Cannot decode handshake.\n";)
handleConnError(CONN_FAILURE, getMessage(ERR_CONN_RDFAIL, "Cannot decode handshake"));
@@ -340,6 +482,11 @@ void DrillClientImpl::handleHandshake(ByteBuf_t _buf,
this->m_serverAuthMechanisms.push_back(mechanism);
}
+ // Updated encryption context based on server response
+ this->m_encryptionCtxt.setEncryptionReqd(b2u.has_encrypted() && b2u.encrypted());
+ if(b2u.has_maxwrappedsize()) {
+ this->m_encryptionCtxt.setMaxWrappedSize(b2u.maxwrappedsize());
+ }
}else{
// boost error
if(error==boost::asio::error::eof){ // Server broke off the connection
@@ -360,7 +507,8 @@ void DrillClientImpl::handleHShakeReadTimeout(const boost::system::error_code &
if (m_deadlineTimer.expires_at() <= boost::asio::deadline_timer::traits_type::now()){
// The deadline has passed.
m_deadlineTimer.expires_at(boost::posix_time::pos_infin);
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::HandleHShakeReadTimeout: Deadline timer expired; ERR_CONN_HSHAKETIMOUT.\n";)
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::HandleHShakeReadTimeout: "
+ << "Deadline timer expired; ERR_CONN_HSHAKETIMOUT.\n";)
handleConnError(CONN_HANDSHAKE_TIMEOUT, getMessage(ERR_CONN_HSHAKETIMOUT));
m_io_service.stop();
boost::system::error_code ignorederr;
@@ -370,6 +518,33 @@ void DrillClientImpl::handleHShakeReadTimeout(const boost::system::error_code &
return;
}
+/*
+ * Check's if client has explicitly expressed interest in encrypted connections only. It looks for USERPROP_SASL_ENCRYPT
+ * connection string property. If set to true then returns true else returns false
+ */
+bool DrillClientImpl::clientNeedsEncryption(const DrillUserProperties* userProperties) {
+ bool needsEncryption = false;
+ // check if userProperties is null
+ if(!userProperties) {
+ return needsEncryption;
+ }
+
+ // Loop through the property to find USERPROP_SASL_ENCRYPT and it's value
+ for (size_t i = 0; i < userProperties->size(); i++) {
+ const std::string key = userProperties->keyAt(i);
+ std::string value = userProperties->valueAt(i);
+
+ if(USERPROP_SASL_ENCRYPT == key) {
+ boost::algorithm::to_lower(value);
+
+ if(0 == value.compare("true")) {
+ needsEncryption = true;
+ }
+ }
+ }
+ return needsEncryption;
+}
+
connectionStatus_t DrillClientImpl::validateHandshake(DrillUserProperties* properties){
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "validateHandShake\n";)
@@ -379,7 +554,7 @@ connectionStatus_t DrillClientImpl::validateHandshake(DrillUserProperties* prope
u2b.set_rpc_version(DRILL_RPC_VERSION);
u2b.set_support_listening(true);
u2b.set_support_timeout(DrillClientConfig::getHeartbeatFrequency() > 0);
- u2b.set_sasl_support(exec::user::SASL_AUTH);
+ u2b.set_sasl_support(exec::user::SASL_PRIVACY);
// Adding version info
exec::user::RpcEndpointInfos* infos = u2b.mutable_client_infos();
@@ -436,7 +611,7 @@ connectionStatus_t DrillClientImpl::validateHandshake(DrillUserProperties* prope
uint64_t coordId = this->getNextCoordinationId();
rpc::OutBoundRpcMessage out_msg(exec::rpc::REQUEST, exec::user::HANDSHAKE, coordId, &u2b);
- sendSync(out_msg);
+ sendSyncCommon(out_msg);
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Sent handshake request message. Coordination id: " << coordId << "\n";)
}
@@ -479,6 +654,13 @@ connectionStatus_t DrillClientImpl::validateHandshake(DrillUserProperties* prope
}
connectionStatus_t DrillClientImpl::handleAuthentication(const DrillUserProperties *userProperties) {
+
+ // Check if client needs encryption and server is configured for encryption or not before starting handshake
+ if(clientNeedsEncryption(userProperties) && !m_encryptionCtxt.isEncryptionReqd()) {
+ return handleConnError(CONN_AUTH_FAILED, "Client needs encryption but on server side encryption is disabled."
+ " Please check connection parameters or contact administrator?");
+ }
+
try {
m_saslAuthenticator = new SaslAuthenticatorImpl(userProperties);
} catch (std::runtime_error& e) {
@@ -495,26 +677,46 @@ connectionStatus_t DrillClientImpl::handleAuthentication(const DrillUserProperti
}
}
+ std::stringstream logMsg;
+ logMsg << "DrillClientImpl::handleAuthentication: Authentication failed. [Details: ";
+
if (SASL_OK == m_saslResultCode) {
- DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "DrillClientImpl::handleAuthentication: Successfully authenticated!"
- << std::endl;)
+ // Check the negotiated SSF value and change the handlers.
+ if(m_encryptionCtxt.isEncryptionReqd()) {
+ if(SASL_OK != m_saslAuthenticator->verifyAndUpdateSaslProps()) {
+ logMsg << m_encryptionCtxt << "]. Negotiated Parameter is invalid."
+ << " Error: " << m_saslResultCode;
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << logMsg.str() << std::endl;)
+ return handleConnError(CONN_AUTH_FAILED, logMsg.str().c_str());
+ }
+
+ // Successfully negotiated for encryption related security parameters.
+ // Start using Encrypt and Decrypt handlers.
+ m_fpCurrentSendHandler = &DrillClientImpl::sendSyncEncrypted;
+ m_fpCurrentReadMsgHandler = &DrillClientImpl::readAndDecryptMsg;
+ }
- // in future, negotiated security layers are known here..
+ // Reset the errorMsg stream since this is success case.
+ logMsg.str(std::string());
+ logMsg << "DrillClientImpl::handleAuthentication: Successfully authenticated! [Details: "
+ << m_encryptionCtxt << " ]";
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << logMsg.str() << std::endl;)
m_io_service.reset();
return CONN_SUCCESS;
} else {
- DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "DrillClientImpl::handleAuthentication: Authentication failed: "
- << m_saslResultCode << std::endl;)
+ logMsg << m_encryptionCtxt << ", Error: " << m_saslResultCode;
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << logMsg.str() << std::endl;)
+
// shuts down socket as well
- return handleConnError(CONN_AUTH_FAILED, "Authentication failed. Check connection parameters?");
+ logMsg << "]. Check connection parameters?";
+ return handleConnError(CONN_AUTH_FAILED, logMsg.str().c_str());
}
}
void DrillClientImpl::initiateAuthentication() {
exec::shared::SaslMessage response;
- m_saslResultCode = m_saslAuthenticator->init(m_serverAuthMechanisms, response);
-
+ m_saslResultCode = m_saslAuthenticator->init(m_serverAuthMechanisms, response, &m_encryptionCtxt);
switch (m_saslResultCode) {
case SASL_CONTINUE:
@@ -539,7 +741,7 @@ void DrillClientImpl::sendSaslResponse(const exec::shared::SaslMessage& response
boost::lock_guard<boost::mutex> lock(m_dcMutex);
const int32_t coordId = getNextCoordinationId();
rpc::OutBoundRpcMessage msg(exec::rpc::REQUEST, exec::user::SASL_MESSAGE, coordId, &response);
- sendSync(msg);
+ sendSyncCommon(msg);
if (m_pendingRequests++ == 0) {
getNextResult();
}
@@ -768,23 +970,23 @@ Handle* DrillClientImpl::sendMsg(boost::function<Handle*(int32_t)> handleFactory
phandle = handleFactory(coordId);
this->m_queryHandles[coordId]=phandle;
- connectionStatus_t cStatus=sendSync(out_msg);
+ connectionStatus_t cStatus = sendSyncCommon(out_msg);
if(cStatus == CONN_SUCCESS){
bool sendRequest=false;
DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Sent " << ::exec::user::RpcType_Name(type) << " request. " << "[" << m_connectedHost << "]" << "Coordination id = " << coordId << std::endl;)
- DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Sent " << ::exec::user::RpcType_Name(type) << " Coordination id = " << coordId << " query: " << phandle->getQuery() << std::endl;)
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Sent " << ::exec::user::RpcType_Name(type) << " Coordination id = " << coordId << " query: " << phandle->getQuery() << std::endl;)
- if(m_pendingRequests++==0){
- sendRequest=true;
- }else{
- DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Queuing " << ::exec::user::RpcType_Name(type) << " request to server" << std::endl;)
- DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Number of pending requests = " << m_pendingRequests << std::endl;)
- }
+ if(m_pendingRequests++==0){
+ sendRequest=true;
+ }else{
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Queuing " << ::exec::user::RpcType_Name(type) << " request to server" << std::endl;)
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Number of pending requests = " << m_pendingRequests << std::endl;)
+ }
if(sendRequest){
DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "Sending " << ::exec::user::RpcType_Name(type) << " request. Number of pending requests = "
<< m_pendingRequests << std::endl;)
- getNextResult(); // async wait for results
+ getNextResult(); // async wait for results
}
}
@@ -854,76 +1056,319 @@ void DrillClientImpl::waitForResults(){
}
}
-status_t DrillClientImpl::readMsg(ByteBuf_t _buf,
- AllocatedBufferPtr* allocatedBuffer,
- rpc::InBoundRpcMessage& msg){
+/*
+ * Decode the length of the message from bufWithLen and then read entire message from the socket.
+ * Parameters:
+ * bufWithLenField - in param - buffer containing the length of the RPC message/encrypted chunk
+ * bufferWithDataAndLenBytes - out param - buffer pointer which points to memory allocated in this function and has the
+ * entire one RPC message / encrypted chunk along with the length of the message.
+ * Memory for this buffer is released by caller.
+ * lengthFieldLength - out param - bytes of bufWithLen which contains the length of the entire RPC message or
+ * encrypted chunk
+ * lengthDecodeHandler - in param - function pointer with length decoder to use. For encrypted chunk we use
+ * lengthDecode and for plain RPC message we use rpcLengthDecode.
+ * Return:
+ * status_t - QRY_SUCCESS - In case of success.
+ * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error.
+ */
+status_t DrillClientImpl::readLenBytesFromSocket(const ByteBuf_t bufWithLenField, AllocatedBufferPtr* bufferWithDataAndLenBytes,
+ uint32_t& lengthFieldLength, lengthDecoder lengthDecodeHandler) {
+
+ uint32_t rmsgLen = 0;
+ boost::system::error_code error;
+ *bufferWithDataAndLenBytes = NULL;
+
+ // Decode the length field
+ lengthFieldLength = (this->*lengthDecodeHandler)(bufWithLenField, rmsgLen);
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Length bytes = " << lengthFieldLength << std::endl;)
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Msg Length = " << rmsgLen << std::endl;)
+
+ if(rmsgLen>0) {
+ const size_t leftover = LEN_PREFIX_BUFLEN - lengthFieldLength;
+
+ // Allocate a buffer for reading all the bytes in bufWithLen and length number of bytes.
+ const size_t bufferSizeWithLenBytes = rmsgLen + lengthFieldLength;
+ *bufferWithDataAndLenBytes = new AllocatedBuffer(bufferSizeWithLenBytes);
+
+ if(*bufferWithDataAndLenBytes == NULL) {
+ return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL);
+ }
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readLenBytesFromSocket: Allocated and locked buffer: [ "
+ << *bufferWithDataAndLenBytes << ", size = " << bufferSizeWithLenBytes << " ]\n";)
+
+ // Copy the memory of bufWithLen into bufferWithLenBytesSize
+ memcpy((*bufferWithDataAndLenBytes)->m_pBuffer, bufWithLenField, LEN_PREFIX_BUFLEN);
+ const size_t bytesToRead = rmsgLen - leftover;
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Copied bufWithLen into bufferWithLenBytes. "
+ << "Now reading data (rmsgLen - leftover) : " << bytesToRead
+ << std::endl;)
+
+ // Read the entire data left from socket and copy to currentBuffer.
+ const ByteBuf_t b = (*bufferWithDataAndLenBytes)->m_pBuffer + LEN_PREFIX_BUFLEN;
+ doReadFromSocket(b, bytesToRead, error);
+ } else {
+ return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL);
+ }
+
+ return error ? handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL)
+ : QRY_SUCCESS;
+}
+
+
+/*
+ * Function to read entire RPC message from socket and decode it to InboundRpcMessage
+ * Parameters:
+ * inBuf - in param - Buffer containing the length bytes.
+ * allocatedBuffer - out param - Buffer containing the length bytes and entire RPC message bytes.
+ * msg - out param - Decoded InBoundRpcMessage from the bytes in allocatedBuffer
+ * Return:
+ * status_t - QRY_SUCCESS - In case of success.
+ * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error.
+ */
+status_t DrillClientImpl::readMsg(const ByteBuf_t inBuf, AllocatedBufferPtr* allocatedBuffer,
+ rpc::InBoundRpcMessage& msg){
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readMsg: Read message from buffer "
- << reinterpret_cast<int*>(_buf) << std::endl;)
- size_t leftover=0;
- uint32_t rmsgLen;
- AllocatedBufferPtr currentBuffer;
- *allocatedBuffer=NULL;
+ << reinterpret_cast<int*>(inBuf) << std::endl;)
+ *allocatedBuffer = NULL;
+ {
+ // We need to protect the readLength and read buffer, and the pending requests counter,
+ // but we don't have to keep the lock while we decode the rest of the buffer.
+ boost::lock_guard<boost::mutex> lock(this->m_dcMutex);
+ uint32_t lengthFieldSize = 0;
+
+ // Read the message length and extract length size bytes to form InBoundRpcMessage
+ const status_t statusCode = readLenBytesFromSocket(inBuf, allocatedBuffer, lengthFieldSize,
+ &DrillClientImpl::rpcLengthDecode);
+
+ // Check for error conditions
+ if(QRY_SUCCESS != statusCode) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return statusCode;
+ }
+
+ // Get the message size
+ size_t msgLen = (*allocatedBuffer)->m_bufSize;
+
+ // Read data successfully, now let's try to decode the buffer and form a valid RPC message.
+ // allocatedBuffer also contains the length bytes which is not needed by decodes so skip that part of buffer.
+ // We have it since in case of encryption the unwrap function expects it
+ if (!decode((*allocatedBuffer)->m_pBuffer + lengthFieldSize, msgLen - lengthFieldSize, msg)) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, "Cannot decode server message"), NULL);
+ }
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Successfully created a RPC message with Coordination id: "
+ << msg.m_coord_id << std::endl;)
+ }
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readMsg: Free buffer "
+ << reinterpret_cast<int*>(inBuf) << std::endl;)
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return QRY_SUCCESS;
+}
+
+
+/*
+ * Read ENCRYPT_LEN_PREFIX_BUFLEN bytes to decode length of one complete encrypted chunk. The length bytes are expected
+ * to be in network order. It is converted to host order and the value is stored in rmsgLen parameter.
+ * Parameters:
+ * inBuf - in param - ByteBuf_t containing atleast the length bytes.
+ * rmsgLen - out param - Contain the decoded value of length.
+ * Return:
+ * size_t - length bytes read to decode
+ */
+size_t DrillClientImpl::lengthDecode(const ByteBuf_t inBuf, uint32_t& rmsgLen) {
+ memcpy(&rmsgLen, inBuf, ENCRYPT_LEN_PREFIX_BUFLEN);
+ rmsgLen = ntohl(rmsgLen);
+ return ENCRYPT_LEN_PREFIX_BUFLEN;
+}
+
+/*
+ * Wrapper which uses RPC message length decoder to get length of one complete RPC message from _buf.
+ * Parameters:
+ * inBuf - in param - ByteBuf_t containing atleast the length bytes.
+ * rmsgLen - out param - Contain the decoded value of length.
+ * Return:
+ * size_t - length bytes read to decode
+ */
+size_t DrillClientImpl::rpcLengthDecode(const ByteBuf_t inBuf, uint32_t& rmsgLen) {
+ return rpc::lengthDecode(inBuf, rmsgLen);
+}
+
+
+/*
+ * Read all the encrypted chunk needed to form a complete RPC message. Read an entire chunk from network, decrypt it
+ * and put in a buffer. The same process is repeated until the entire buffer to form a completed RPC message is read.
+ * Parameters:
+ * inBuf - in param - ByteBuf_t containing atleast the length bytes.
+ * allocatedBuffer - out param - Buffer containing the entire RPC message bytes which is formed by reading all the
+ * required encrypted chunk from network and decrypting each individual chunk. The
+ * buffer memory is released by caller.
+.* msg - out param - InBoundRpcMessage formed from bytes in allocatedBuffer
+ * Return:
+ * status_t - QRY_SUCCESS - In case of success.
+ * - QRY_COMM_ERROR/QRY_INTERNAL_ERROR/QRY_CLIENT_OUTOFMEM - In cases of error.
+ */
+status_t DrillClientImpl::readAndDecryptMsg(const ByteBuf_t inBuf, AllocatedBufferPtr* allocatedBuffer,
+ rpc::InBoundRpcMessage& msg) {
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Read message from buffer "
+ << reinterpret_cast<int*>(inBuf) << std::endl;)
+
+ size_t leftover = 0;
+ uint32_t rpcMsgLen = 0;
+ size_t bytes_read = 0;
+ uint32_t writeIndex = 0;
+ size_t bytesToRead = 0;
+
+ *allocatedBuffer = NULL;
+ boost::system::error_code error;
+ std::stringstream errorMsg;
+
{
// We need to protect the readLength and read buffer, and the pending requests counter,
// but we don't have to keep the lock while we decode the rest of the buffer.
boost::lock_guard<boost::mutex> lock(this->m_dcMutex);
- std::size_t bytes_read = rpc::lengthDecode(_buf, rmsgLen);
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "len bytes = " << bytes_read << std::endl;)
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "rmsgLen = " << rmsgLen << std::endl;)
-
- if(rmsgLen>0){
- leftover = LEN_PREFIX_BUFLEN - bytes_read;
- // Allocate a buffer
- currentBuffer=new AllocatedBuffer(rmsgLen);
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readMsg: Allocated and locked buffer: [ "
- << currentBuffer << ", size = " << rmsgLen << " ]\n";)
- if(currentBuffer==NULL){
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
- return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL);
+
+ do{
+ AllocatedBufferPtr currentBuffer = NULL;
+ uint32_t lengthFieldSize = 0;
+ const status_t statusCode = readLenBytesFromSocket(inBuf, &currentBuffer, lengthFieldSize,
+ &DrillClientImpl::lengthDecode);
+
+ if(QRY_SUCCESS != statusCode) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+
+ // Release the buffer allocated to hold chunk
+ if(currentBuffer != NULL) {
+ Utils::freeBuffer(currentBuffer->m_pBuffer, currentBuffer->m_bufSize);
+ currentBuffer = NULL;
+ }
+ return statusCode;
}
- *allocatedBuffer=currentBuffer;
- if(leftover){
- memcpy(currentBuffer->m_pBuffer, _buf + bytes_read, leftover);
+
+ // read one chunk successfully. Let's try to decrypt the message
+ const char* unWrappedData = NULL;
+ uint32_t unWrappedLen = 0;
+ const int decryptResult = m_saslAuthenticator->unwrap(reinterpret_cast<const char*>(currentBuffer->m_pBuffer),
+ currentBuffer->m_bufSize, &unWrappedData, unWrappedLen);
+
+ if(SASL_OK != decryptResult) {
+
+ errorMsg << "Sasl unwrap failed for the buffer of size:" << currentBuffer->m_bufSize << " , Error: "
+ << decryptResult;
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "DrillClientImpl::readAndDecryptMsg: "
+ << errorMsg.str() << std::endl;)
+
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+
+ // Release the buffer allocated to hold chunk
+ Utils::freeBuffer(currentBuffer->m_pBuffer, currentBuffer->m_bufSize);
+ currentBuffer = NULL;
+ return handleQryError(QRY_COMM_ERROR,
+ getMessage(ERR_QRY_COMMERR, errorMsg.str().c_str()), NULL);
}
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "reading data (rmsgLen - leftover) : "
- << (rmsgLen - leftover) << std::endl;)
- ByteBuf_t b=currentBuffer->m_pBuffer + leftover;
- size_t bytesToRead=rmsgLen - leftover;
- boost::system::error_code error;
- while(1){
- size_t dataBytesRead=this->m_socket.read_some(
- boost::asio::buffer(b, bytesToRead),
- error);
- if(error) break;
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Data Message: actual bytes read = " << dataBytesRead << std::endl;)
- if(dataBytesRead==bytesToRead) break;
- bytesToRead-=dataBytesRead;
- b+=dataBytesRead;
+
+ // Check for case if the unWrappedLen is 0, since Cyrus SASL plugin verifies if the length of wrapped data
+ // is less than the length specified by prepended 4 octets as per RFC 4422/2222. If so it just returns
+ // and waits for more data
+ if(unWrappedLen == 0 || (unWrappedData == NULL)) {
+ errorMsg << "Sasl unwrap failed with mismatch in length of wrapped data and the prepended length value";
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "DrillClientImpl::readAndDecryptMsg: " << errorMsg.str()
+ << std::endl;)
+
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+
+ // Release the buffer allocated to hold chunk
+ Utils::freeBuffer(currentBuffer->m_pBuffer, currentBuffer->m_bufSize);
+ currentBuffer = NULL;
+ return handleQryError(QRY_COMM_ERROR,
+ getMessage(ERR_QRY_COMMERR, errorMsg.str().c_str()), NULL);
}
- if(!error){
- // read data successfully
- if (!decode(currentBuffer->m_pBuffer, rmsgLen, msg)) {
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
- return handleQryError(QRY_COMM_ERROR,
- getMessage(ERR_QRY_COMMERR, "Cannot decode server message"), NULL);;
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Successfully decrypted the buffer"
+ << " Sizes - Before Decryption = " << currentBuffer->m_bufSize
+ << " and After Decryption = " << unWrappedLen << std::endl;)
+
+ // Release the buffer allocated to hold chunk
+ Utils::freeBuffer(currentBuffer->m_pBuffer, currentBuffer->m_bufSize);
+ currentBuffer = NULL;
+
+ bytes_read = 0;
+ if(*allocatedBuffer == NULL) {
+ // This is the first chunk of the RPC message. We will decode the RPC message full length
+ bytes_read = rpcLengthDecode(reinterpret_cast<ByteBuf_t>(const_cast<char*>(unWrappedData)), rpcMsgLen);
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Rpc Message Length bytes = "
+ << bytes_read << std::endl;)
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Rpc Message Length = "
+ << rpcMsgLen << std::endl;)
+
+ if(rpcMsgLen == 0) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL);
}
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Done decoding chunk. Coordination id: " <<msg.m_coord_id<< std::endl;)
- }else{
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
- return handleQryError(QRY_COMM_ERROR,
- getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL);
+ // Allocate a buffer for storing full RPC message. This is released by the caller
+ *allocatedBuffer = new AllocatedBuffer(rpcMsgLen);
+
+ if(*allocatedBuffer == NULL){
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return handleQryError(QRY_CLIENT_OUTOFMEM, getMessage(ERR_QRY_OUTOFMEM), NULL);
+ }
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Allocated and locked buffer:"
+ << "[ " << *allocatedBuffer << ", size = " << rpcMsgLen << " ]\n";)
+
+ bytesToRead = rpcMsgLen;
}
- }else{
- // got a message with an invalid read length.
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
- return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVREADLEN), NULL);
+
+ // Update the leftover bytes that is not copied yet
+ leftover = unWrappedLen - bytes_read;
+
+ // Copy rest of decrypted message to the buffer. We can do this since it is assured that one
+ // entire decrypted chunk is part of the same RPC message.
+ if(leftover) {
+ memcpy((*allocatedBuffer)->m_pBuffer + writeIndex, unWrappedData + bytes_read, leftover);
+ }
+
+ // Update bytes left to read to form full RPC message.
+ bytesToRead -= leftover;
+ writeIndex += leftover;
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Left to read unencrypted data"
+ << " of length (bytesToRead) : " << bytesToRead << std::endl;)
+
+ if(bytesToRead > 0) {
+ // Read synchronously buffer of size LEN_PREFIX_BUFLEN to get length of next chunk
+ doReadFromSocket(inBuf, LEN_PREFIX_BUFLEN, error);
+
+ if(error) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR, error.message().c_str()), NULL);
+ }
+ }
+ }while(bytesToRead > 0); // more chunks to read for entire RPC message
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Done decrypting entire RPC message "
+ << " of length: " << rpcMsgLen << ". Now starting decode:" << std::endl;)
+
+ // Decode the buffer and form a RPC message
+ if (!decode((*allocatedBuffer)->m_pBuffer, rpcMsgLen, msg)) {
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
+ return handleQryError(QRY_COMM_ERROR, getMessage(ERR_QRY_COMMERR,
+ "Cannot decode server message into valid RPC message"), NULL);
}
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Successfully created a RPC message with Coordination id: "
+ << msg.m_coord_id << std::endl;)
}
- DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readMsg: Free buffer "
- << reinterpret_cast<int*>(_buf) << std::endl;)
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::readAndDecryptMsg: Free buffer "
+ << reinterpret_cast<int*>(inBuf) << std::endl;)
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
return QRY_SUCCESS;
}
@@ -1364,15 +1809,15 @@ status_t DrillClientImpl::processServerMetaResult(AllocatedBufferPtr allocatedBu
std::map<int,DrillClientQueryHandle*>::const_iterator it=this->m_queryHandles.find(msg.m_coord_id);
if(it!=this->m_queryHandles.end()){
DrillClientServerMetaHandle* pHandle=static_cast<DrillClientServerMetaHandle*>((*it).second);
+ exec::user::GetServerMetaResp* resp = new exec::user::GetServerMetaResp();
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Received GetServerMetaResp result Handle " << msg.m_pbody.size() << std::endl;)
- exec::user::GetServerMetaResp resp;
- if (!(resp.ParseFromArray(msg.m_pbody.data(), msg.m_pbody.size()))) {
+ if (!(resp->ParseFromArray(msg.m_pbody.data(), msg.m_pbody.size()))) {
return handleQryError(QRY_COMM_ERROR, "Cannot decode GetServerMetaResp results", pHandle);
}
- if (resp.status() != exec::user::OK) {
- return handleQryError(QRY_FAILED, resp.error(), pHandle);
+ if (resp->status() != exec::user::OK) {
+ return handleQryError(QRY_FAILED, resp->error(), pHandle);
}
- pHandle->notifyListener(&(resp.server_meta()), NULL);
+ pHandle->notifyListener(&(resp->server_meta()), NULL);
DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "GetServerMetaResp result " << std::endl;)
}else{
return handleQryError(QRY_INTERNAL_ERROR, getMessage(ERR_QRY_INVQUERYID), NULL);
@@ -1484,11 +1929,11 @@ void DrillClientImpl::handleReadTimeout(const boost::system::error_code & err){
return;
}
-void DrillClientImpl::handleRead(ByteBuf_t _buf,
+void DrillClientImpl::handleRead(ByteBuf_t inBuf,
const boost::system::error_code& error,
size_t bytes_transferred) {
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::handleRead: Handle Read from buffer "
- << reinterpret_cast<int*>(_buf) << std::endl;)
+ << reinterpret_cast<int*>(inBuf) << std::endl;)
if(DrillClientConfig::getQueryTimeout() > 0){
// Cancel the timeout if handleRead is called
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::handleRead: Cancel deadline timer.\n";)
@@ -1496,7 +1941,7 @@ void DrillClientImpl::handleRead(ByteBuf_t _buf,
}
if (error) {
// boost error
- Utils::freeBuffer(_buf, LEN_PREFIX_BUFLEN);
+ Utils::freeBuffer(inBuf, LEN_PREFIX_BUFLEN);
boost::lock_guard<boost::mutex> lock(this->m_dcMutex);
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "DrillClientImpl::handleRead: ERR_QRY_COMMERR. "
"Boost Communication Error: " << error.message() << std::endl;)
@@ -1510,7 +1955,7 @@ void DrillClientImpl::handleRead(ByteBuf_t _buf,
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Getting new message" << std::endl;)
AllocatedBufferPtr allocatedBuffer=NULL;
- if(readMsg(_buf, &allocatedBuffer, msg)!=QRY_SUCCESS){
+ if((this->*m_fpCurrentReadMsgHandler)(inBuf, &allocatedBuffer, msg)!=QRY_SUCCESS){
delete allocatedBuffer;
if(m_pendingRequests!=0){
boost::lock_guard<boost::mutex> lock(this->m_dcMutex);
@@ -1655,6 +2100,9 @@ status_t DrillClientImpl::validateResultMessage(const rpc::InBoundRpcMessage& ms
return QRY_SUCCESS;
}
+/*
+ * Called when there is failure in connect/send.
+ */
connectionStatus_t DrillClientImpl::handleConnError(connectionStatus_t status, const std::string& msg){
DrillClientError* pErr = new DrillClientError(status, DrillClientError::CONN_ERROR_START+status, msg);
m_pendingRequests=0;
@@ -1669,19 +2117,28 @@ connectionStatus_t DrillClientImpl::handleConnError(connectionStatus_t status, c
return status;
}
+/*
+ * Always called with NULL QueryHandle when there is any error while reading data from socket. Once enough data is read
+ * and a valid RPC message is formed then it can get called with NULL/valid QueryHandle depending on if QueryHandle is found
+ * for the created RPC message.
+ */
status_t DrillClientImpl::handleQryError(status_t status, const std::string& msg, DrillClientQueryHandle* pQueryHandle){
DrillClientError* pErr = new DrillClientError(status, DrillClientError::QRY_ERROR_START+status, msg);
- // set query error only if queries are running
+ // Set query error only if queries are running. If valid QueryHandle that means the bytes to form a valid
+ // RPC message was read successfully from socket. So there is no socket/connection issues.
if(pQueryHandle!=NULL){
m_pendingRequests--;
pQueryHandle->signalError(pErr);
- }else{
+ }else{ // This means error was while reading from socket, hence call broadcastError which eventually closes socket.
m_pendingRequests=0;
broadcastError(pErr);
}
return status;
}
+/*
+ * Always called with valid QueryHandle when there is any error processing Query related data.
+ */
status_t DrillClientImpl::handleQryError(status_t status,
const exec::shared::DrillPBError& e,
DrillClientQueryHandle* pQueryHandle){
@@ -1766,7 +2223,7 @@ void DrillClientImpl::sendAck(const rpc::InBoundRpcMessage& msg, bool isOk){
ack.set_ok(isOk);
rpc::OutBoundRpcMessage ack_msg(exec::rpc::RESPONSE, exec::user::ACK, msg.m_coord_id, &ack);
boost::lock_guard<boost::mutex> lock(m_dcMutex);
- sendSync(ack_msg);
+ sendSyncCommon(ack_msg);
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "ACK sent" << std::endl;)
}
@@ -1774,7 +2231,7 @@ void DrillClientImpl::sendCancel(const exec::shared::QueryId* pQueryId){
boost::lock_guard<boost::mutex> lock(m_dcMutex);
uint64_t coordId = this->getNextCoordinationId();
rpc::OutBoundRpcMessage cancel_msg(exec::rpc::REQUEST, exec::user::CANCEL_QUERY, coordId, pQueryId);
- sendSync(cancel_msg);
+ sendSyncCommon(cancel_msg);
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "CANCEL sent" << std::endl;)
}
@@ -1783,6 +2240,21 @@ void DrillClientImpl::shutdownSocket(){
boost::system::error_code ignorederr;
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignorederr);
m_bIsConnected=false;
+
+ // Delete the saslAuthenticatorImpl instance since connection is broken. It will recreated on next
+ // call to connect.
+ if(m_saslAuthenticator != NULL) {
+ delete m_saslAuthenticator;
+ m_saslAuthenticator = NULL;
+ }
+
+ // Reset the SASL states.
+ m_saslDone = false;
+ m_saslResultCode = SASL_OK;
+
+ // Reset the encryption context since connection is invalid
+ m_encryptionCtxt.reset();
+
DRILL_MT_LOG(DRILL_LOG(LOG_TRACE) << "Socket shutdown" << std::endl;)
}
@@ -1799,8 +2271,6 @@ struct ServerMetaContext {
boost::mutex m_mutex;
boost::condition_variable m_cv;
- ServerMetaContext(): m_done(false), m_status(QRY_SUCCESS), m_serverMeta(), m_mutex(), m_cv() {};
-
static status_t listener(void* ctx, const exec::user::ServerMeta* serverMeta, DrillClientError* err) {
ServerMetaContext* context = static_cast<ServerMetaContext*>(ctx);
if (err) {
diff --git a/contrib/native/client/src/clientlib/drillClientImpl.hpp b/contrib/native/client/src/clientlib/drillClientImpl.hpp
index d37076e6a..852233f8b 100644
--- a/contrib/native/client/src/clientlib/drillClientImpl.hpp
+++ b/contrib/native/client/src/clientlib/drillClientImpl.hpp
@@ -368,16 +368,17 @@ class DrillClientColumnResult: public DrillClientMetadataResult<Metadata::pfnCol
DrillClientMetadataResult<Metadata::pfnColumnMetadataListener, meta::ColumnMetadata, meta::DrillColumnMetadata, exec::user::GetColumnsResp>(client, coordId, "getColumns", listener, listenerCtx) {}
};
+// Length Decoder Function Pointer definition
+typedef size_t (DrillClientImpl::*lengthDecoder)(const ByteBuf_t, uint32_t&);
class DrillClientImpl : public DrillClientImplBase{
public:
DrillClientImpl():
- m_coordinationId(1),
m_handshakeVersion(0),
m_handshakeStatus(exec::user::SUCCESS),
m_bIsConnected(false),
m_saslAuthenticator(NULL),
- m_saslResultCode(SASL_OK),
+ m_saslResultCode(SASL_OK),
m_saslDone(false),
m_pendingRequests(0),
m_pError(NULL),
@@ -388,9 +389,11 @@ class DrillClientImpl : public DrillClientImplBase{
m_heartbeatTimer(m_io_service),
m_rbuf(NULL),
m_wbuf(MAX_SOCK_RD_BUFSIZE),
- m_bIsDirectConnection(false)
+ m_bIsDirectConnection(false)
{
m_coordinationId=rand()%1729+1;
+ m_fpCurrentReadMsgHandler = &DrillClientImpl::readMsg;
+ m_fpCurrentSendHandler = &DrillClientImpl::sendSyncPlain;
};
~DrillClientImpl(){
@@ -477,9 +480,10 @@ class DrillClientImpl : public DrillClientImplBase{
void handleHeartbeatTimeout(const boost::system::error_code & err); // send a heartbeat. If send fails, broadcast error, close connection and bail out.
int32_t getNextCoordinationId(){ return ++m_coordinationId; };
- // send synchronous messages
- //connectionStatus_t recvSync(rpc::InBoundRpcMessage& msg);
- connectionStatus_t sendSync(rpc::OutBoundRpcMessage& msg);
+ // synchronous message send handlers
+ connectionStatus_t sendSyncCommon(rpc::OutBoundRpcMessage& msg);
+ connectionStatus_t sendSyncPlain();
+ connectionStatus_t sendSyncEncrypted();
// handshake
connectionStatus_t recvHandshake();
void handleHandshake(ByteBuf_t b, const boost::system::error_code& err, std::size_t bytes_transferred );
@@ -488,10 +492,16 @@ class DrillClientImpl : public DrillClientImplBase{
void startMessageListener();
// Query results
void getNextResult();
- status_t readMsg(
- ByteBuf_t _buf,
- AllocatedBufferPtr* allocatedBuffer,
- rpc::InBoundRpcMessage& msg);
+ // Read Message Handlers
+ status_t readMsg(const ByteBuf_t inBuf, AllocatedBufferPtr* allocatedBuffer, rpc::InBoundRpcMessage& msg);
+ status_t readAndDecryptMsg(const ByteBuf_t inBuf, AllocatedBufferPtr* allocatedBuffer, rpc::InBoundRpcMessage& msg);
+ status_t readLenBytesFromSocket(const ByteBuf_t bufWithLenField, AllocatedBufferPtr* bufferWithDataAndLenBytes,
+ uint32_t& lengthFieldLength, lengthDecoder lengthDecodeHandler);
+ void doReadFromSocket(ByteBuf_t inBuf, size_t bytesToRead, boost::system::error_code& errorCode);
+ void doWriteToSocket(const char* dataPtr, size_t bytesToWrite, boost::system::error_code& errorCode);
+ // Length decode handlers
+ size_t lengthDecode(const ByteBuf_t inBuf, uint32_t& rmsgLen);
+ size_t rpcLengthDecode(const ByteBuf_t inBuf, uint32_t& rmsgLen);
status_t processQueryResult(AllocatedBufferPtr allocatedBuffer, const rpc::InBoundRpcMessage& msg);
status_t processQueryData(AllocatedBufferPtr allocatedBuffer, const rpc::InBoundRpcMessage& msg);
status_t processCancelledQueryResult( exec::shared::QueryId& qid, exec::shared::QueryResult* qr);
@@ -506,7 +516,7 @@ class DrillClientImpl : public DrillClientImplBase{
status_t processQueryStatusResult( exec::shared::QueryResult* qr,
DrillClientQueryResult* pDrillClientQueryResult);
void handleReadTimeout(const boost::system::error_code & err);
- void handleRead(ByteBuf_t _buf, const boost::system::error_code & err, size_t bytes_transferred) ;
+ void handleRead(ByteBuf_t inBuf, const boost::system::error_code & err, size_t bytes_transferred) ;
status_t validateDataMessage(const rpc::InBoundRpcMessage& msg, const exec::shared::QueryData& qd, std::string& valError);
status_t validateResultMessage(const rpc::InBoundRpcMessage& msg, const exec::shared::QueryResult& qr, std::string& valError);
connectionStatus_t handleConnError(connectionStatus_t status, const std::string& msg);
@@ -540,6 +550,7 @@ class DrillClientImpl : public DrillClientImplBase{
void finishAuthentication();
void shutdownSocket();
+ bool clientNeedsEncryption(const DrillUserProperties* userProperties);
int32_t m_coordinationId;
int32_t m_handshakeVersion;
@@ -557,6 +568,14 @@ class DrillClientImpl : public DrillClientImplBase{
boost::mutex m_saslMutex; // mutex to protect m_saslDone
boost::condition_variable m_saslCv; // to signal completion of SASL exchange
+ // Used for encryption and is set when server notifies in first handshake response.
+ EncryptionContext m_encryptionCtxt;
+
+ // Function pointer for read and send handler. By default these are referred to handler for plain message read/send. When encryption is enabled
+ // then after successful handshake these pointers refer to handler for encrypted message read/send over wire.
+ status_t (DrillClientImpl::*m_fpCurrentReadMsgHandler)(ByteBuf_t inBuf, AllocatedBufferPtr* allocatedBuffer, rpc::InBoundRpcMessage& msg);
+ connectionStatus_t (DrillClientImpl::*m_fpCurrentSendHandler)();
+
std::string m_connectStr;
//
diff --git a/contrib/native/client/src/clientlib/rpcMessage.cpp b/contrib/native/client/src/clientlib/rpcMessage.cpp
index 13cd7a82e..f64167f5a 100644
--- a/contrib/native/client/src/clientlib/rpcMessage.cpp
+++ b/contrib/native/client/src/clientlib/rpcMessage.cpp
@@ -47,7 +47,7 @@ std::size_t lengthDecode(const uint8_t* buf, uint32_t& length) {
// read the frame to get the length of the message and then
- CodedInputStream cis(buf, 5); // read 5 bytes at most
+ CodedInputStream cis(buf, LEN_PREFIX_BUFLEN); // read LEN_PREFIX_BUFLEN bytes at most
int startPos(cis.CurrentPosition()); // for debugging
if (!cis.ReadVarint32(&length)) {
diff --git a/contrib/native/client/src/clientlib/rpcMessage.hpp b/contrib/native/client/src/clientlib/rpcMessage.hpp
index 15487e9ba..43bcaeb13 100644
--- a/contrib/native/client/src/clientlib/rpcMessage.hpp
+++ b/contrib/native/client/src/clientlib/rpcMessage.hpp
@@ -54,7 +54,6 @@ std::size_t lengthDecode(const uint8_t* buf, uint32_t& length);
bool decode(const uint8_t* buf, int length, InBoundRpcMessage& msg);
bool encode(DataBuf& buf, const OutBoundRpcMessage& msg);
-
} // namespace rpc
} // namespace Drill
diff --git a/contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp b/contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp
index e7e2ba594..c5dc3aced 100644
--- a/contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp
+++ b/contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp
@@ -32,6 +32,7 @@ static const std::string DEFAULT_SERVICE_NAME = "drill";
static const std::string KERBEROS_SIMPLE_NAME = "kerberos";
static const std::string KERBEROS_SASL_NAME = "gssapi";
static const std::string PLAIN_NAME = "plain";
+static const int PREFERRED_MIN_SSF = 56;
const std::map<std::string, std::string> SaslAuthenticatorImpl::MECHANISM_MAPPING = boost::assign::map_list_of
(KERBEROS_SIMPLE_NAME, KERBEROS_SASL_NAME)
@@ -42,8 +43,7 @@ boost::mutex SaslAuthenticatorImpl::s_mutex;
bool SaslAuthenticatorImpl::s_initialized = false;
SaslAuthenticatorImpl::SaslAuthenticatorImpl(const DrillUserProperties* const properties) :
- m_pUserProperties(properties), m_pConnection(NULL), m_ppwdSecret(NULL) {
-
+ m_pUserProperties(properties), m_pConnection(NULL), m_ppwdSecret(NULL), m_pEncryptCtxt(NULL) {
if (!s_initialized) {
boost::lock_guard<boost::mutex> lock(SaslAuthenticatorImpl::s_mutex);
if (!s_initialized) {
@@ -85,6 +85,9 @@ SaslAuthenticatorImpl::~SaslAuthenticatorImpl() {
sasl_dispose(&m_pConnection);
}
m_pConnection = NULL;
+
+ // Memory is owned by DrillClientImpl object
+ m_pEncryptCtxt = NULL;
}
typedef int (*sasl_callback_proc_t)(void); // see sasl_callback_ft
@@ -109,8 +112,14 @@ int SaslAuthenticatorImpl::passwordCallback(sasl_conn_t *conn, void *context, in
return SASL_OK;
}
-int SaslAuthenticatorImpl::init(const std::vector<std::string>& mechanisms, exec::shared::SaslMessage& response) {
- // find and set parameters
+int SaslAuthenticatorImpl::init(const std::vector<std::string>& mechanisms, exec::shared::SaslMessage& response,
+ EncryptionContext* const encryptCtxt) {
+
+ // EncryptionContext should not be NULL here.
+ assert(encryptCtxt != NULL);
+ m_pEncryptCtxt = encryptCtxt;
+
+ // find and set parameters
std::string authMechanismToUse;
std::string serviceName;
std::string serviceHost;
@@ -163,6 +172,9 @@ int SaslAuthenticatorImpl::init(const std::vector<std::string>& mechanisms, exec
<< saslResult << std::endl;)
if (saslResult != SASL_OK) return saslResult;
+ // set the security properties
+ setSecurityProps();
+
// initiate; for now, pass in only one mechanism
const char *out;
unsigned outlen;
@@ -204,4 +216,103 @@ int SaslAuthenticatorImpl::step(const exec::shared::SaslMessage& challenge, exec
return saslResult;
}
+/*
+ * Verify that the negotiated value is correct as per system configurations. Also retrieves and set the rawWrapSendSize
+ */
+int SaslAuthenticatorImpl::verifyAndUpdateSaslProps() {
+ const int* negotiatedValue;
+ int result = SASL_OK;
+
+ if(SASL_OK != (result = sasl_getprop(m_pConnection, SASL_SSF, reinterpret_cast<const void **>(&negotiatedValue)))) {
+ return result;
+ }
+
+ // If the negotiated SSF value is less than required one that means we have negotiated for weaker security level.
+ if(*negotiatedValue < PREFERRED_MIN_SSF) {
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "SaslAuthenticatorImpl::verifyAndUpdateSaslProps: "
+ << "Negotiated SSF parameter:" << *negotiatedValue
+ << " is less than Preferred one: " << PREFERRED_MIN_SSF << std::endl;)
+ result = SASL_BADPARAM;
+ return result;
+ }
+
+ if(SASL_OK != (result = sasl_getprop(m_pConnection, SASL_MAXOUTBUF,
+ reinterpret_cast<const void **>(&negotiatedValue)))) {
+ return result;
+ }
+
+ DRILL_MT_LOG(DRILL_LOG(LOG_DEBUG) << "SaslAuthenticatorImpl::verifyAndUpdateSaslProps: "
+ << "Negotiated Raw Wrap Buffer size: " << *negotiatedValue << std::endl;)
+
+ m_pEncryptCtxt->setWrapSizeLimit(*negotiatedValue);
+ return result;
+}
+
+/*
+ * Set the security properties structure with all the needed parameters for encryption so that
+ * a proper mechanism with and cipher is chosen after handshake.
+ *
+ * PREFERRED_MIN_SSF is chosen to be 56 since that is the max_ssf supported by gssapi. We want
+ * stronger cipher algorithm to be used all the time (preferably AES-256), so leaving MAX_SSF as UINT_MAX
+ */
+void SaslAuthenticatorImpl::setSecurityProps() const{
+
+ if(m_pEncryptCtxt->isEncryptionReqd()) {
+ // set the security properties.
+ sasl_security_properties_t secprops;
+ secprops.min_ssf = PREFERRED_MIN_SSF;
+ secprops.max_ssf = UINT_MAX;
+ secprops.maxbufsize = m_pEncryptCtxt->getMaxWrappedSize();
+ secprops.property_names = NULL;
+ secprops.property_values = NULL;
+ // Only specify NOPLAINTEXT for encryption since the mechanism is selected based on name not
+ // the security properties configured here.
+ secprops.security_flags = SASL_SEC_NOPLAINTEXT;
+
+ // Set the security properties in the connection context.
+ sasl_setprop(m_pConnection, SASL_SEC_PROPS, &secprops);
+ }
+}
+
+/*
+ * Encodes the input data by calling the sasl_encode provided by Cyrus-SASL library which internally calls
+ * the wrap function of the chosen mechanism. The output buffer will have first 4 octets as the length of
+ * encrypted data in network byte order.
+ *
+ * Parameters:
+ * dataToWrap - in param - pointer to data buffer to encrypt.
+ * dataToWrapLen - in param - length of data buffer to encrypt.
+ * output - out param - pointer to data buffer with encrypted data. Allocated by Cyrus-SASL
+ * wrappedLen - out param - length of data after encryption
+ * Returns:
+ * SASL_OK - success (returns input if no layer negotiated)
+ * SASL_NOTDONE - security layer negotiation not finished
+ * SASL_BADPARAM - inputlen is greater than the SASL_MAXOUTBUF
+ */
+int SaslAuthenticatorImpl::wrap(const char* dataToWrap, const int& dataToWrapLen, const char** output,
+ uint32_t& wrappedLen) {
+ return sasl_encode(m_pConnection, dataToWrap, dataToWrapLen, output, &wrappedLen);
+}
+
+/*
+ * Decodes the input data by calling the sasl_decode provided by Cyrus-SASL library which internally calls
+ * the wrap function of the chosen mechanism. The input buffer will have first 4 octets as the length of
+ * encrypted data in network byte order.
+ *
+ * Parameters:
+ * dataToUnWrap - in param - pointer to data buffer to decrypt.
+ * dataToUnWrapLen - in param - length of data buffer to decrypt.
+ * output - out param - pointer to data buffer with decrypted data. Allocated by Cyrus-SASL
+ * unWrappedLen - out param - length of data after decryption
+ * Returns:
+ * SASL_OK - success (returns input if no layer negotiated)
+ * SASL_NOTDONE - security layer negotiation not finished
+ * SASL_BADPARAM - inputlen is greater than the SASL_MAXOUTBUF
+ */
+int SaslAuthenticatorImpl::unwrap(const char* dataToUnWrap, const int& dataToUnWrapLen, const char** output,
+ uint32_t& unWrappedLen) {
+ return sasl_decode(m_pConnection, dataToUnWrap, dataToUnWrapLen, output, &unWrappedLen);
+}
+
+
} /* namespace Drill */
diff --git a/contrib/native/client/src/clientlib/saslAuthenticatorImpl.hpp b/contrib/native/client/src/clientlib/saslAuthenticatorImpl.hpp
index 5e36ee123..53fe4e362 100644
--- a/contrib/native/client/src/clientlib/saslAuthenticatorImpl.hpp
+++ b/contrib/native/client/src/clientlib/saslAuthenticatorImpl.hpp
@@ -24,6 +24,7 @@
#include <vector>
#include "drill/drillClient.hpp"
#include "UserBitShared.pb.h"
+#include "utils.hpp"
#include "sasl/sasl.h"
#include "sasl/saslplug.h"
@@ -38,10 +39,17 @@ public:
~SaslAuthenticatorImpl();
- int init(const std::vector<std::string>& mechanisms, exec::shared::SaslMessage& response);
+ int init(const std::vector<std::string>& mechanisms, exec::shared::SaslMessage& response,
+ EncryptionContext* const encryptCtxt);
int step(const exec::shared::SaslMessage& challenge, exec::shared::SaslMessage& response) const;
+ int verifyAndUpdateSaslProps();
+
+ int wrap(const char* dataToWrap, const int& dataToWrapLen, const char** output, uint32_t& wrappedLen);
+
+ int unwrap(const char* dataToUnWrap, const int& dataToUnWrapLen, const char** output, uint32_t& unWrappedLen);
+
private:
static const std::map<std::string, std::string> MECHANISM_MAPPING;
@@ -53,11 +61,13 @@ private:
sasl_conn_t *m_pConnection;
std::string m_username;
sasl_secret_t *m_ppwdSecret;
+ EncryptionContext *m_pEncryptCtxt;
static int passwordCallback(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret);
static int userNameCallback(void *context, int id, const char **result, unsigned int *len);
+ void setSecurityProps() const;
};
} /* namespace Drill */
diff --git a/contrib/native/client/src/clientlib/utils.cpp b/contrib/native/client/src/clientlib/utils.cpp
index d3c8f08d7..11aa2c272 100644
--- a/contrib/native/client/src/clientlib/utils.cpp
+++ b/contrib/native/client/src/clientlib/utils.cpp
@@ -111,4 +111,53 @@ AllocatedBuffer::~AllocatedBuffer(){
m_bufSize = 0;
}
+EncryptionContext::EncryptionContext(const bool& encryptionReqd, const int& maxWrappedSize, const int& wrapSizeLimit) {
+ this->m_bEncryptionReqd = encryptionReqd;
+ this->m_maxWrappedSize = maxWrappedSize;
+ this->m_wrapSizeLimit = wrapSizeLimit;
+}
+
+EncryptionContext::EncryptionContext() {
+ this->m_bEncryptionReqd = false;
+ this->m_maxWrappedSize = 65536;
+ this->m_wrapSizeLimit = 0;
+}
+
+void EncryptionContext::setEncryptionReqd(const bool& encryptionReqd) {
+ this->m_bEncryptionReqd = encryptionReqd;
+}
+
+void EncryptionContext::setMaxWrappedSize(const int& maxWrappedSize) {
+ this->m_maxWrappedSize = maxWrappedSize;
+}
+
+void EncryptionContext::setWrapSizeLimit(const int& wrapSizeLimit) {
+ this->m_wrapSizeLimit = wrapSizeLimit;
+}
+
+bool EncryptionContext::isEncryptionReqd() const {
+ return m_bEncryptionReqd;
+}
+
+int EncryptionContext::getMaxWrappedSize() const {
+ return m_maxWrappedSize;
+}
+
+int EncryptionContext::getWrapSizeLimit() const {
+ return m_wrapSizeLimit;
+}
+
+void EncryptionContext::reset() {
+ this->m_bEncryptionReqd = false;
+ this->m_maxWrappedSize = 65536;
+ this->m_wrapSizeLimit = 0;
+}
+
+std::ostream& operator<<(std::ostream &contextStream, const EncryptionContext& context) {
+ contextStream << " Encryption: " << (context.isEncryptionReqd() ? "enabled" : "disabled");
+ contextStream << " ,MaxWrappedSize: " << context.getMaxWrappedSize();
+ contextStream << " ,WrapSizeLimit: " << context.getWrapSizeLimit();
+ return contextStream;
+}
+
} // namespace
diff --git a/contrib/native/client/src/clientlib/utils.hpp b/contrib/native/client/src/clientlib/utils.hpp
index 4cd8fa5e8..d30794c9a 100644
--- a/contrib/native/client/src/clientlib/utils.hpp
+++ b/contrib/native/client/src/clientlib/utils.hpp
@@ -98,6 +98,38 @@ class DECLSPEC_DRILL_CLIENT Utils{
}; // Utils
+/*
+ * Encryption related configuration parameters. The member's are updated with value received from server
+ * and also after the SASL Handshake is done.
+ */
+class EncryptionContext {
+
+ bool m_bEncryptionReqd;
+ int m_maxWrappedSize;
+ int m_wrapSizeLimit;
+
+public:
+ EncryptionContext();
+
+ EncryptionContext(const bool& encryptionReqd, const int& maxWrappedSize, const int& wrapSizeLimit);
+
+ void setEncryptionReqd(const bool& encryptionReqd);
+
+ void setMaxWrappedSize(const int& maxWrappedSize);
+
+ void setWrapSizeLimit(const int& wrapSizeLimit);
+
+ bool isEncryptionReqd() const;
+
+ int getMaxWrappedSize() const;
+
+ int getWrapSizeLimit() const;
+
+ void reset();
+
+ friend std::ostream& operator<<(std::ostream &contextStream, const EncryptionContext& context);
+};
+
} // namespace Drill
#endif
diff --git a/contrib/native/client/src/include/drill/common.hpp b/contrib/native/client/src/include/drill/common.hpp
index ed0a1ed32..5401c75a9 100644
--- a/contrib/native/client/src/include/drill/common.hpp
+++ b/contrib/native/client/src/include/drill/common.hpp
@@ -56,6 +56,7 @@
#define LENGTH_PREFIX_MAX_LENGTH 5
#define LEN_PREFIX_BUFLEN LENGTH_PREFIX_MAX_LENGTH
+#define ENCRYPT_LEN_PREFIX_BUFLEN 4
#define MAX_CONNECT_STR 4096
#define MAX_SOCK_RD_BUFSIZE 1024
@@ -169,6 +170,7 @@ typedef enum{
#define USERPROP_AUTH_MECHANISM "auth"
#define USERPROP_SERVICE_NAME "service_name"
#define USERPROP_SERVICE_HOST "service_host"
+#define USERPROP_SASL_ENCRYPT "sasl_encrypt"
// Bitflags to describe user properties
// Used in DrillUserProperties::USER_PROPERTIES
diff --git a/contrib/native/client/src/protobuf/User.pb.cc b/contrib/native/client/src/protobuf/User.pb.cc
index be3f0016b..e2ae3d19e 100644
--- a/contrib/native/client/src/protobuf/User.pb.cc
+++ b/contrib/native/client/src/protobuf/User.pb.cc
@@ -269,7 +269,7 @@ void protobuf_AssignDesc_User_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(QueryPlanFragments));
BitToUserHandshake_descriptor_ = file->message_type(7);
- static const int BitToUserHandshake_offsets_[7] = {
+ static const int BitToUserHandshake_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, rpc_version_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, status_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, errorid_),
@@ -277,6 +277,8 @@ void protobuf_AssignDesc_User_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, server_infos_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, authenticationmechanisms_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, supported_methods_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, encrypted_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, maxwrappedsize_),
};
BitToUserHandshake_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -952,198 +954,200 @@ void protobuf_AddDesc_User_2eproto() {
"ed.QueryResult.QueryState\022&\n\010query_id\030\002 "
"\001(\0132\024.exec.shared.QueryId\0221\n\tfragments\030\003"
" \003(\0132\036.exec.bit.control.PlanFragment\022(\n\005"
- "error\030\004 \001(\0132\031.exec.shared.DrillPBError\"\200"
+ "error\030\004 \001(\0132\031.exec.shared.DrillPBError\"\253"
"\002\n\022BitToUserHandshake\022\023\n\013rpc_version\030\002 \001"
"(\005\022*\n\006status\030\003 \001(\0162\032.exec.user.Handshake"
"Status\022\017\n\007errorId\030\004 \001(\t\022\024\n\014errorMessage\030"
"\005 \001(\t\0221\n\014server_infos\030\006 \001(\0132\033.exec.user."
"RpcEndpointInfos\022 \n\030authenticationMechan"
"isms\030\007 \003(\t\022-\n\021supported_methods\030\010 \003(\0162\022."
- "exec.user.RpcType\"-\n\nLikeFilter\022\017\n\007patte"
- "rn\030\001 \001(\t\022\016\n\006escape\030\002 \001(\t\"D\n\016GetCatalogsR"
- "eq\0222\n\023catalog_name_filter\030\001 \001(\0132\025.exec.u"
- "ser.LikeFilter\"M\n\017CatalogMetadata\022\024\n\014cat"
- "alog_name\030\001 \001(\t\022\023\n\013description\030\002 \001(\t\022\017\n\007"
- "connect\030\003 \001(\t\"\223\001\n\017GetCatalogsResp\022(\n\006sta"
- "tus\030\001 \001(\0162\030.exec.user.RequestStatus\022,\n\010c"
- "atalogs\030\002 \003(\0132\032.exec.user.CatalogMetadat"
- "a\022(\n\005error\030\003 \001(\0132\031.exec.shared.DrillPBEr"
- "ror\"v\n\rGetSchemasReq\0222\n\023catalog_name_fil"
- "ter\030\001 \001(\0132\025.exec.user.LikeFilter\0221\n\022sche"
- "ma_name_filter\030\002 \001(\0132\025.exec.user.LikeFil"
- "ter\"i\n\016SchemaMetadata\022\024\n\014catalog_name\030\001 "
- "\001(\t\022\023\n\013schema_name\030\002 \001(\t\022\r\n\005owner\030\003 \001(\t\022"
- "\014\n\004type\030\004 \001(\t\022\017\n\007mutable\030\005 \001(\t\"\220\001\n\016GetSc"
- "hemasResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Re"
- "questStatus\022*\n\007schemas\030\002 \003(\0132\031.exec.user"
- ".SchemaMetadata\022(\n\005error\030\003 \001(\0132\031.exec.sh"
- "ared.DrillPBError\"\302\001\n\014GetTablesReq\0222\n\023ca"
- "talog_name_filter\030\001 \001(\0132\025.exec.user.Like"
- "Filter\0221\n\022schema_name_filter\030\002 \001(\0132\025.exe"
- "c.user.LikeFilter\0220\n\021table_name_filter\030\003"
- " \001(\0132\025.exec.user.LikeFilter\022\031\n\021table_typ"
- "e_filter\030\004 \003(\t\"\\\n\rTableMetadata\022\024\n\014catal"
- "og_name\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022\n\nta"
- "ble_name\030\003 \001(\t\022\014\n\004type\030\004 \001(\t\"\215\001\n\rGetTabl"
- "esResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Reque"
- "stStatus\022(\n\006tables\030\002 \003(\0132\030.exec.user.Tab"
- "leMetadata\022(\n\005error\030\003 \001(\0132\031.exec.shared."
- "DrillPBError\"\333\001\n\rGetColumnsReq\0222\n\023catalo"
- "g_name_filter\030\001 \001(\0132\025.exec.user.LikeFilt"
- "er\0221\n\022schema_name_filter\030\002 \001(\0132\025.exec.us"
- "er.LikeFilter\0220\n\021table_name_filter\030\003 \001(\013"
- "2\025.exec.user.LikeFilter\0221\n\022column_name_f"
- "ilter\030\004 \001(\0132\025.exec.user.LikeFilter\"\251\003\n\016C"
- "olumnMetadata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013s"
- "chema_name\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022\023\n\013"
- "column_name\030\004 \001(\t\022\030\n\020ordinal_position\030\005 "
- "\001(\005\022\025\n\rdefault_value\030\006 \001(\t\022\023\n\013is_nullabl"
- "e\030\007 \001(\010\022\021\n\tdata_type\030\010 \001(\t\022\027\n\017char_max_l"
- "ength\030\t \001(\005\022\031\n\021char_octet_length\030\n \001(\005\022\031"
- "\n\021numeric_precision\030\013 \001(\005\022\037\n\027numeric_pre"
- "cision_radix\030\014 \001(\005\022\025\n\rnumeric_scale\030\r \001("
- "\005\022\033\n\023date_time_precision\030\016 \001(\005\022\025\n\rinterv"
- "al_type\030\017 \001(\t\022\032\n\022interval_precision\030\020 \001("
- "\005\022\023\n\013column_size\030\021 \001(\005\"\220\001\n\016GetColumnsRes"
- "p\022(\n\006status\030\001 \001(\0162\030.exec.user.RequestSta"
- "tus\022*\n\007columns\030\002 \003(\0132\031.exec.user.ColumnM"
- "etadata\022(\n\005error\030\003 \001(\0132\031.exec.shared.Dri"
- "llPBError\"/\n\032CreatePreparedStatementReq\022"
- "\021\n\tsql_query\030\001 \001(\t\"\326\003\n\024ResultColumnMetad"
- "ata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema_name"
- "\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022\023\n\013column_nam"
- "e\030\004 \001(\t\022\r\n\005label\030\005 \001(\t\022\021\n\tdata_type\030\006 \001("
- "\t\022\023\n\013is_nullable\030\007 \001(\010\022\021\n\tprecision\030\010 \001("
- "\005\022\r\n\005scale\030\t \001(\005\022\016\n\006signed\030\n \001(\010\022\024\n\014disp"
- "lay_size\030\013 \001(\005\022\022\n\nis_aliased\030\014 \001(\010\0225\n\rse"
- "archability\030\r \001(\0162\036.exec.user.ColumnSear"
- "chability\0223\n\014updatability\030\016 \001(\0162\035.exec.u"
- "ser.ColumnUpdatability\022\026\n\016auto_increment"
- "\030\017 \001(\010\022\030\n\020case_sensitivity\030\020 \001(\010\022\020\n\010sort"
- "able\030\021 \001(\010\022\022\n\nclass_name\030\022 \001(\t\022\023\n\013is_cur"
- "rency\030\024 \001(\010\".\n\027PreparedStatementHandle\022\023"
- "\n\013server_info\030\001 \001(\014\"\200\001\n\021PreparedStatemen"
- "t\0220\n\007columns\030\001 \003(\0132\037.exec.user.ResultCol"
- "umnMetadata\0229\n\rserver_handle\030\002 \001(\0132\".exe"
- "c.user.PreparedStatementHandle\"\253\001\n\033Creat"
- "ePreparedStatementResp\022(\n\006status\030\001 \001(\0162\030"
- ".exec.user.RequestStatus\0228\n\022prepared_sta"
- "tement\030\002 \001(\0132\034.exec.user.PreparedStateme"
- "nt\022(\n\005error\030\003 \001(\0132\031.exec.shared.DrillPBE"
- "rror\"\022\n\020GetServerMetaReq\"P\n\016ConvertSuppo"
- "rt\022\037\n\004from\030\001 \002(\0162\021.common.MinorType\022\035\n\002t"
- "o\030\002 \002(\0162\021.common.MinorType\"\223\001\n\021GetServer"
- "MetaResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Req"
- "uestStatus\022*\n\013server_meta\030\002 \001(\0132\025.exec.u"
- "ser.ServerMeta\022(\n\005error\030\003 \001(\0132\031.exec.sha"
- "red.DrillPBError\"\377\r\n\nServerMeta\022\035\n\025all_t"
- "ables_selectable\030\001 \001(\010\022%\n\035blob_included_"
- "in_max_row_size\030\002 \001(\010\022\030\n\020catalog_at_star"
- "t\030\003 \001(\010\022\031\n\021catalog_separator\030\004 \001(\t\022\024\n\014ca"
- "talog_term\030\005 \001(\t\0222\n\017collate_support\030\006 \003("
- "\0162\031.exec.user.CollateSupport\022!\n\031column_a"
- "liasing_supported\030\007 \001(\010\0222\n\017convert_suppo"
- "rt\030\010 \003(\0132\031.exec.user.ConvertSupport\022E\n\031c"
- "orrelation_names_support\030\t \001(\0162\".exec.us"
- "er.CorrelationNamesSupport\022\033\n\023date_time_"
- "functions\030\n \003(\t\022F\n\032date_time_literals_su"
- "pport\030\013 \003(\0162\".exec.user.DateTimeLiterals"
- "Support\0223\n\020group_by_support\030\014 \001(\0162\031.exec"
- ".user.GroupBySupport\0226\n\021identifier_casin"
- "g\030\r \001(\0162\033.exec.user.IdentifierCasing\022\037\n\027"
- "identifier_quote_string\030\016 \001(\t\022$\n\034like_es"
- "cape_clause_supported\030\017 \001(\010\022!\n\031max_binar"
- "y_literal_length\030\020 \001(\r\022\037\n\027max_catalog_na"
- "me_length\030\021 \001(\r\022\037\n\027max_char_literal_leng"
- "th\030\022 \001(\r\022\036\n\026max_column_name_length\030\023 \001(\r"
- "\022\037\n\027max_columns_in_group_by\030\024 \001(\r\022\037\n\027max"
- "_columns_in_order_by\030\025 \001(\r\022\035\n\025max_column"
- "s_in_select\030\026 \001(\r\022\036\n\026max_cursor_name_len"
- "gth\030\027 \001(\r\022\034\n\024max_logical_lob_size\030\030 \001(\r\022"
- "\024\n\014max_row_size\030\031 \001(\r\022\036\n\026max_schema_name"
- "_length\030\032 \001(\r\022\034\n\024max_statement_length\030\033 "
- "\001(\r\022\026\n\016max_statements\030\034 \001(\r\022\035\n\025max_table"
- "_name_length\030\035 \001(\r\022\034\n\024max_tables_in_sele"
- "ct\030\036 \001(\r\022\034\n\024max_user_name_length\030\037 \001(\r\0220"
- "\n\016null_collation\030 \001(\0162\030.exec.user.NullC"
- "ollation\022&\n\036null_plus_non_null_equals_nu"
- "ll\030! \001(\010\022\031\n\021numeric_functions\030\" \003(\t\0223\n\020o"
- "rder_by_support\030# \003(\0162\031.exec.user.OrderB"
- "ySupport\0227\n\022outer_join_support\030$ \003(\0162\033.e"
- "xec.user.OuterJoinSupport\022=\n\030quoted_iden"
- "tifier_casing\030% \001(\0162\033.exec.user.Identifi"
- "erCasing\022\021\n\tread_only\030& \001(\010\022\023\n\013schema_te"
- "rm\030\' \001(\t\022\034\n\024search_escape_string\030( \001(\t\022#"
- "\n\033select_for_update_supported\030) \001(\010\022\032\n\022s"
- "pecial_characters\030* \001(\t\022\024\n\014sql_keywords\030"
- "+ \003(\t\022\030\n\020string_functions\030, \003(\t\0224\n\020subqu"
- "ery_support\030- \003(\0162\032.exec.user.SubQuerySu"
- "pport\022\030\n\020system_functions\030. \003(\t\022\022\n\ntable"
- "_term\030/ \001(\t\022\035\n\025transaction_supported\0300 \001"
- "(\010\022.\n\runion_support\0301 \003(\0162\027.exec.user.Un"
- "ionSupport\"\353\001\n\010RunQuery\0221\n\014results_mode\030"
- "\001 \001(\0162\033.exec.user.QueryResultsMode\022$\n\004ty"
- "pe\030\002 \001(\0162\026.exec.shared.QueryType\022\014\n\004plan"
- "\030\003 \001(\t\0221\n\tfragments\030\004 \003(\0132\036.exec.bit.con"
- "trol.PlanFragment\022E\n\031prepared_statement_"
- "handle\030\005 \001(\0132\".exec.user.PreparedStateme"
- "ntHandle*\320\003\n\007RpcType\022\r\n\tHANDSHAKE\020\000\022\007\n\003A"
- "CK\020\001\022\013\n\007GOODBYE\020\002\022\r\n\tRUN_QUERY\020\003\022\020\n\014CANC"
- "EL_QUERY\020\004\022\023\n\017REQUEST_RESULTS\020\005\022\027\n\023RESUM"
- "E_PAUSED_QUERY\020\013\022\034\n\030GET_QUERY_PLAN_FRAGM"
- "ENTS\020\014\022\020\n\014GET_CATALOGS\020\016\022\017\n\013GET_SCHEMAS\020"
- "\017\022\016\n\nGET_TABLES\020\020\022\017\n\013GET_COLUMNS\020\021\022\035\n\031CR"
- "EATE_PREPARED_STATEMENT\020\026\022\023\n\017GET_SERVER_"
- "META\020\010\022\016\n\nQUERY_DATA\020\006\022\020\n\014QUERY_HANDLE\020\007"
- "\022\030\n\024QUERY_PLAN_FRAGMENTS\020\r\022\014\n\010CATALOGS\020\022"
- "\022\013\n\007SCHEMAS\020\023\022\n\n\006TABLES\020\024\022\013\n\007COLUMNS\020\025\022\026"
- "\n\022PREPARED_STATEMENT\020\027\022\017\n\013SERVER_META\020\t\022"
- "\020\n\014QUERY_RESULT\020\n\022\020\n\014SASL_MESSAGE\020\030*6\n\013S"
- "aslSupport\022\030\n\024UNKNOWN_SASL_SUPPORT\020\000\022\r\n\t"
- "SASL_AUTH\020\001*#\n\020QueryResultsMode\022\017\n\013STREA"
- "M_FULL\020\001*q\n\017HandshakeStatus\022\013\n\007SUCCESS\020\001"
- "\022\030\n\024RPC_VERSION_MISMATCH\020\002\022\017\n\013AUTH_FAILE"
- "D\020\003\022\023\n\017UNKNOWN_FAILURE\020\004\022\021\n\rAUTH_REQUIRE"
- "D\020\005*D\n\rRequestStatus\022\022\n\016UNKNOWN_STATUS\020\000"
- "\022\006\n\002OK\020\001\022\n\n\006FAILED\020\002\022\013\n\007TIMEOUT\020\003*Y\n\023Col"
- "umnSearchability\022\031\n\025UNKNOWN_SEARCHABILIT"
- "Y\020\000\022\010\n\004NONE\020\001\022\010\n\004CHAR\020\002\022\n\n\006NUMBER\020\003\022\007\n\003A"
- "LL\020\004*K\n\022ColumnUpdatability\022\030\n\024UNKNOWN_UP"
- "DATABILITY\020\000\022\r\n\tREAD_ONLY\020\001\022\014\n\010WRITABLE\020"
- "\002*1\n\016CollateSupport\022\016\n\nCS_UNKNOWN\020\000\022\017\n\013C"
- "S_GROUP_BY\020\001*J\n\027CorrelationNamesSupport\022"
- "\013\n\007CN_NONE\020\001\022\026\n\022CN_DIFFERENT_NAMES\020\002\022\n\n\006"
- "CN_ANY\020\003*\271\003\n\027DateTimeLiteralsSupport\022\016\n\n"
- "DL_UNKNOWN\020\000\022\013\n\007DL_DATE\020\001\022\013\n\007DL_TIME\020\002\022\020"
- "\n\014DL_TIMESTAMP\020\003\022\024\n\020DL_INTERVAL_YEAR\020\004\022\025"
- "\n\021DL_INTERVAL_MONTH\020\005\022\023\n\017DL_INTERVAL_DAY"
- "\020\006\022\024\n\020DL_INTERVAL_HOUR\020\007\022\026\n\022DL_INTERVAL_"
- "MINUTE\020\010\022\026\n\022DL_INTERVAL_SECOND\020\t\022\035\n\031DL_I"
- "NTERVAL_YEAR_TO_MONTH\020\n\022\033\n\027DL_INTERVAL_D"
- "AY_TO_HOUR\020\013\022\035\n\031DL_INTERVAL_DAY_TO_MINUT"
- "E\020\014\022\035\n\031DL_INTERVAL_DAY_TO_SECOND\020\r\022\036\n\032DL"
- "_INTERVAL_HOUR_TO_MINUTE\020\016\022\036\n\032DL_INTERVA"
- "L_HOUR_TO_SECOND\020\017\022 \n\034DL_INTERVAL_MINUTE"
- "_TO_SECOND\020\020*Y\n\016GroupBySupport\022\013\n\007GB_NON"
- "E\020\001\022\022\n\016GB_SELECT_ONLY\020\002\022\024\n\020GB_BEYOND_SEL"
- "ECT\020\003\022\020\n\014GB_UNRELATED\020\004*x\n\020IdentifierCas"
- "ing\022\016\n\nIC_UNKNOWN\020\000\022\023\n\017IC_STORES_LOWER\020\001"
- "\022\023\n\017IC_STORES_MIXED\020\002\022\023\n\017IC_STORES_UPPER"
- "\020\003\022\025\n\021IC_SUPPORTS_MIXED\020\004*X\n\rNullCollati"
- "on\022\016\n\nNC_UNKNOWN\020\000\022\017\n\013NC_AT_START\020\001\022\r\n\tN"
- "C_AT_END\020\002\022\013\n\007NC_HIGH\020\003\022\n\n\006NC_LOW\020\004*E\n\016O"
- "rderBySupport\022\016\n\nOB_UNKNOWN\020\000\022\020\n\014OB_UNRE"
- "LATED\020\001\022\021\n\rOB_EXPRESSION\020\002*\226\001\n\020OuterJoin"
- "Support\022\016\n\nOJ_UNKNOWN\020\000\022\013\n\007OJ_LEFT\020\001\022\014\n\010"
- "OJ_RIGHT\020\002\022\013\n\007OJ_FULL\020\003\022\r\n\tOJ_NESTED\020\004\022\022"
- "\n\016OJ_NOT_ORDERED\020\005\022\014\n\010OJ_INNER\020\006\022\031\n\025OJ_A"
- "LL_COMPARISON_OPS\020\007*\204\001\n\017SubQuerySupport\022"
- "\016\n\nSQ_UNKNOWN\020\000\022\021\n\rSQ_CORRELATED\020\001\022\024\n\020SQ"
- "_IN_COMPARISON\020\002\022\020\n\014SQ_IN_EXISTS\020\003\022\020\n\014SQ"
- "_IN_INSERT\020\004\022\024\n\020SQ_IN_QUANTIFIED\020\005*;\n\014Un"
- "ionSupport\022\r\n\tU_UNKNOWN\020\000\022\013\n\007U_UNION\020\001\022\017"
- "\n\013U_UNION_ALL\020\002B+\n\033org.apache.drill.exec"
- ".protoB\nUserProtosH\001", 8820);
+ "exec.user.RpcType\022\021\n\tencrypted\030\t \001(\010\022\026\n\016"
+ "maxWrappedSize\030\n \001(\005\"-\n\nLikeFilter\022\017\n\007pa"
+ "ttern\030\001 \001(\t\022\016\n\006escape\030\002 \001(\t\"D\n\016GetCatalo"
+ "gsReq\0222\n\023catalog_name_filter\030\001 \001(\0132\025.exe"
+ "c.user.LikeFilter\"M\n\017CatalogMetadata\022\024\n\014"
+ "catalog_name\030\001 \001(\t\022\023\n\013description\030\002 \001(\t\022"
+ "\017\n\007connect\030\003 \001(\t\"\223\001\n\017GetCatalogsResp\022(\n\006"
+ "status\030\001 \001(\0162\030.exec.user.RequestStatus\022,"
+ "\n\010catalogs\030\002 \003(\0132\032.exec.user.CatalogMeta"
+ "data\022(\n\005error\030\003 \001(\0132\031.exec.shared.DrillP"
+ "BError\"v\n\rGetSchemasReq\0222\n\023catalog_name_"
+ "filter\030\001 \001(\0132\025.exec.user.LikeFilter\0221\n\022s"
+ "chema_name_filter\030\002 \001(\0132\025.exec.user.Like"
+ "Filter\"i\n\016SchemaMetadata\022\024\n\014catalog_name"
+ "\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\r\n\005owner\030\003 \001"
+ "(\t\022\014\n\004type\030\004 \001(\t\022\017\n\007mutable\030\005 \001(\t\"\220\001\n\016Ge"
+ "tSchemasResp\022(\n\006status\030\001 \001(\0162\030.exec.user"
+ ".RequestStatus\022*\n\007schemas\030\002 \003(\0132\031.exec.u"
+ "ser.SchemaMetadata\022(\n\005error\030\003 \001(\0132\031.exec"
+ ".shared.DrillPBError\"\302\001\n\014GetTablesReq\0222\n"
+ "\023catalog_name_filter\030\001 \001(\0132\025.exec.user.L"
+ "ikeFilter\0221\n\022schema_name_filter\030\002 \001(\0132\025."
+ "exec.user.LikeFilter\0220\n\021table_name_filte"
+ "r\030\003 \001(\0132\025.exec.user.LikeFilter\022\031\n\021table_"
+ "type_filter\030\004 \003(\t\"\\\n\rTableMetadata\022\024\n\014ca"
+ "talog_name\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022\n"
+ "\ntable_name\030\003 \001(\t\022\014\n\004type\030\004 \001(\t\"\215\001\n\rGetT"
+ "ablesResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Re"
+ "questStatus\022(\n\006tables\030\002 \003(\0132\030.exec.user."
+ "TableMetadata\022(\n\005error\030\003 \001(\0132\031.exec.shar"
+ "ed.DrillPBError\"\333\001\n\rGetColumnsReq\0222\n\023cat"
+ "alog_name_filter\030\001 \001(\0132\025.exec.user.LikeF"
+ "ilter\0221\n\022schema_name_filter\030\002 \001(\0132\025.exec"
+ ".user.LikeFilter\0220\n\021table_name_filter\030\003 "
+ "\001(\0132\025.exec.user.LikeFilter\0221\n\022column_nam"
+ "e_filter\030\004 \001(\0132\025.exec.user.LikeFilter\"\251\003"
+ "\n\016ColumnMetadata\022\024\n\014catalog_name\030\001 \001(\t\022\023"
+ "\n\013schema_name\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022"
+ "\023\n\013column_name\030\004 \001(\t\022\030\n\020ordinal_position"
+ "\030\005 \001(\005\022\025\n\rdefault_value\030\006 \001(\t\022\023\n\013is_null"
+ "able\030\007 \001(\010\022\021\n\tdata_type\030\010 \001(\t\022\027\n\017char_ma"
+ "x_length\030\t \001(\005\022\031\n\021char_octet_length\030\n \001("
+ "\005\022\031\n\021numeric_precision\030\013 \001(\005\022\037\n\027numeric_"
+ "precision_radix\030\014 \001(\005\022\025\n\rnumeric_scale\030\r"
+ " \001(\005\022\033\n\023date_time_precision\030\016 \001(\005\022\025\n\rint"
+ "erval_type\030\017 \001(\t\022\032\n\022interval_precision\030\020"
+ " \001(\005\022\023\n\013column_size\030\021 \001(\005\"\220\001\n\016GetColumns"
+ "Resp\022(\n\006status\030\001 \001(\0162\030.exec.user.Request"
+ "Status\022*\n\007columns\030\002 \003(\0132\031.exec.user.Colu"
+ "mnMetadata\022(\n\005error\030\003 \001(\0132\031.exec.shared."
+ "DrillPBError\"/\n\032CreatePreparedStatementR"
+ "eq\022\021\n\tsql_query\030\001 \001(\t\"\326\003\n\024ResultColumnMe"
+ "tadata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema_n"
+ "ame\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022\023\n\013column_"
+ "name\030\004 \001(\t\022\r\n\005label\030\005 \001(\t\022\021\n\tdata_type\030\006"
+ " \001(\t\022\023\n\013is_nullable\030\007 \001(\010\022\021\n\tprecision\030\010"
+ " \001(\005\022\r\n\005scale\030\t \001(\005\022\016\n\006signed\030\n \001(\010\022\024\n\014d"
+ "isplay_size\030\013 \001(\005\022\022\n\nis_aliased\030\014 \001(\010\0225\n"
+ "\rsearchability\030\r \001(\0162\036.exec.user.ColumnS"
+ "earchability\0223\n\014updatability\030\016 \001(\0162\035.exe"
+ "c.user.ColumnUpdatability\022\026\n\016auto_increm"
+ "ent\030\017 \001(\010\022\030\n\020case_sensitivity\030\020 \001(\010\022\020\n\010s"
+ "ortable\030\021 \001(\010\022\022\n\nclass_name\030\022 \001(\t\022\023\n\013is_"
+ "currency\030\024 \001(\010\".\n\027PreparedStatementHandl"
+ "e\022\023\n\013server_info\030\001 \001(\014\"\200\001\n\021PreparedState"
+ "ment\0220\n\007columns\030\001 \003(\0132\037.exec.user.Result"
+ "ColumnMetadata\0229\n\rserver_handle\030\002 \001(\0132\"."
+ "exec.user.PreparedStatementHandle\"\253\001\n\033Cr"
+ "eatePreparedStatementResp\022(\n\006status\030\001 \001("
+ "\0162\030.exec.user.RequestStatus\0228\n\022prepared_"
+ "statement\030\002 \001(\0132\034.exec.user.PreparedStat"
+ "ement\022(\n\005error\030\003 \001(\0132\031.exec.shared.Drill"
+ "PBError\"\022\n\020GetServerMetaReq\"P\n\016ConvertSu"
+ "pport\022\037\n\004from\030\001 \002(\0162\021.common.MinorType\022\035"
+ "\n\002to\030\002 \002(\0162\021.common.MinorType\"\223\001\n\021GetSer"
+ "verMetaResp\022(\n\006status\030\001 \001(\0162\030.exec.user."
+ "RequestStatus\022*\n\013server_meta\030\002 \001(\0132\025.exe"
+ "c.user.ServerMeta\022(\n\005error\030\003 \001(\0132\031.exec."
+ "shared.DrillPBError\"\377\r\n\nServerMeta\022\035\n\025al"
+ "l_tables_selectable\030\001 \001(\010\022%\n\035blob_includ"
+ "ed_in_max_row_size\030\002 \001(\010\022\030\n\020catalog_at_s"
+ "tart\030\003 \001(\010\022\031\n\021catalog_separator\030\004 \001(\t\022\024\n"
+ "\014catalog_term\030\005 \001(\t\0222\n\017collate_support\030\006"
+ " \003(\0162\031.exec.user.CollateSupport\022!\n\031colum"
+ "n_aliasing_supported\030\007 \001(\010\0222\n\017convert_su"
+ "pport\030\010 \003(\0132\031.exec.user.ConvertSupport\022E"
+ "\n\031correlation_names_support\030\t \001(\0162\".exec"
+ ".user.CorrelationNamesSupport\022\033\n\023date_ti"
+ "me_functions\030\n \003(\t\022F\n\032date_time_literals"
+ "_support\030\013 \003(\0162\".exec.user.DateTimeLiter"
+ "alsSupport\0223\n\020group_by_support\030\014 \001(\0162\031.e"
+ "xec.user.GroupBySupport\0226\n\021identifier_ca"
+ "sing\030\r \001(\0162\033.exec.user.IdentifierCasing\022"
+ "\037\n\027identifier_quote_string\030\016 \001(\t\022$\n\034like"
+ "_escape_clause_supported\030\017 \001(\010\022!\n\031max_bi"
+ "nary_literal_length\030\020 \001(\r\022\037\n\027max_catalog"
+ "_name_length\030\021 \001(\r\022\037\n\027max_char_literal_l"
+ "ength\030\022 \001(\r\022\036\n\026max_column_name_length\030\023 "
+ "\001(\r\022\037\n\027max_columns_in_group_by\030\024 \001(\r\022\037\n\027"
+ "max_columns_in_order_by\030\025 \001(\r\022\035\n\025max_col"
+ "umns_in_select\030\026 \001(\r\022\036\n\026max_cursor_name_"
+ "length\030\027 \001(\r\022\034\n\024max_logical_lob_size\030\030 \001"
+ "(\r\022\024\n\014max_row_size\030\031 \001(\r\022\036\n\026max_schema_n"
+ "ame_length\030\032 \001(\r\022\034\n\024max_statement_length"
+ "\030\033 \001(\r\022\026\n\016max_statements\030\034 \001(\r\022\035\n\025max_ta"
+ "ble_name_length\030\035 \001(\r\022\034\n\024max_tables_in_s"
+ "elect\030\036 \001(\r\022\034\n\024max_user_name_length\030\037 \001("
+ "\r\0220\n\016null_collation\030 \001(\0162\030.exec.user.Nu"
+ "llCollation\022&\n\036null_plus_non_null_equals"
+ "_null\030! \001(\010\022\031\n\021numeric_functions\030\" \003(\t\0223"
+ "\n\020order_by_support\030# \003(\0162\031.exec.user.Ord"
+ "erBySupport\0227\n\022outer_join_support\030$ \003(\0162"
+ "\033.exec.user.OuterJoinSupport\022=\n\030quoted_i"
+ "dentifier_casing\030% \001(\0162\033.exec.user.Ident"
+ "ifierCasing\022\021\n\tread_only\030& \001(\010\022\023\n\013schema"
+ "_term\030\' \001(\t\022\034\n\024search_escape_string\030( \001("
+ "\t\022#\n\033select_for_update_supported\030) \001(\010\022\032"
+ "\n\022special_characters\030* \001(\t\022\024\n\014sql_keywor"
+ "ds\030+ \003(\t\022\030\n\020string_functions\030, \003(\t\0224\n\020su"
+ "bquery_support\030- \003(\0162\032.exec.user.SubQuer"
+ "ySupport\022\030\n\020system_functions\030. \003(\t\022\022\n\nta"
+ "ble_term\030/ \001(\t\022\035\n\025transaction_supported\030"
+ "0 \001(\010\022.\n\runion_support\0301 \003(\0162\027.exec.user"
+ ".UnionSupport\"\353\001\n\010RunQuery\0221\n\014results_mo"
+ "de\030\001 \001(\0162\033.exec.user.QueryResultsMode\022$\n"
+ "\004type\030\002 \001(\0162\026.exec.shared.QueryType\022\014\n\004p"
+ "lan\030\003 \001(\t\0221\n\tfragments\030\004 \003(\0132\036.exec.bit."
+ "control.PlanFragment\022E\n\031prepared_stateme"
+ "nt_handle\030\005 \001(\0132\".exec.user.PreparedStat"
+ "ementHandle*\320\003\n\007RpcType\022\r\n\tHANDSHAKE\020\000\022\007"
+ "\n\003ACK\020\001\022\013\n\007GOODBYE\020\002\022\r\n\tRUN_QUERY\020\003\022\020\n\014C"
+ "ANCEL_QUERY\020\004\022\023\n\017REQUEST_RESULTS\020\005\022\027\n\023RE"
+ "SUME_PAUSED_QUERY\020\013\022\034\n\030GET_QUERY_PLAN_FR"
+ "AGMENTS\020\014\022\020\n\014GET_CATALOGS\020\016\022\017\n\013GET_SCHEM"
+ "AS\020\017\022\016\n\nGET_TABLES\020\020\022\017\n\013GET_COLUMNS\020\021\022\035\n"
+ "\031CREATE_PREPARED_STATEMENT\020\026\022\023\n\017GET_SERV"
+ "ER_META\020\010\022\016\n\nQUERY_DATA\020\006\022\020\n\014QUERY_HANDL"
+ "E\020\007\022\030\n\024QUERY_PLAN_FRAGMENTS\020\r\022\014\n\010CATALOG"
+ "S\020\022\022\013\n\007SCHEMAS\020\023\022\n\n\006TABLES\020\024\022\013\n\007COLUMNS\020"
+ "\025\022\026\n\022PREPARED_STATEMENT\020\027\022\017\n\013SERVER_META"
+ "\020\t\022\020\n\014QUERY_RESULT\020\n\022\020\n\014SASL_MESSAGE\020\030*H"
+ "\n\013SaslSupport\022\030\n\024UNKNOWN_SASL_SUPPORT\020\000\022"
+ "\r\n\tSASL_AUTH\020\001\022\020\n\014SASL_PRIVACY\020\002*#\n\020Quer"
+ "yResultsMode\022\017\n\013STREAM_FULL\020\001*q\n\017Handsha"
+ "keStatus\022\013\n\007SUCCESS\020\001\022\030\n\024RPC_VERSION_MIS"
+ "MATCH\020\002\022\017\n\013AUTH_FAILED\020\003\022\023\n\017UNKNOWN_FAIL"
+ "URE\020\004\022\021\n\rAUTH_REQUIRED\020\005*D\n\rRequestStatu"
+ "s\022\022\n\016UNKNOWN_STATUS\020\000\022\006\n\002OK\020\001\022\n\n\006FAILED\020"
+ "\002\022\013\n\007TIMEOUT\020\003*Y\n\023ColumnSearchability\022\031\n"
+ "\025UNKNOWN_SEARCHABILITY\020\000\022\010\n\004NONE\020\001\022\010\n\004CH"
+ "AR\020\002\022\n\n\006NUMBER\020\003\022\007\n\003ALL\020\004*K\n\022ColumnUpdat"
+ "ability\022\030\n\024UNKNOWN_UPDATABILITY\020\000\022\r\n\tREA"
+ "D_ONLY\020\001\022\014\n\010WRITABLE\020\002*1\n\016CollateSupport"
+ "\022\016\n\nCS_UNKNOWN\020\000\022\017\n\013CS_GROUP_BY\020\001*J\n\027Cor"
+ "relationNamesSupport\022\013\n\007CN_NONE\020\001\022\026\n\022CN_"
+ "DIFFERENT_NAMES\020\002\022\n\n\006CN_ANY\020\003*\271\003\n\027DateTi"
+ "meLiteralsSupport\022\016\n\nDL_UNKNOWN\020\000\022\013\n\007DL_"
+ "DATE\020\001\022\013\n\007DL_TIME\020\002\022\020\n\014DL_TIMESTAMP\020\003\022\024\n"
+ "\020DL_INTERVAL_YEAR\020\004\022\025\n\021DL_INTERVAL_MONTH"
+ "\020\005\022\023\n\017DL_INTERVAL_DAY\020\006\022\024\n\020DL_INTERVAL_H"
+ "OUR\020\007\022\026\n\022DL_INTERVAL_MINUTE\020\010\022\026\n\022DL_INTE"
+ "RVAL_SECOND\020\t\022\035\n\031DL_INTERVAL_YEAR_TO_MON"
+ "TH\020\n\022\033\n\027DL_INTERVAL_DAY_TO_HOUR\020\013\022\035\n\031DL_"
+ "INTERVAL_DAY_TO_MINUTE\020\014\022\035\n\031DL_INTERVAL_"
+ "DAY_TO_SECOND\020\r\022\036\n\032DL_INTERVAL_HOUR_TO_M"
+ "INUTE\020\016\022\036\n\032DL_INTERVAL_HOUR_TO_SECOND\020\017\022"
+ " \n\034DL_INTERVAL_MINUTE_TO_SECOND\020\020*Y\n\016Gro"
+ "upBySupport\022\013\n\007GB_NONE\020\001\022\022\n\016GB_SELECT_ON"
+ "LY\020\002\022\024\n\020GB_BEYOND_SELECT\020\003\022\020\n\014GB_UNRELAT"
+ "ED\020\004*x\n\020IdentifierCasing\022\016\n\nIC_UNKNOWN\020\000"
+ "\022\023\n\017IC_STORES_LOWER\020\001\022\023\n\017IC_STORES_MIXED"
+ "\020\002\022\023\n\017IC_STORES_UPPER\020\003\022\025\n\021IC_SUPPORTS_M"
+ "IXED\020\004*X\n\rNullCollation\022\016\n\nNC_UNKNOWN\020\000\022"
+ "\017\n\013NC_AT_START\020\001\022\r\n\tNC_AT_END\020\002\022\013\n\007NC_HI"
+ "GH\020\003\022\n\n\006NC_LOW\020\004*E\n\016OrderBySupport\022\016\n\nOB"
+ "_UNKNOWN\020\000\022\020\n\014OB_UNRELATED\020\001\022\021\n\rOB_EXPRE"
+ "SSION\020\002*\226\001\n\020OuterJoinSupport\022\016\n\nOJ_UNKNO"
+ "WN\020\000\022\013\n\007OJ_LEFT\020\001\022\014\n\010OJ_RIGHT\020\002\022\013\n\007OJ_FU"
+ "LL\020\003\022\r\n\tOJ_NESTED\020\004\022\022\n\016OJ_NOT_ORDERED\020\005\022"
+ "\014\n\010OJ_INNER\020\006\022\031\n\025OJ_ALL_COMPARISON_OPS\020\007"
+ "*\204\001\n\017SubQuerySupport\022\016\n\nSQ_UNKNOWN\020\000\022\021\n\r"
+ "SQ_CORRELATED\020\001\022\024\n\020SQ_IN_COMPARISON\020\002\022\020\n"
+ "\014SQ_IN_EXISTS\020\003\022\020\n\014SQ_IN_INSERT\020\004\022\024\n\020SQ_"
+ "IN_QUANTIFIED\020\005*;\n\014UnionSupport\022\r\n\tU_UNK"
+ "NOWN\020\000\022\013\n\007U_UNION\020\001\022\017\n\013U_UNION_ALL\020\002B+\n\033"
+ "org.apache.drill.exec.protoB\nUserProtosH"
+ "\001", 8881);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"User.proto", &protobuf_RegisterTypes);
Property::default_instance_ = new Property();
@@ -1262,6 +1266,7 @@ bool SaslSupport_IsValid(int value) {
switch(value) {
case 0:
case 1:
+ case 2:
return true;
default:
return false;
@@ -4044,6 +4049,8 @@ const int BitToUserHandshake::kErrorMessageFieldNumber;
const int BitToUserHandshake::kServerInfosFieldNumber;
const int BitToUserHandshake::kAuthenticationMechanismsFieldNumber;
const int BitToUserHandshake::kSupportedMethodsFieldNumber;
+const int BitToUserHandshake::kEncryptedFieldNumber;
+const int BitToUserHandshake::kMaxWrappedSizeFieldNumber;
#endif // !_MSC_VER
BitToUserHandshake::BitToUserHandshake()
@@ -4068,6 +4075,8 @@ void BitToUserHandshake::SharedCtor() {
errorid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
errormessage_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
server_infos_ = NULL;
+ encrypted_ = false;
+ maxwrappedsize_ = 0;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -4125,6 +4134,10 @@ void BitToUserHandshake::Clear() {
if (has_server_infos()) {
if (server_infos_ != NULL) server_infos_->::exec::user::RpcEndpointInfos::Clear();
}
+ encrypted_ = false;
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ maxwrappedsize_ = 0;
}
authenticationmechanisms_.Clear();
supported_methods_.Clear();
@@ -4266,6 +4279,38 @@ bool BitToUserHandshake::MergePartialFromCodedStream(
goto handle_uninterpreted;
}
if (input->ExpectTag(64)) goto parse_supported_methods;
+ if (input->ExpectTag(72)) goto parse_encrypted;
+ break;
+ }
+
+ // optional bool encrypted = 9;
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_encrypted:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &encrypted_)));
+ set_has_encrypted();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(80)) goto parse_maxWrappedSize;
+ break;
+ }
+
+ // optional int32 maxWrappedSize = 10;
+ case 10: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_maxWrappedSize:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &maxwrappedsize_)));
+ set_has_maxwrappedsize();
+ } else {
+ goto handle_uninterpreted;
+ }
if (input->ExpectAtEnd()) return true;
break;
}
@@ -4338,6 +4383,16 @@ void BitToUserHandshake::SerializeWithCachedSizes(
8, this->supported_methods(i), output);
}
+ // optional bool encrypted = 9;
+ if (has_encrypted()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(9, this->encrypted(), output);
+ }
+
+ // optional int32 maxWrappedSize = 10;
+ if (has_maxwrappedsize()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(10, this->maxwrappedsize(), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
@@ -4399,6 +4454,16 @@ void BitToUserHandshake::SerializeWithCachedSizes(
8, this->supported_methods(i), target);
}
+ // optional bool encrypted = 9;
+ if (has_encrypted()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(9, this->encrypted(), target);
+ }
+
+ // optional int32 maxWrappedSize = 10;
+ if (has_maxwrappedsize()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(10, this->maxwrappedsize(), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
@@ -4444,6 +4509,20 @@ int BitToUserHandshake::ByteSize() const {
this->server_infos());
}
+ // optional bool encrypted = 9;
+ if (has_encrypted()) {
+ total_size += 1 + 1;
+ }
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional int32 maxWrappedSize = 10;
+ if (has_maxwrappedsize()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->maxwrappedsize());
+ }
+
}
// repeated string authenticationMechanisms = 7;
total_size += 1 * this->authenticationmechanisms_size();
@@ -4505,6 +4584,14 @@ void BitToUserHandshake::MergeFrom(const BitToUserHandshake& from) {
if (from.has_server_infos()) {
mutable_server_infos()->::exec::user::RpcEndpointInfos::MergeFrom(from.server_infos());
}
+ if (from.has_encrypted()) {
+ set_encrypted(from.encrypted());
+ }
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_maxwrappedsize()) {
+ set_maxwrappedsize(from.maxwrappedsize());
+ }
}
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -4535,6 +4622,8 @@ void BitToUserHandshake::Swap(BitToUserHandshake* other) {
std::swap(server_infos_, other->server_infos_);
authenticationmechanisms_.Swap(&other->authenticationmechanisms_);
supported_methods_.Swap(&other->supported_methods_);
+ std::swap(encrypted_, other->encrypted_);
+ std::swap(maxwrappedsize_, other->maxwrappedsize_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
diff --git a/contrib/native/client/src/protobuf/User.pb.h b/contrib/native/client/src/protobuf/User.pb.h
index a8f8db4d3..b50e8c386 100644
--- a/contrib/native/client/src/protobuf/User.pb.h
+++ b/contrib/native/client/src/protobuf/User.pb.h
@@ -117,11 +117,12 @@ inline bool RpcType_Parse(
}
enum SaslSupport {
UNKNOWN_SASL_SUPPORT = 0,
- SASL_AUTH = 1
+ SASL_AUTH = 1,
+ SASL_PRIVACY = 2
};
bool SaslSupport_IsValid(int value);
const SaslSupport SaslSupport_MIN = UNKNOWN_SASL_SUPPORT;
-const SaslSupport SaslSupport_MAX = SASL_AUTH;
+const SaslSupport SaslSupport_MAX = SASL_PRIVACY;
const int SaslSupport_ARRAYSIZE = SaslSupport_MAX + 1;
const ::google::protobuf::EnumDescriptor* SaslSupport_descriptor();
@@ -1439,6 +1440,20 @@ class BitToUserHandshake : public ::google::protobuf::Message {
inline const ::google::protobuf::RepeatedField<int>& supported_methods() const;
inline ::google::protobuf::RepeatedField<int>* mutable_supported_methods();
+ // optional bool encrypted = 9;
+ inline bool has_encrypted() const;
+ inline void clear_encrypted();
+ static const int kEncryptedFieldNumber = 9;
+ inline bool encrypted() const;
+ inline void set_encrypted(bool value);
+
+ // optional int32 maxWrappedSize = 10;
+ inline bool has_maxwrappedsize() const;
+ inline void clear_maxwrappedsize();
+ static const int kMaxWrappedSizeFieldNumber = 10;
+ inline ::google::protobuf::int32 maxwrappedsize() const;
+ inline void set_maxwrappedsize(::google::protobuf::int32 value);
+
// @@protoc_insertion_point(class_scope:exec.user.BitToUserHandshake)
private:
inline void set_has_rpc_version();
@@ -1451,6 +1466,10 @@ class BitToUserHandshake : public ::google::protobuf::Message {
inline void clear_has_errormessage();
inline void set_has_server_infos();
inline void clear_has_server_infos();
+ inline void set_has_encrypted();
+ inline void clear_has_encrypted();
+ inline void set_has_maxwrappedsize();
+ inline void clear_has_maxwrappedsize();
::google::protobuf::UnknownFieldSet _unknown_fields_;
@@ -1461,9 +1480,11 @@ class BitToUserHandshake : public ::google::protobuf::Message {
::exec::user::RpcEndpointInfos* server_infos_;
::google::protobuf::RepeatedPtrField< ::std::string> authenticationmechanisms_;
::google::protobuf::RepeatedField<int> supported_methods_;
+ bool encrypted_;
+ ::google::protobuf::int32 maxwrappedsize_;
mutable int _cached_size_;
- ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+ ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
friend void protobuf_AddDesc_User_2eproto();
friend void protobuf_AssignDesc_User_2eproto();
@@ -6226,6 +6247,50 @@ BitToUserHandshake::mutable_supported_methods() {
return &supported_methods_;
}
+// optional bool encrypted = 9;
+inline bool BitToUserHandshake::has_encrypted() const {
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void BitToUserHandshake::set_has_encrypted() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void BitToUserHandshake::clear_has_encrypted() {
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline void BitToUserHandshake::clear_encrypted() {
+ encrypted_ = false;
+ clear_has_encrypted();
+}
+inline bool BitToUserHandshake::encrypted() const {
+ return encrypted_;
+}
+inline void BitToUserHandshake::set_encrypted(bool value) {
+ set_has_encrypted();
+ encrypted_ = value;
+}
+
+// optional int32 maxWrappedSize = 10;
+inline bool BitToUserHandshake::has_maxwrappedsize() const {
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void BitToUserHandshake::set_has_maxwrappedsize() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void BitToUserHandshake::clear_has_maxwrappedsize() {
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline void BitToUserHandshake::clear_maxwrappedsize() {
+ maxwrappedsize_ = 0;
+ clear_has_maxwrappedsize();
+}
+inline ::google::protobuf::int32 BitToUserHandshake::maxwrappedsize() const {
+ return maxwrappedsize_;
+}
+inline void BitToUserHandshake::set_maxwrappedsize(::google::protobuf::int32 value) {
+ set_has_maxwrappedsize();
+ maxwrappedsize_ = value;
+}
+
// -------------------------------------------------------------------
// LikeFilter