diff options
Diffstat (limited to 'contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp')
-rw-r--r-- | contrib/native/client/src/clientlib/saslAuthenticatorImpl.cpp | 119 |
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 */ |