mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-06 18:35:19 +00:00
THRIFT-5391 Named pipes transport hardening
Client: netstd Patch: Jens Geyer This closes #2367
This commit is contained in:
parent
20a86d68e9
commit
ef0cb01abe
@ -17,6 +17,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO.Pipes;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -39,7 +40,7 @@ namespace Thrift.Transport.Client
|
||||
var serverName = string.IsNullOrWhiteSpace(server) ? server : ".";
|
||||
ConnectTimeout = (timeout > 0) ? timeout : Timeout.Infinite;
|
||||
|
||||
PipeStream = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None);
|
||||
PipeStream = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Anonymous);
|
||||
}
|
||||
|
||||
public override bool IsOpen => PipeStream != null && PipeStream.IsConnected;
|
||||
|
@ -27,6 +27,12 @@ using System.Security.Principal;
|
||||
|
||||
namespace Thrift.Transport.Server
|
||||
{
|
||||
[Flags]
|
||||
public enum NamedPipeClientFlags {
|
||||
None = 0x00,
|
||||
OnlyLocalClients = 0x01
|
||||
};
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class TNamedPipeServerTransport : TServerTransport
|
||||
{
|
||||
@ -37,11 +43,21 @@ namespace Thrift.Transport.Server
|
||||
private bool _asyncMode = true;
|
||||
private volatile bool _isPending = true;
|
||||
private NamedPipeServerStream _stream = null;
|
||||
private readonly bool _onlyLocalClients = false; // compatibility default
|
||||
|
||||
public TNamedPipeServerTransport(string pipeAddress, TConfiguration config, NamedPipeClientFlags flags)
|
||||
: base(config)
|
||||
{
|
||||
_pipeAddress = pipeAddress;
|
||||
_onlyLocalClients = flags.HasFlag(NamedPipeClientFlags.OnlyLocalClients);
|
||||
}
|
||||
|
||||
[Obsolete("This CTOR is deprecated, please use the other one instead.")]
|
||||
public TNamedPipeServerTransport(string pipeAddress, TConfiguration config)
|
||||
: base(config)
|
||||
{
|
||||
_pipeAddress = pipeAddress;
|
||||
_onlyLocalClients = false;
|
||||
}
|
||||
|
||||
public override bool IsOpen() {
|
||||
@ -96,7 +112,7 @@ namespace Thrift.Transport.Server
|
||||
|
||||
try
|
||||
{
|
||||
var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf);
|
||||
var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf, _onlyLocalClients);
|
||||
if ((handle != null) && (!handle.IsInvalid))
|
||||
{
|
||||
_stream = new NamedPipeServerStream(PipeDirection.InOut, _asyncMode, false, handle);
|
||||
@ -149,14 +165,14 @@ namespace Thrift.Transport.Server
|
||||
|
||||
|
||||
// Workaround: create the pipe via API call
|
||||
// we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs
|
||||
// we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs and/or arguments
|
||||
// and _stream.SetAccessControl(pipesec); only keeps throwing ACCESS_DENIED errors at us
|
||||
// References:
|
||||
// - https://github.com/dotnet/corefx/issues/30170 (closed, continued in 31190)
|
||||
// - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work
|
||||
// - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC
|
||||
// - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe
|
||||
private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf)
|
||||
private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf, bool OnlyLocalClients)
|
||||
{
|
||||
if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
return null; // Windows only
|
||||
@ -187,18 +203,25 @@ namespace Thrift.Transport.Server
|
||||
}
|
||||
|
||||
// a bunch of constants we will need shortly
|
||||
const int PIPE_ACCESS_DUPLEX = 0x00000003;
|
||||
const int FILE_FLAG_OVERLAPPED = 0x40000000;
|
||||
const int WRITE_DAC = 0x00040000;
|
||||
const int PIPE_TYPE_BYTE = 0x00000000;
|
||||
const int PIPE_READMODE_BYTE = 0x00000000;
|
||||
const int PIPE_UNLIMITED_INSTANCES = 255;
|
||||
const uint PIPE_ACCESS_DUPLEX = 0x00000003;
|
||||
const uint FILE_FLAG_OVERLAPPED = 0x40000000;
|
||||
const uint WRITE_DAC = 0x00040000;
|
||||
const uint PIPE_TYPE_BYTE = 0x00000000;
|
||||
const uint PIPE_READMODE_BYTE = 0x00000000;
|
||||
const uint PIPE_UNLIMITED_INSTANCES = 255;
|
||||
const uint PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000; // Connections from remote clients can be accepted and checked against the security descriptor for the pipe.
|
||||
const uint PIPE_REJECT_REMOTE_CLIENTS = 0x00000008; // Connections from remote clients are automatically rejected.
|
||||
|
||||
// any extra flags we want to add
|
||||
uint dwPipeModeXtra
|
||||
= (OnlyLocalClients ? PIPE_REJECT_REMOTE_CLIENTS : PIPE_ACCEPT_REMOTE_CLIENTS)
|
||||
;
|
||||
|
||||
// create the pipe via API call
|
||||
var rawHandle = CreateNamedPipe(
|
||||
@"\\.\pipe\" + name,
|
||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | dwPipeModeXtra,
|
||||
PIPE_UNLIMITED_INSTANCES, (uint)inbuf, (uint)outbuf,
|
||||
5 * 1000,
|
||||
secAttrs
|
||||
|
@ -149,7 +149,10 @@ namespace ThriftTest
|
||||
|
||||
public class TestServer
|
||||
{
|
||||
public static int _clientID = -1;
|
||||
#pragma warning disable CA2211
|
||||
public static int _clientID = -1; // use with Interlocked only!
|
||||
#pragma warning restore CA2211
|
||||
|
||||
private static readonly TConfiguration Configuration = null; // or new TConfiguration() if needed
|
||||
|
||||
public delegate void TestLogDelegate(string msg, params object[] values);
|
||||
@ -556,7 +559,7 @@ namespace ThriftTest
|
||||
{
|
||||
case TransportChoice.NamedPipe:
|
||||
Debug.Assert(param.pipe != null);
|
||||
trans = new TNamedPipeServerTransport(param.pipe, Configuration);
|
||||
trans = new TNamedPipeServerTransport(param.pipe, Configuration, NamedPipeClientFlags.OnlyLocalClients);
|
||||
break;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user