Skip to content

Commit 8a6cbbe

Browse files
committed
Added basic multi-security context support.
1 parent c3caa1f commit 8a6cbbe

11 files changed

Lines changed: 656 additions & 193 deletions

NtApiDotNet/DisposableList.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public T[] ToArrayAndClear()
8686
return ret;
8787
}
8888

89+
/// <summary>
90+
/// Detach a detachable reference and add it to the list.
91+
/// </summary>
92+
/// <typeparam name="R">The type of resource to detach.</typeparam>
93+
/// <returns>The detached resource.</returns>
94+
public R Detach<R>(DetachableContainer<R> container) where R : class, T
95+
{
96+
return AddResource(container.Detach());
97+
}
98+
8999
#region IDisposable Support
90100
private bool disposedValue = false;
91101

NtApiDotNet/NtApiDotNet.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@
247247
<Compile Include="Security\INtObjectSecurity.cs" />
248248
<Compile Include="Utilities\Collections\CollectionUtils.cs" />
249249
<Compile Include="Utilities\Memory\UnmanagedUtils.cs" />
250+
<Compile Include="Utilities\Misc\DetachableContainer.cs" />
251+
<Compile Include="Utilities\Misc\MiscUtils.cs" />
250252
<Compile Include="Utilities\Reflection\ReflectionUtils.cs" />
251253
<Compile Include="Utilities\Reflection\SDKNameAttribute.cs" />
252254
<Compile Include="SecurityDescriptorSid.cs" />
@@ -460,6 +462,7 @@
460462
<Compile Include="Win32\DirectoryService\DirectoryServiceNameFormat.cs" />
461463
<Compile Include="Win32\DirectoryService\DirectoryServiceNameResult.cs" />
462464
<Compile Include="Win32\DirectoryService\DirectoryServiceNativeMethods.cs" />
465+
<Compile Include="Win32\Rpc\Transport\RpcTransportSecurityContext.cs" />
463466
<Compile Include="Win32\SafeHandles\SafeDirectoryServiceHandle.cs" />
464467
<Compile Include="Win32\DirectoryService\DirectoryServiceSecurityPrincipal.cs" />
465468
<Compile Include="Win32\DirectoryService\DirectoryServiceReferenceClass.cs" />
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2021 Google LLC. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Threading;
17+
18+
namespace NtApiDotNet.Utilities.Misc
19+
{
20+
/// <summary>
21+
/// A container which can detach an innner reference.
22+
/// </summary>
23+
/// <typeparam name="T"></typeparam>
24+
public sealed class DetachableContainer<T> : IDisposable where T : class, IDisposable
25+
{
26+
private T _obj;
27+
28+
internal DetachableContainer(T obj)
29+
{
30+
_obj = obj;
31+
}
32+
33+
/// <summary>
34+
/// Get the contained value.
35+
/// </summary>
36+
public T Value => _obj;
37+
38+
/// <summary>
39+
/// Detach the object so the original isn't disposed.
40+
/// </summary>
41+
/// <returns>Detached object.</returns>
42+
public T Detach()
43+
{
44+
return Interlocked.Exchange(ref _obj, null);
45+
}
46+
47+
void IDisposable.Dispose()
48+
{
49+
_obj?.Dispose();
50+
}
51+
}
52+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2021 Google LLC. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
17+
namespace NtApiDotNet.Utilities.Misc
18+
{
19+
/// <summary>
20+
/// Miscellaneous utilities.
21+
/// </summary>
22+
public static class MiscUtils
23+
{
24+
/// <summary>
25+
/// Convert a disposable object to a detachable object.
26+
/// </summary>
27+
/// <typeparam name="T">The disposable object type.</typeparam>
28+
/// <param name="obj">The disposable object.</param>
29+
/// <returns>The disposable container.</returns>
30+
public static DetachableContainer<T> AsDetachable<T>(this T obj) where T : class, IDisposable
31+
{
32+
return new DetachableContainer<T>(obj);
33+
}
34+
}
35+
}
Lines changed: 102 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,114 @@
1-
// Copyright 2019 Google Inc. All Rights Reserved.
2-
//
3-
// Licensed under the Apache License, Version 2.0 (the "License");
4-
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License at
6-
//
7-
// http://www.apache.org/licenses/LICENSE-2.0
8-
//
9-
// Unless required by applicable law or agreed to in writing, software
10-
// distributed under the License is distributed on an "AS IS" BASIS,
11-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
// See the License for the specific language governing permissions and
13-
// limitations under the License.
14-
15-
using NtApiDotNet.Ndr.Marshal;
16-
using System;
17-
using System.Collections.Generic;
18-
19-
namespace NtApiDotNet.Win32.Rpc.Transport
20-
{
21-
/// <summary>
22-
/// Interface to implement an RPC client transport.
23-
/// </summary>
24-
public interface IRpcClientTransport : IDisposable
25-
{
26-
/// <summary>
27-
/// Bind the RPC transport to a specified interface.
28-
/// </summary>
29-
/// <param name="interface_id">The interface ID to bind to.</param>
30-
/// <param name="interface_version">The interface version to bind to.</param>
31-
/// <param name="transfer_syntax_id">The transfer syntax to use.</param>
32-
/// <param name="transfer_syntax_version">The transfer syntax version to use.</param>
33-
void Bind(Guid interface_id, Version interface_version, Guid transfer_syntax_id, Version transfer_syntax_version);
34-
35-
/// <summary>
36-
/// Send and receive an RPC message.
37-
/// </summary>
38-
/// <param name="proc_num">The procedure number.</param>
39-
/// <param name="objuuid">The object UUID for the call.</param>
40-
/// <param name="data_representation">NDR data representation.</param>
41-
/// <param name="ndr_buffer">Marshal NDR buffer for the call.</param>
42-
/// <param name="handles">List of handles marshaled into the buffer.</param>
43-
/// <returns>Client response from the send.</returns>
44-
RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresentation data_representation,
45-
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles);
46-
47-
/// <summary>
48-
/// Disconnect the transport.
49-
/// </summary>
50-
void Disconnect();
51-
52-
/// <summary>
53-
/// Get whether the client is connected or not.
54-
/// </summary>
55-
bool Connected { get; }
56-
57-
/// <summary>
58-
/// Get the endpoint the client is connected to.
59-
/// </summary>
60-
string Endpoint { get; }
61-
62-
/// <summary>
63-
/// Get the transport protocol sequence.
64-
/// </summary>
65-
string ProtocolSequence { get; }
66-
1+
// Copyright 2019 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using NtApiDotNet.Ndr.Marshal;
16+
using System;
17+
using System.Collections.Generic;
18+
19+
namespace NtApiDotNet.Win32.Rpc.Transport
20+
{
21+
/// <summary>
22+
/// Interface to implement an RPC client transport.
23+
/// </summary>
24+
public interface IRpcClientTransport : IDisposable
25+
{
26+
/// <summary>
27+
/// Bind the RPC transport to a specified interface.
28+
/// </summary>
29+
/// <param name="interface_id">The interface ID to bind to.</param>
30+
/// <param name="interface_version">The interface version to bind to.</param>
31+
/// <param name="transfer_syntax_id">The transfer syntax to use.</param>
32+
/// <param name="transfer_syntax_version">The transfer syntax version to use.</param>
33+
void Bind(Guid interface_id, Version interface_version, Guid transfer_syntax_id, Version transfer_syntax_version);
34+
35+
/// <summary>
36+
/// Send and receive an RPC message.
37+
/// </summary>
38+
/// <param name="proc_num">The procedure number.</param>
39+
/// <param name="objuuid">The object UUID for the call.</param>
40+
/// <param name="data_representation">NDR data representation.</param>
41+
/// <param name="ndr_buffer">Marshal NDR buffer for the call.</param>
42+
/// <param name="handles">List of handles marshaled into the buffer.</param>
43+
/// <returns>Client response from the send.</returns>
44+
RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresentation data_representation,
45+
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles);
46+
47+
/// <summary>
48+
/// Add and authenticate a new security context.
49+
/// </summary>
50+
/// <param name="transport_security">The transport security for the context.</param>
51+
/// <returns>The created security context.</returns>
52+
RpcTransportSecurityContext AddSecurityContext(RpcTransportSecurity transport_security);
53+
54+
/// <summary>
55+
/// Disconnect the transport.
56+
/// </summary>
57+
void Disconnect();
58+
59+
/// <summary>
60+
/// Get whether the client is connected or not.
61+
/// </summary>
62+
bool Connected { get; }
63+
64+
/// <summary>
65+
/// Get the endpoint the client is connected to.
66+
/// </summary>
67+
string Endpoint { get; }
68+
69+
/// <summary>
70+
/// Get the transport protocol sequence.
71+
/// </summary>
72+
string ProtocolSequence { get; }
73+
6774
/// <summary>
6875
/// Get whether the client has been authenticated.
69-
/// </summary>
70-
bool Authenticated { get; }
71-
76+
/// </summary>
77+
bool Authenticated { get; }
78+
7279
/// <summary>
73-
/// Get the transports authentication type.
74-
/// </summary>
75-
RpcAuthenticationType AuthenticationType { get; }
76-
80+
/// Get the transport's authentication type.
81+
/// </summary>
82+
RpcAuthenticationType AuthenticationType { get; }
83+
7784
/// <summary>
78-
/// Get the transports authentication level.
79-
/// </summary>
80-
RpcAuthenticationLevel AuthenticationLevel { get; }
81-
85+
/// Get the transport's authentication level.
86+
/// </summary>
87+
RpcAuthenticationLevel AuthenticationLevel { get; }
88+
8289
/// <summary>
8390
/// Get information about the local server process, if known.
84-
/// </summary>
91+
/// </summary>
8592
RpcServerProcessInformation ServerProcess { get; }
8693

8794
/// <summary>
8895
/// Get the current Call ID.
8996
/// </summary>
9097
int CallId { get; }
91-
}
92-
}
98+
99+
/// <summary>
100+
/// Indicates if this connection supported multiple security context.
101+
/// </summary>
102+
bool SupportsMultipleSecurityContexts { get; }
103+
104+
/// <summary>
105+
/// Get the list of negotiated security context.
106+
/// </summary>
107+
IReadOnlyList<RpcTransportSecurityContext> SecurityContext { get; }
108+
109+
/// <summary>
110+
/// Get or set the current security context.
111+
/// </summary>
112+
RpcTransportSecurityContext CurrentSecurityContext { get; set; }
113+
}
114+
}

