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; }
/* * Processes received authentication tokens as well as supplies the * response token. */ int ne_sspi_authenticate(void *context, const char *base64Token, char **responseToken) { SecBufferDesc outBufferDesc; SecBuffer outBuffer; int status; SECURITY_STATUS securityStatus; ULONG contextFlags; SSPIContext *sspiContext; if (initialized <= 0) { return -1; } status = getContext(context, &sspiContext); if (status) { return status; } /* TODO: Not sure what flags should be set. joe: this needs to be * driven by the ne_auth interface; the GSSAPI code needs similar * flags. */ contextFlags = ISC_REQ_CONFIDENTIALITY | ISC_REQ_MUTUAL_AUTH; initSingleEmptyBuffer(&outBufferDesc, &outBuffer); status = makeBuffer(&outBufferDesc, sspiContext->maxTokenSize); if (status) { return status; } if (base64Token) { SecBufferDesc inBufferDesc; SecBuffer inBuffer; if (!sspiContext->continueNeeded) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Got an unexpected token.\n"); return -1; } initSingleEmptyBuffer(&inBufferDesc, &inBuffer); status = base64ToBuffer(base64Token, &inBufferDesc); if (status) { freeBuffer(&outBufferDesc); return status; } securityStatus = initializeSecurityContext(&sspiContext->credentials, &(sspiContext->context), sspiContext->serverName, contextFlags, &inBufferDesc, &(sspiContext->context), &outBufferDesc); if (securityStatus == SEC_E_OK) { sspiContext->authfinished = 1; } freeBuffer(&inBufferDesc); } else { if (sspiContext->continueNeeded) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Expected a token from server.\n"); return -1; } if (sspiContext->authfinished && (sspiContext->credentials.dwLower || sspiContext->credentials.dwUpper)) { if (sspiContext->authfinished) { freeBuffer(&outBufferDesc); sspiContext->authfinished = 0; NE_DEBUG(NE_DBG_HTTPAUTH,"sspi: failing because starting over from failed try.\n"); return -1; } sspiContext->authfinished = 0; } /* Reset any existing context since we are starting over */ resetContext(sspiContext); if (acquireCredentialsHandle (&sspiContext->credentials, sspiContext->mechanism) != SEC_E_OK) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: acquireCredentialsHandle failed.\n"); return -1; } securityStatus = initializeSecurityContext(&sspiContext->credentials, NULL, sspiContext->serverName, contextFlags, NULL, &(sspiContext->context), &outBufferDesc); } if (securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_COMPLETE_NEEDED) { SECURITY_STATUS compleStatus = pSFT->CompleteAuthToken(&(sspiContext->context), &outBufferDesc); if (compleStatus != SEC_E_OK) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: CompleteAuthToken failed.\n"); return -1; } } if (securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_CONTINUE_NEEDED) { sspiContext->continueNeeded = 1; } else { sspiContext->continueNeeded = 0; } if (!(securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_COMPLETE_NEEDED || securityStatus == SEC_I_CONTINUE_NEEDED || securityStatus == SEC_E_OK)) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: initializeSecurityContext [failed] [%x].\n", securityStatus); freeBuffer(&outBufferDesc); return -1; } *responseToken = ne_base64(outBufferDesc.pBuffers->pvBuffer, outBufferDesc.pBuffers->cbBuffer); freeBuffer(&outBufferDesc); return 0; }