aboutsummaryrefslogtreecommitdiff
path: root/contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp')
-rw-r--r--contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp119
1 files changed, 115 insertions, 4 deletions
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 */