summaryrefslogtreecommitdiff
path: root/src/mongo/client/sasl_sspi.cpp
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2013-10-28 10:48:07 -0400
committerEric Milkie <milkie@10gen.com>2013-10-28 14:40:59 -0400
commit4b146301e61a7bf6dbb1c046a2a8698811f20fd3 (patch)
treeb256445817434990b93ddb01178d9ee93a0c705f /src/mongo/client/sasl_sspi.cpp
parentc86a094c97b97de8b34f6bba66068df470ff4d10 (diff)
downloadmongo-4b146301e61a7bf6dbb1c046a2a8698811f20fd3.tar.gz
SERVER-11356 fix DecryptMessage; avoid memory corruption
Diffstat (limited to 'src/mongo/client/sasl_sspi.cpp')
-rw-r--r--src/mongo/client/sasl_sspi.cpp40
1 files changed, 13 insertions, 27 deletions
diff --git a/src/mongo/client/sasl_sspi.cpp b/src/mongo/client/sasl_sspi.cpp
index d3391f1f9db..537a52aebe6 100644
--- a/src/mongo/client/sasl_sspi.cpp
+++ b/src/mongo/client/sasl_sspi.cpp
@@ -207,41 +207,27 @@ namespace {
sasl_client_params_t* cparams,
const char *serverin,
unsigned serverinlen) {
- SecPkgContext_Sizes sizes;
- SECURITY_STATUS status = QueryContextAttributesW(&pcctx->ctx,
- SECPKG_ATTR_SIZES,
- &sizes);
- if (status != SEC_E_OK) {
- HandleLastError(cparams->utils, status, "QueryContextAttributes(sizes)");
- return SASL_FAIL;
- }
-
- unsigned bufferLength = sizes.cbMaxToken + sizes.cbMaxSignature + sizes.cbSecurityTrailer;
- boost::scoped_array<char> message(new char[bufferLength]);
- if (serverinlen > bufferLength) {
- cparams->utils->seterror(cparams->utils->conn, 0, "SSPI: server message is too long");
- return SASL_FAIL;
- }
+ boost::scoped_array<char> message(new char[serverinlen]);
memcpy(message.get(), serverin, serverinlen);
- SecBuffer wrapBufs[4];
+ SecBuffer wrapBufs[2];
SecBufferDesc wrapBufDesc;
wrapBufDesc.cBuffers = 2;
wrapBufDesc.pBuffers = wrapBufs;
wrapBufDesc.ulVersion = SECBUFFER_VERSION;
- wrapBufs[0].cbBuffer = 0;
- wrapBufs[0].BufferType = SECBUFFER_DATA;
+ wrapBufs[0].cbBuffer = serverinlen;
+ wrapBufs[0].BufferType = SECBUFFER_STREAM;
wrapBufs[0].pvBuffer = message.get();
- wrapBufs[1].cbBuffer = serverinlen;
- wrapBufs[1].BufferType = SECBUFFER_STREAM;
- wrapBufs[1].pvBuffer = message.get();
+ wrapBufs[1].cbBuffer = 0;
+ wrapBufs[1].BufferType = SECBUFFER_DATA;
+ wrapBufs[1].pvBuffer = NULL;
- status = DecryptMessage(&pcctx->ctx,
- &wrapBufDesc,
- 0,
- NULL);
+ SECURITY_STATUS status = DecryptMessage(&pcctx->ctx,
+ &wrapBufDesc,
+ 0,
+ NULL);
if (status != SEC_E_OK) {
HandleLastError(cparams->utils, status, "DecryptMessage");
return SASL_FAIL;
@@ -249,14 +235,14 @@ namespace {
// Validate the server's plaintext message.
// Length (as per RFC 4752)
- if (wrapBufs[0].cbBuffer < 4) {
+ if (wrapBufs[1].cbBuffer < 4) {
cparams->utils->seterror(cparams->utils->conn, 0, "SSPI: server message is too short");
return SASL_FAIL;
}
// First bit of first byte set, indicating that the client may elect to use no
// security layer. As a client we are uninterested in any of the other features the
// server offers and thus we ignore the other bits.
- if (!(static_cast<char*>(wrapBufs[0].pvBuffer)[0] & 1)) {
+ if (!(static_cast<char*>(wrapBufs[1].pvBuffer)[0] & 1)) {
cparams->utils->seterror(cparams->utils->conn, 0,
"SSPI: server does not support the required security layer");
return SASL_BADAUTH;