summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2018-03-29 13:13:29 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2018-03-29 13:13:29 -0400
commitf5ca29a16663dc991721a1486810755bab306f76 (patch)
tree1b9e65e10cb1aded1698eb5c5bea656cc9a7a55b
parentc6ee159c915ce44ed095adc0b371bc4226b68ec6 (diff)
downloadmongo-f5ca29a16663dc991721a1486810755bab306f76.tar.gz
SERVER-33832 SChannel and Test Fixes
-rw-r--r--etc/evergreen.yml23
-rw-r--r--jstests/ssl/ssl_cert_selector.js9
-rw-r--r--src/mongo/util/net/ssl/detail/impl/schannel.ipp105
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp8
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;
}