diff options
Diffstat (limited to 'Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp')
-rw-r--r-- | Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp | 318 |
1 files changed, 159 insertions, 159 deletions
diff --git a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp index 12b0dc4..aae437f 100644 --- a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp +++ b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp @@ -15,183 +15,183 @@ namespace Swift { WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname, int port) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) { - WindowsServicePrincipalName servicePrincipalName(domainname); - servicePrincipalName.setInstanceName(hostname); - if ((port != -1) && (port != 5222)) { - servicePrincipalName.setInstancePort(port); - } - servicePrincipalNameString_ = servicePrincipalName.toString(); - - errorCode_ = acquireCredentialsHandle(&credentialsHandle_); - if (isError()) { - return; - } - else { - haveCredentialsHandle_ = true; - } - - buildSecurityContext(boost::optional<ByteArray>()); + WindowsServicePrincipalName servicePrincipalName(domainname); + servicePrincipalName.setInstanceName(hostname); + if ((port != -1) && (port != 5222)) { + servicePrincipalName.setInstancePort(port); + } + servicePrincipalNameString_ = servicePrincipalName.toString(); + + errorCode_ = acquireCredentialsHandle(&credentialsHandle_); + if (isError()) { + return; + } + else { + haveCredentialsHandle_ = true; + } + + buildSecurityContext(boost::optional<ByteArray>()); } WindowsGSSAPIClientAuthenticator::~WindowsGSSAPIClientAuthenticator() { - if (haveContextHandle_) { - deleteSecurityContext(&contextHandle_); - } + if (haveContextHandle_) { + deleteSecurityContext(&contextHandle_); + } - if (haveCredentialsHandle_) { - freeCredentialsHandle(&credentialsHandle_); - } + if (haveCredentialsHandle_) { + freeCredentialsHandle(&credentialsHandle_); + } } boost::optional<SafeByteArray> WindowsGSSAPIClientAuthenticator::getResponse() const { - SWIFT_LOG(debug) << "response_.size(): " << response_.size() << std::endl; - return response_; + SWIFT_LOG(debug) << "response_.size(): " << response_.size() << std::endl; + return response_; } bool WindowsGSSAPIClientAuthenticator::setChallenge(const boost::optional<ByteArray>& challengeData) { - /* Following http://tools.ietf.org/html/rfc4752, https://msdn.microsoft.com/en-us/library/windows/desktop/aa380496%28v=vs.85%29.aspx */ - - if (step_ == BuildingSecurityContext) { - buildSecurityContext(challengeData); - } - else if (step_ == SecurityLayerNegotiation) { - if (!challengeData) { - SWIFT_LOG(debug) << "Empty message received from the server" << std::endl; - error_ = true; - return false; - } - - SafeByteArray challenge; - errorCode_ = decryptMessage(&contextHandle_, challengeData.get(), challenge); - if (isError()) { - return false; - } - - if (challenge.size() != 4) { - SWIFT_LOG(debug) << "Token received from the server of incorrect length: " << challenge.size() << std::endl; - error_ = true; - return false; - } - - unsigned char* challengePointer = vecptr(challenge); - - unsigned char serverSecurityLayer = challengePointer[0]; - if (serverSecurityLayer == 0) { - SWIFT_LOG(debug) << "Server supports unknown security layer, assuming no security layer" << std::endl; - serverSecurityLayer = SECURITY_LAYER_NONE; - } - else if (serverSecurityLayer == SECURITY_LAYER_NONE) { - SWIFT_LOG(debug) << "Server supports no security layer" << std::endl; - } - else { - SWIFT_LOG(debug) << "Server supports security layer" << std::endl; - } - - unsigned int serverMaximumBuffer = (challengePointer[1] << 16) | - (challengePointer[2] << 8) | - (challengePointer[3] << 0); - - if ((serverSecurityLayer == SECURITY_LAYER_NONE) && (serverMaximumBuffer != 0)) { - SWIFT_LOG(debug) << "Server supports no security layer but has maximum buffer size" << serverMaximumBuffer << std::endl; - error_ = true; - return false; - } - - SafeByteArray message(4); - - /* Commenting this out as streamSizes was not obtained before - if (message.size() > streamSizes_.cbMaximumMessage) { - error_ = true; - return false; - } */ - - unsigned char* messagePointer = vecptr(message); - messagePointer[0] = SECURITY_LAYER_NONE; - - /* The next 3 bytes indicate the client's maximum size buffer which is set to 0 as we do not support a security layer */ - messagePointer[1] = 0; - messagePointer[2] = 0; - messagePointer[3] = 0; - - /* The authorization identity is omitted as it is the same as the authentication identity */ - - errorCode_ = encryptMessage(&contextHandle_, sizes_, message, response_); - if (isError()) { - return false; - } - - step_ = ServerAuthenticated; - } - - if (isError()) { - return false; - } - - return true; + /* Following http://tools.ietf.org/html/rfc4752, https://msdn.microsoft.com/en-us/library/windows/desktop/aa380496%28v=vs.85%29.aspx */ + + if (step_ == BuildingSecurityContext) { + buildSecurityContext(challengeData); + } + else if (step_ == SecurityLayerNegotiation) { + if (!challengeData) { + SWIFT_LOG(debug) << "Empty message received from the server" << std::endl; + error_ = true; + return false; + } + + SafeByteArray challenge; + errorCode_ = decryptMessage(&contextHandle_, challengeData.get(), challenge); + if (isError()) { + return false; + } + + if (challenge.size() != 4) { + SWIFT_LOG(debug) << "Token received from the server of incorrect length: " << challenge.size() << std::endl; + error_ = true; + return false; + } + + unsigned char* challengePointer = vecptr(challenge); + + unsigned char serverSecurityLayer = challengePointer[0]; + if (serverSecurityLayer == 0) { + SWIFT_LOG(debug) << "Server supports unknown security layer, assuming no security layer" << std::endl; + serverSecurityLayer = SECURITY_LAYER_NONE; + } + else if (serverSecurityLayer == SECURITY_LAYER_NONE) { + SWIFT_LOG(debug) << "Server supports no security layer" << std::endl; + } + else { + SWIFT_LOG(debug) << "Server supports security layer" << std::endl; + } + + unsigned int serverMaximumBuffer = (challengePointer[1] << 16) | + (challengePointer[2] << 8) | + (challengePointer[3] << 0); + + if ((serverSecurityLayer == SECURITY_LAYER_NONE) && (serverMaximumBuffer != 0)) { + SWIFT_LOG(debug) << "Server supports no security layer but has maximum buffer size" << serverMaximumBuffer << std::endl; + error_ = true; + return false; + } + + SafeByteArray message(4); + + /* Commenting this out as streamSizes was not obtained before + if (message.size() > streamSizes_.cbMaximumMessage) { + error_ = true; + return false; + } */ + + unsigned char* messagePointer = vecptr(message); + messagePointer[0] = SECURITY_LAYER_NONE; + + /* The next 3 bytes indicate the client's maximum size buffer which is set to 0 as we do not support a security layer */ + messagePointer[1] = 0; + messagePointer[2] = 0; + messagePointer[3] = 0; + + /* The authorization identity is omitted as it is the same as the authentication identity */ + + errorCode_ = encryptMessage(&contextHandle_, sizes_, message, response_); + if (isError()) { + return false; + } + + step_ = ServerAuthenticated; + } + + if (isError()) { + return false; + } + + return true; } bool WindowsGSSAPIClientAuthenticator::isError() { - if (error_) { - return true; - } + if (error_) { + return true; + } - if (!errorCode_) { - return false; - } + if (!errorCode_) { + return false; + } - return true; + return true; } void WindowsGSSAPIClientAuthenticator::buildSecurityContext(const boost::optional<ByteArray>& inputToken) { - ULONG contextSupported; - - /* An XMPP server may not support Kerberos encryption or SASL security layer so not requesting integrity or confidentiality */ - errorCode_ = initializeSecurityContext(inputToken, servicePrincipalNameString_, &credentialsHandle_, haveContextHandle_, &contextHandle_, ISC_REQ_MUTUAL_AUTH, &contextSupported, &haveCompleteContext_, response_); - if (isError()) { - return; - } - - haveContextHandle_ = true; - - if (!haveCompleteContext_) { - return; - } - - if (contextSupported & ISC_REQ_MUTUAL_AUTH == 0) { - SWIFT_LOG(debug) << "Mutual authentication not supported" << std::endl; - error_ = true; - return; - } - - errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_SIZES, &sizes_); - if (isError()) { - return; - } - - /* Commenting this out as it gives the error code 0x80090302: The function requested is not supported - errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_STREAM_SIZES, &streamSizes_); - if (isError()) { - return; - }*/ - - SecPkgContext_Names names; - errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_NAMES, &names); - if (isError()) { - return; - } - - userName_ = names.sUserName; - SWIFT_LOG(debug) << "User name: " << userName_ << std::endl; - - std::size_t position = userName_.find("\\"); - clientName_ = userName_.substr(position + 1); - SWIFT_LOG(debug) << "Client name: " << clientName_ << std::endl; - - serverName_ = userName_.substr(0, position); - SWIFT_LOG(debug) << "Server name: " << serverName_ << std::endl; - - freeContextBuffer(names.sUserName); - step_ = SecurityLayerNegotiation; + ULONG contextSupported; + + /* An XMPP server may not support Kerberos encryption or SASL security layer so not requesting integrity or confidentiality */ + errorCode_ = initializeSecurityContext(inputToken, servicePrincipalNameString_, &credentialsHandle_, haveContextHandle_, &contextHandle_, ISC_REQ_MUTUAL_AUTH, &contextSupported, &haveCompleteContext_, response_); + if (isError()) { + return; + } + + haveContextHandle_ = true; + + if (!haveCompleteContext_) { + return; + } + + if (contextSupported & ISC_REQ_MUTUAL_AUTH == 0) { + SWIFT_LOG(debug) << "Mutual authentication not supported" << std::endl; + error_ = true; + return; + } + + errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_SIZES, &sizes_); + if (isError()) { + return; + } + + /* Commenting this out as it gives the error code 0x80090302: The function requested is not supported + errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_STREAM_SIZES, &streamSizes_); + if (isError()) { + return; + }*/ + + SecPkgContext_Names names; + errorCode_ = queryContextAttributes(&contextHandle_, SECPKG_ATTR_NAMES, &names); + if (isError()) { + return; + } + + userName_ = names.sUserName; + SWIFT_LOG(debug) << "User name: " << userName_ << std::endl; + + std::size_t position = userName_.find("\\"); + clientName_ = userName_.substr(position + 1); + SWIFT_LOG(debug) << "Client name: " << clientName_ << std::endl; + + serverName_ = userName_.substr(0, position); + SWIFT_LOG(debug) << "Server name: " << serverName_ << std::endl; + + freeContextBuffer(names.sUserName); + step_ = SecurityLayerNegotiation; } } |