diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2018-03-29 13:13:29 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2018-03-29 13:13:29 -0400 |
commit | f5ca29a16663dc991721a1486810755bab306f76 (patch) | |
tree | 1b9e65e10cb1aded1698eb5c5bea656cc9a7a55b | |
parent | c6ee159c915ce44ed095adc0b371bc4226b68ec6 (diff) | |
download | mongo-f5ca29a16663dc991721a1486810755bab306f76.tar.gz |
SERVER-33832 SChannel and Test Fixes
-rw-r--r-- | etc/evergreen.yml | 23 | ||||
-rw-r--r-- | jstests/ssl/ssl_cert_selector.js | 9 | ||||
-rw-r--r-- | src/mongo/util/net/ssl/detail/impl/schannel.ipp | 105 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_windows.cpp | 8 |
4 files changed, 91 insertions, 54 deletions
diff --git a/etc/evergreen.yml b/etc/evergreen.yml index 24e1547f82c..75589b338f3 100644 --- a/etc/evergreen.yml +++ b/etc/evergreen.yml @@ -6197,6 +6197,29 @@ buildvariants: ext: zip use_scons_cache: true +- <<: *enterprise-windows-64-2k8-template + name: enterprise-windows-64-2k8-openssl + display_name: "~ Enterprise Windows 2008R2 OpenSSL" + batchtime: 1440 # 1 day + modules: + - enterprise + expansions: + test_flags: --excludeWithAnyTags=requires_mmapv1 + platform_decompress: unzip + tooltags: "-tags 'ssl sasl'" + exe: ".exe" + gorootvars: 'PATH="/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:/cygdrive/c/sasl/:$PATH" CGO_CFLAGS="-D_WIN32_WINNT=0x0601 -DNTDDI_VERSION=0x06010000"' + msi_target: msi + content_type: application/zip + compile_flags: --release --ssl --ssl-provider=openssl MONGO_DISTMOD=windows-64 CPPPATH="c:/openssl/include c:/sasl/include c:/snmp/include c:/curl/include" LIBPATH="c:/openssl/lib c:/sasl/lib c:/snmp/lib c:/curl/lib" -j$(( $(grep -c ^processor /proc/cpuinfo) / 2 )) --dynamic-windows --win-version-min=ws08r2 + # We invoke SCons using --jobs = (# of CPUs / 4) to avoid causing out of memory errors due to + # spawning a large number of linker processes. + num_scons_compile_all_jobs_available: $(( $(grep -c ^processor /proc/cpuinfo) / 4 )) + python: python + num_jobs_available: $(grep -c ^processor /proc/cpuinfo) + ext: zip + use_scons_cache: true + - name: enterprise-windows-64-2k8-async display_name: "~ Enterprise Windows 2008R2 async" modules: diff --git a/jstests/ssl/ssl_cert_selector.js b/jstests/ssl/ssl_cert_selector.js index 35e002863fa..b62c9cb2890 100644 --- a/jstests/ssl/ssl_cert_selector.js +++ b/jstests/ssl/ssl_cert_selector.js @@ -14,13 +14,8 @@ requireSSLProvider('windows', function() { // Import a pfx file since it contains both a cert and private key and is easy to import // via command line. - runProgram("certutil.exe", - "-importpfx", - "-f", - "-p", - "foo", - "My", - "jstests\\libs\\trusted-client.pfx"); + runProgram( + "certutil.exe", "-importpfx", "-f", "-p", "foo", "jstests\\libs\\trusted-client.pfx"); } const conn = MongoRunner.runMongod( diff --git a/src/mongo/util/net/ssl/detail/impl/schannel.ipp b/src/mongo/util/net/ssl/detail/impl/schannel.ipp index d0741260dfc..288dfa3c56e 100644 --- a/src/mongo/util/net/ssl/detail/impl/schannel.ipp +++ b/src/mongo/util/net/ssl/detail/impl/schannel.ipp @@ -563,63 +563,80 @@ ssl_want SSLReadManager::readDecryptedData(void* data, } ssl_want SSLReadManager::decryptBuffer(asio::error_code& ec, DecryptState* pDecryptState) { - std::array<SecBuffer, 4> securityBuffers; - securityBuffers[0].cbBuffer = _pInBuffer->size(); - securityBuffers[0].BufferType = SECBUFFER_DATA; - securityBuffers[0].pvBuffer = _pInBuffer->data(); + while (true) { + std::array<SecBuffer, 4> securityBuffers; + securityBuffers[0].cbBuffer = _pInBuffer->size(); + securityBuffers[0].BufferType = SECBUFFER_DATA; + securityBuffers[0].pvBuffer = _pInBuffer->data(); - securityBuffers[1].cbBuffer = 0; - securityBuffers[1].BufferType = SECBUFFER_EMPTY; - securityBuffers[1].pvBuffer = NULL; + securityBuffers[1].cbBuffer = 0; + securityBuffers[1].BufferType = SECBUFFER_EMPTY; + securityBuffers[1].pvBuffer = NULL; - securityBuffers[2].cbBuffer = 0; - securityBuffers[2].BufferType = SECBUFFER_EMPTY; - securityBuffers[2].pvBuffer = NULL; + securityBuffers[2].cbBuffer = 0; + securityBuffers[2].BufferType = SECBUFFER_EMPTY; + securityBuffers[2].pvBuffer = NULL; - securityBuffers[3].cbBuffer = 0; - securityBuffers[3].BufferType = SECBUFFER_EMPTY; - securityBuffers[3].pvBuffer = NULL; + securityBuffers[3].cbBuffer = 0; + securityBuffers[3].BufferType = SECBUFFER_EMPTY; + securityBuffers[3].pvBuffer = NULL; - SecBufferDesc bufferDesc; - bufferDesc.ulVersion = SECBUFFER_VERSION; - bufferDesc.cBuffers = securityBuffers.size(); - bufferDesc.pBuffers = securityBuffers.data(); + SecBufferDesc bufferDesc; + bufferDesc.ulVersion = SECBUFFER_VERSION; + bufferDesc.cBuffers = securityBuffers.size(); + bufferDesc.pBuffers = securityBuffers.data(); - SECURITY_STATUS ss = DecryptMessage(_phctxt, &bufferDesc, 0, NULL); + SECURITY_STATUS ss = DecryptMessage(_phctxt, &bufferDesc, 0, NULL); - if (ss < SEC_E_OK) { - if (ss == SEC_E_INCOMPLETE_MESSAGE) { - return ssl_want::want_input_and_retry; - } else { - ec = asio::error_code(ss, asio::error::get_ssl_category()); - return ssl_want::want_nothing; + if (ss < SEC_E_OK) { + if (ss == SEC_E_INCOMPLETE_MESSAGE) { + return ssl_want::want_input_and_retry; + } else { + ec = asio::error_code(ss, asio::error::get_ssl_category()); + return ssl_want::want_nothing; + } } - } - // Shutdown has been initiated at the client side - if (ss == SEC_I_CONTEXT_EXPIRED) { - *pDecryptState = DecryptState::Shutdown; - } else if (ss == SEC_I_RENEGOTIATE) { - *pDecryptState = DecryptState::Renegotiate; + // Shutdown has been initiated at the client side + if (ss == SEC_I_CONTEXT_EXPIRED) { + *pDecryptState = DecryptState::Shutdown; + } else if (ss == SEC_I_RENEGOTIATE) { + *pDecryptState = DecryptState::Renegotiate; - // Fail the connection on SSL renegotiations - ec = asio::ssl::error::stream_truncated; - return ssl_want::want_nothing; - } + // Fail the connection on SSL renegotiations + ec = asio::ssl::error::stream_truncated; + return ssl_want::want_nothing; + } - if (securityBuffers[1].cbBuffer > 0) { - _pInBuffer->resetPos(securityBuffers[1].pvBuffer, securityBuffers[1].cbBuffer); - } + // The network layer may have read more then 1 SSL packet so remember the extra data. + if (securityBuffers[3].BufferType == SECBUFFER_EXTRA && securityBuffers[3].cbBuffer > 0) { + ASIO_ASSERT(_pExtraEncryptedBuffer->empty()); + _pExtraEncryptedBuffer->append(securityBuffers[3].pvBuffer, + securityBuffers[3].cbBuffer); + } - // The network layer may have read more then 1 SSL packet so remember the extra data. - if (securityBuffers[3].BufferType == SECBUFFER_EXTRA && securityBuffers[3].cbBuffer > 0) { - ASIO_ASSERT(_pExtraEncryptedBuffer->empty()); - _pExtraEncryptedBuffer->append(securityBuffers[3].pvBuffer, securityBuffers[3].cbBuffer); - } + // Check if we have application data + if (securityBuffers[1].cbBuffer > 0) { + _pInBuffer->resetPos(securityBuffers[1].pvBuffer, securityBuffers[1].cbBuffer); - setState(State::HaveDecryptedData); + setState(State::HaveDecryptedData); - return ssl_want::want_nothing; + return ssl_want::want_nothing; + } else { + // Sigh, this means that the remote side sent us an TLS record with just a encryption + // header/trailer but no actual data. + // + // If we have extra encrypted data, we may have a TLS record with some data, otherwise + // we need more data from the remote side + if (!_pExtraEncryptedBuffer->empty()) { + _pInBuffer->swap(*_pExtraEncryptedBuffer); + _pExtraEncryptedBuffer->reset(); + continue; + } + + return ssl_want::want_input_and_retry; + } + } } diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp index 2bba7fa088f..3e91df52fe9 100644 --- a/src/mongo/util/net/ssl_manager_windows.cpp +++ b/src/mongo/util/net/ssl_manager_windows.cpp @@ -510,13 +510,15 @@ int SSLManagerWindows::SSL_read(SSLConnectionInterface* connInterface, void* buf // 1. fetch some from the network // 2. give it to ASIO // 3. retry - int ret = - recv(conn->socket->rawFD(), reinterpret_cast<char*>(buf), num, portRecvFlags); + int ret = recv(conn->socket->rawFD(), + conn->_tempBuffer.data(), + conn->_tempBuffer.size(), + portRecvFlags); if (ret == SOCKET_ERROR) { conn->socket->handleRecvError(ret, num); } - conn->_engine.put_input(asio::const_buffer(buf, ret)); + conn->_engine.put_input(asio::const_buffer(conn->_tempBuffer.data(), ret)); continue; } |