NtApiDotNet/Win32/Rpc/Transport/RpcAlpcClientTransport.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class RpcAlpcClientTransport : IRpcClientTransport
2525
{
2626
#region Private Members
2727
private NtAlpcClient _client;
28+
private readonly SecurityQualityOfService _sqos;
2829

2930
private static AlpcPortAttributes CreatePortAttributes(SecurityQualityOfService sqos)
3031
{
@@ -241,6 +242,7 @@ public RpcAlpcClientTransport(string path, SecurityQualityOfService security_qua
241242
}
242243

243244
_client = ConnectPort(path, security_quality_of_service);
245+
_sqos = security_quality_of_service;
244246
Endpoint = path;
245247
}
246248
#endregion
@@ -300,6 +302,16 @@ public void Disconnect()
300302
Dispose();
301303
}
302304

305+
/// <summary>
306+
/// Add and authenticate a new security context.
307+
/// </summary>
308+
/// <param name="transport_security">The transport security for the context.</param>
309+
/// <returns>The created security context.</returns>
310+
public RpcTransportSecurityContext AddSecurityContext(RpcTransportSecurity transport_security)
311+
{
312+
throw new InvalidOperationException("Transport doesn't support multiple security context.");
313+
}
314+
303315
#endregion
304316

305317
#region Public Properties
@@ -351,6 +363,28 @@ public RpcServerProcessInformation ServerProcess
351363
/// </summary>
352364
public RpcAuthenticationLevel AuthenticationLevel => Authenticated ? RpcAuthenticationLevel.PacketPrivacy : RpcAuthenticationLevel.None;
353365

366+
/// <summary>
367+
/// Indicates if this connection supported multiple security context.
368+
/// </summary>
369+
public bool SupportsMultipleSecurityContexts => false;
370+
371+
/// <summary>
372+
/// Get the list of negotiated security context.
373+
/// </summary>
374+
public IReadOnlyList<RpcTransportSecurityContext> SecurityContext =>
375+
new List<RpcTransportSecurityContext>() { CurrentSecurityContext }.AsReadOnly();
376+
377+
/// <summary>
378+
/// Get or set the current security context.
379+
/// </summary>
380+
public RpcTransportSecurityContext CurrentSecurityContext {
381+
get => new RpcTransportSecurityContext(this, new RpcTransportSecurity(_sqos)
382+
{
383+
AuthenticationType = AuthenticationType,
384+
AuthenticationLevel = AuthenticationLevel
385+
}, 0);
386+
set => throw new InvalidOperationException("Transport doesn't support multiple security context."); }
387+
354388
#endregion
355389
}
356390
}

0 commit comments

Comments
 (0)