Skip to content

CSHARP-4335: Do not connect to mongocryptd if shared library is loaded. #969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
using MongoDB.Driver.Core.Authentication.External;
using MongoDB.Driver.Core.Bindings;
using MongoDB.Driver.Core.Clusters;
using MongoDB.Driver.Core.Configuration;
using MongoDB.Driver.Core.Events;
using MongoDB.Driver.Core.Misc;
using MongoDB.Driver.Core.Operations;
Expand Down Expand Up @@ -250,6 +249,75 @@ public void BsonSizeLimitAndBatchSizeSplittingTest(
}
}

[SkippableTheory]
[ParameterAttributeData]
public void BypassMongocryptdClientWhenSharedLibraryTest(
[Values(false, true)] bool async)
{
RequireServer.Check().Supports(Feature.ClientSideEncryption);
RequireEnvironment.Check().EnvironmentVariable("CRYPT_SHARED_LIB_PATH", isDefined: true, allowEmpty: false);
// socket.Close can hang on non windows OS. Might be related to this issue: https://github.com/dotnet/runtime/issues/47342
RequirePlatform
.Check()
.SkipWhen(SupportedOperatingSystem.Linux)
.SkipWhen(SupportedOperatingSystem.MacOS);

const int mongocryptPort = 27030;
var timeout = TimeSpan.FromSeconds(3);
var extraOptions = new Dictionary<string, object>
{
{ "mongocryptdURI", $"mongodb://localhost:{mongocryptPort}" }
};

var mongocryptdIpAddress = IPAddress.Parse("127.0.0.1");
TcpListener tcpListener = null;
try
{
tcpListener = new TcpListener(mongocryptdIpAddress, port: mongocryptPort);
var listenerThread = new Thread(new ParameterizedThreadStart(ThreadStart)) { IsBackground = true };

using (var clientEncrypted = ConfigureClientEncrypted(kmsProviderFilter: "local", extraOptions: extraOptions))
{
var coll = GetCollection(clientEncrypted, __collCollectionNamespace);

listenerThread.Start(tcpListener);

_ = Record.Exception(() => Insert(coll, async, new BsonDocument("unencrypted", "test")));

if (listenerThread.Join(timeout))
{
// This exception is never thrown when mognocryptd mongoClient is not spawned which is expected behavior.
// However, if we intentionally break that logic to spawn mongocryptd mongoClient regardless of shared library,
// this exception sometimes won't be thrown. In all such cases the spent time in listenerThread.Join is higher
// or really close to timeout. So it's unclear why Join doesn't throw in that cases, but that logic is unrelated
// to the driver and csfle in particular. We rely on the fact that even if we break this logic,
// we run this test more than once.
throw new Exception($"Listener accepted a tcp call for moncgocryptd during {timeout}.");
}
}
}
finally
{
tcpListener?.Stop();
}

void ThreadStart(object param)
{
try
{
var tcpListener = (TcpListener)param;
tcpListener.Start();
using var client = tcpListener.AcceptTcpClient();
// Perform a blocking call to accept requests.
// if we're here, then something queries port 27030.
}
catch (SocketException)
{
// listener stopped outside thread
}
}
}

[SkippableTheory]
[ParameterAttributeData]
public void BypassSpawningMongocryptdViaMongocryptdBypassSpawnTest(
Expand Down