Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
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
@@ -0,0 +1,89 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;

namespace System.Net.Security
{
internal sealed class SafeFreeNegoCredentials : SafeFreeCredentials
{
private SafeGssCredHandle _credential;

public SafeGssCredHandle GssCredential
{
get { return _credential; }
}

public SafeFreeNegoCredentials(string username, string password, string domain) : base(IntPtr.Zero, true)
{
_credential = SafeGssCredHandle.Create(username, password, domain);
}

public override bool IsInvalid
{
get { return (null == _credential); }
}

protected override bool ReleaseHandle()
{
_credential.Dispose();
_credential = null;
return true;
}
}

internal sealed class SafeDeleteNegoContext : SafeDeleteContext
{
private SafeGssNameHandle _targetName;
private SafeGssContextHandle _context;

public SafeGssNameHandle TargetName
{
get { return _targetName; }
}

public SafeGssContextHandle GssContext
{
get { return _context; }
}

public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName)
: base(credential)
{
try
{
_targetName = SafeGssNameHandle.Create(targetName, false);
}
catch
{
base.ReleaseHandle();
throw;
}
}

public void SetGssContext(SafeGssContextHandle context)
{
Debug.Assert(!context.IsInvalid, "Invalid context passed to SafeDeleteNegoContext");
_context = context;
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
if (null != _context)
{
_context.Dispose();
_context = null;
}
_targetName.Dispose();
_targetName = null;
}
base.Dispose(disposing);
}
}
}
81 changes: 53 additions & 28 deletions src/Common/src/Interop/Unix/libssl/SecuritySafeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,19 @@ protected override bool ReleaseHandle()
// Implementation of handles dependable on FreeCredentialsHandle
//
#if DEBUG
internal sealed class SafeFreeCredentials : DebugSafeHandle
internal abstract class SafeFreeCredentials : DebugSafeHandle
{
#else
internal sealed class SafeFreeCredentials : SafeHandle
internal abstract class SafeFreeCredentials : SafeHandle
{
#endif
protected SafeFreeCredentials(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle)
{
}
}

internal sealed class SafeFreeSslCredentials : SafeFreeCredentials
{
private SafeX509Handle _certHandle;
private SafeEvpPKeyHandle _certKeyHandle;
private SslProtocols _protocols = SslProtocols.None;
Expand All @@ -86,7 +93,7 @@ internal EncryptionPolicy Policy
get { return _policy; }
}

public SafeFreeCredentials(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy)
public SafeFreeSslCredentials(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy)
: base(IntPtr.Zero, true)
{
Debug.Assert(
Expand Down Expand Up @@ -206,13 +213,49 @@ protected override bool ReleaseHandle()
}

#if DEBUG
internal sealed class SafeDeleteContext : DebugSafeHandle
internal abstract class SafeDeleteContext : DebugSafeHandle
{
#else
internal sealed class SafeDeleteContext : SafeHandle
internal abstract class SafeDeleteContext : SafeHandle
{
#endif
private readonly SafeFreeCredentials _credential;
private SafeFreeCredentials _credential;

protected SafeDeleteContext(SafeFreeCredentials credential)
: base(IntPtr.Zero, true)
{
Debug.Assert((null != credential), "Invalid credential passed to SafeDeleteContext");

// When a credential handle is first associated with the context we keep credential
// ref count bumped up to ensure ordered finalization. The credential properties
// are used in the SSL/NEGO data structures and should survive the lifetime of
// the SSL/NEGO context
bool ignore = false;
_credential = credential;
_credential.DangerousAddRef(ref ignore);
}

public override bool IsInvalid
{
get { return (null == _credential); }
}

protected override bool ReleaseHandle()
{
Debug.Assert((null != _credential), "Null credential in SafeDeleteContext");
_credential.DangerousRelease();
_credential = null;
return true;
}

public override string ToString()
{
return IsInvalid ? String.Empty : handle.ToString();
}
}

internal sealed class SafeDeleteSslContext : SafeDeleteContext
{
private readonly SafeSslHandle _sslContext;

public SafeSslHandle SslContext
Expand All @@ -223,18 +266,10 @@ public SafeSslHandle SslContext
}
}

public SafeDeleteContext(SafeFreeCredentials credential, bool isServer, bool remoteCertRequired)
: base(IntPtr.Zero, true)
public SafeDeleteSslContext(SafeFreeSslCredentials credential, bool isServer, bool remoteCertRequired)
: base(credential)
{
Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteContext");

// When a credential handle is first associated with the context we keep credential
// ref count bumped up to ensure ordered finalization. The certificate handle and
// key handle are used in the SSL data structures and should survive the lifetime of
// the SSL context
bool gotCredRef = false;
_credential = credential;
_credential.DangerousAddRef(ref gotCredRef);
Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext");

try
{
Expand All @@ -248,11 +283,8 @@ public SafeDeleteContext(SafeFreeCredentials credential, bool isServer, bool rem
}
catch(Exception ex)
{
if (gotCredRef)
{
_credential.DangerousRelease();
}
Debug.Write("Exception Caught. - " + ex);
base.ReleaseHandle();
throw;
}
}
Expand All @@ -265,13 +297,6 @@ public override bool IsInvalid
}
}

protected override bool ReleaseHandle()
{
Debug.Assert((null != _credential) && !_credential.IsInvalid, "Invalid credential saved in SafeDeleteContext");
_credential.DangerousRelease();
return true;
}

protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ namespace System.Net
{
// This class is used to determine if NTLM or
// Kerberos are used in the context of a Negotiate handshake
internal class NegotiationInfoClass
internal partial class NegotiationInfoClass
{
internal const string NTLM = "NTLM";
internal const string Kerberos = "Kerberos";
internal const string WDigest = "WDigest";
internal const string Negotiate = "Negotiate";
internal string AuthenticationPackage;

internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState)
Expand Down
24 changes: 21 additions & 3 deletions src/System.Net.Security/src/System.Net.Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@
<Compile Include="System\Net\SecureProtocols\ProtectionLevel.cs" />

<!-- NegotiateStream -->
<Compile Include="System\Net\ContextFlagsPal.cs" />
<Compile Include="System\Net\NTAuthentication.cs" />
<Compile Include="System\Net\SSPIHandleCache.cs" />
<Compile Include="System\Net\StreamFramer.cs" />
<Compile Include="System\Net\SecureProtocols\BufferAsyncResult.cs" />
<Compile Include="System\Net\SecureProtocols\NegotiateStream.cs" />
<Compile Include="System\Net\SecureProtocols\InternalNegoState.cs" />
<Compile Include="System\Net\SecureProtocols\InternalNegotiateStream.cs" />
<Compile Include="System\Net\NegotiationInfoClass.cs" />

<Compile Include="System\Security\Authentication\ExtendedProtection\ExtendedProtectionPolicy.cs" />
<Compile Include="System\Security\Authentication\ExtendedProtection\PolicyEnforcement.cs" />
Expand Down Expand Up @@ -143,10 +149,7 @@
<Compile Include="System\Net\CertificateValidationPal.Windows.cs" />

<!-- NegotiateStream -->
<Compile Include="System\Net\NTAuthentication.cs" />
<Compile Include="System\Net\SpnDictionary.cs" />
<Compile Include="System\Net\SSPIHandleCache.cs" />
<Compile Include="System\Net\StreamFramer.cs" />
<Compile Include="System\Net\SecureProtocols\NegoState.Windows.cs" />

<!-- Interop -->
Expand Down Expand Up @@ -292,6 +295,21 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Net.Security.Native\Interop.Initialization.cs">
<Link>Common\Interop\Unix\System.Net.Security.Native\Interop.Initialization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Net.Security.Native\Interop.GssApi.cs">
<Link>Common\Interop\Unix\System.Net.Security.Native\Interop.GssApi.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Net.Security.Native\Interop.GssApiException.cs">
<Link>Common\Interop\Unix\System.Net.Security.Native\Interop.GssApiException.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Net.Security.Native\SecuritySafeHandles.cs">
<Link>Common\Interop\Unix\System.Net.Security.Native\SecuritySafeHandles.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\GssSafeHandles.cs">
<Link>Common\Microsoft\Win32\SafeHandles\GssSafeHandles.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Net.Security.Native\Interop.NetSecurity.cs">
<Link>Common\Interop\Unix\System.Net.Security.Native\Interop.NetSecurity.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeX509Handles.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeX509Handles.Unix.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ internal static X509Certificate2 GetRemoteCertificate(SafeDeleteContext security
remoteCertificateStore = new X509Certificate2Collection();

using (SafeSharedX509StackHandle chainStack =
Interop.OpenSsl.GetPeerCertificateChain(securityContext.SslContext))
Interop.OpenSsl.GetPeerCertificateChain(((SafeDeleteSslContext)securityContext).SslContext))
{
if (!chainStack.IsInvalid)
{
Expand Down Expand Up @@ -162,7 +162,7 @@ internal static X509Certificate2 GetRemoteCertificate(SafeDeleteContext security
//
internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
{
using (SafeSharedX509NameStackHandle names = Interop.Ssl.SslGetClientCAList(securityContext.SslContext))
using (SafeSharedX509NameStackHandle names = Interop.Ssl.SslGetClientCAList(((SafeDeleteSslContext)securityContext).SslContext))
{
if (names.IsInvalid)
{
Expand Down Expand Up @@ -256,7 +256,7 @@ private static int QueryContextRemoteCertificate(SafeDeleteContext securityConte
remoteCertContext = null;
try
{
SafeX509Handle remoteCertificate = Interop.OpenSsl.GetPeerCertificate(securityContext.SslContext);
SafeX509Handle remoteCertificate = Interop.OpenSsl.GetPeerCertificate(((SafeDeleteSslContext)securityContext).SslContext);
// Note that cert ownership is transferred to SafeFreeCertContext
remoteCertContext = new SafeFreeCertContext(remoteCertificate);
return 0;
Expand Down
34 changes: 34 additions & 0 deletions src/System.Net.Security/src/System/Net/ContextFlagsPal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

namespace System.Net
{
[Flags]
internal enum ContextFlagsPal
{
Zero = 0,
Delegate = 0x00000001,
MutualAuth = 0x00000002,
ReplayDetect = 0x00000004,
SequenceDetect = 0x00000008,
Confidentiality = 0x00000010,
UseSessionKey = 0x00000020,
AllocateMemory = 0x00000100,
Connection = 0x00000800,
InitExtendedError = 0x00004000,
AcceptExtendedError = 0x00008000,
InitStream = 0x00008000,
AcceptStream = 0x00010000,
InitIntegrity = 0x00010000,
AcceptIntegrity = 0x00020000,
InitManualCredValidation = 0x00080000,
InitUseSuppliedCreds = 0x00000080,
InitIdentify = 0x00020000,
AcceptIdentify = 0x00080000,
ProxyBindings = 0x04000000,
AllowMissingBindings = 0x10000000,
UnverifiedTargetName = 0x20000000,
}
}
Loading