Working on comments.
This commit is contained in:
@@ -9,12 +9,30 @@ using NSspi.Credentials;
|
||||
|
||||
namespace NSspi.Contexts
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a client security context. Provides the means to establish a shared security context
|
||||
/// with the server and to encrypt, decrypt, sign and verify messages to and from the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A client and server establish a shared security context by exchanging authentication tokens. Once
|
||||
/// the shared context is established, the client and server can pass messages to each other, encrypted,
|
||||
/// signed, etc, using the established parameters of the shared context.
|
||||
/// </remarks>
|
||||
public class ClientContext : Context
|
||||
{
|
||||
private ContextAttrib requestedAttribs;
|
||||
private ContextAttrib finalAttribs;
|
||||
private string serverPrinc;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ClientContext class. The context is not fully initialized and usable
|
||||
/// until the authentication cycle has been completed.
|
||||
/// </summary>
|
||||
/// <param name="cred">The security credential to authenticate as.</param>
|
||||
/// <param name="serverPrinc">The principle name of the server to connect to, or null for any.</param>
|
||||
/// <param name="requestedAttribs">Requested attributes that describe the desired properties of the
|
||||
/// context once it is established. If a context cannot be established that satisfies the indicated
|
||||
/// properties, the context initialization is aborted.</param>
|
||||
public ClientContext( ClientCredential cred, string serverPrinc, ContextAttrib requestedAttribs )
|
||||
: base( cred )
|
||||
{
|
||||
@@ -22,6 +40,28 @@ namespace NSspi.Contexts
|
||||
this.requestedAttribs = requestedAttribs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs and continues the authentication cycle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is performed iteratively to start, continue, and end the authentication cycle with the
|
||||
/// server. Each stage works by acquiring a token from one side, presenting it to the other side
|
||||
/// which in turn may generate a new token.
|
||||
///
|
||||
/// The cycle typically starts and ends with the client. On the first invocation on the client,
|
||||
/// no server token exists, and null is provided in its place. The client returns its status, providing
|
||||
/// its output token for the server. The server accepts the clients token as input and provides a
|
||||
/// token as output to send back to the client. This cycle continues until the server and client
|
||||
/// both indicate, typically, a SecurityStatus of 'OK'.
|
||||
/// </remarks>
|
||||
/// <param name="serverToken">The most recently received token from the server, or null if beginning
|
||||
/// the authentication cycle.</param>
|
||||
/// <param name="outToken">The clients next authentication token in the authentication cycle.</param>
|
||||
/// <returns>A status message indicating the progression of the authentication cycle.
|
||||
/// A status of 'OK' indicates that the cycle is complete, from the client's perspective. If the outToken
|
||||
/// is not null, it must be sent to the server.
|
||||
/// A status of 'Continue' indicates that the output token should be sent to the server and
|
||||
/// a response should be anticipated.</returns>
|
||||
public SecurityStatus Init( byte[] serverToken, out byte[] outToken )
|
||||
{
|
||||
TimeStamp rawExpiry = new TimeStamp();
|
||||
|
||||
@@ -11,6 +11,9 @@ using NSspi.Contexts;
|
||||
|
||||
namespace NSspi.Contexts
|
||||
{
|
||||
/// <summary>
|
||||
/// Declares native methods calls for security context-related win32 functions.
|
||||
/// </summary>
|
||||
internal static class ContextNativeMethods
|
||||
{
|
||||
/*
|
||||
@@ -173,7 +176,15 @@ namespace NSspi.Contexts
|
||||
[DllImport( "Secur32.dll", EntryPoint = "RevertSecurityContext", CharSet = CharSet.Unicode )]
|
||||
internal static extern SecurityStatus RevertSecurityContext( ref RawSspiHandle contextHandle );
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Safely invokes the native EncryptMessage function, making sure that handle ref counting is
|
||||
/// performed in a proper CER.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="qualityOfProtection"></param>
|
||||
/// <param name="bufferAdapter"></param>
|
||||
/// <param name="sequenceNumber"></param>
|
||||
/// <returns></returns>
|
||||
internal static SecurityStatus SafeEncryptMessage(
|
||||
SafeContextHandle handle,
|
||||
int qualityOfProtection,
|
||||
@@ -216,6 +227,15 @@ namespace NSspi.Contexts
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Safely invokes the native DecryptMessage function, making sure that handle ref counting is
|
||||
/// performed in a proper CER.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="qualityOfProtection"></param>
|
||||
/// <param name="bufferAdapter"></param>
|
||||
/// <param name="sequenceNumber"></param>
|
||||
/// <returns></returns>
|
||||
internal static SecurityStatus SafeDecryptMessage(
|
||||
SafeContextHandle handle,
|
||||
int qualityOfProtection,
|
||||
@@ -258,6 +278,15 @@ namespace NSspi.Contexts
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Safely invokes the native MakeSignature function, making sure that handle ref counting is
|
||||
/// performed in a proper CER.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="qualityOfProtection"></param>
|
||||
/// <param name="adapter"></param>
|
||||
/// <param name="sequenceNumber"></param>
|
||||
/// <returns></returns>
|
||||
internal static SecurityStatus SafeMakeSignature(
|
||||
SafeContextHandle handle,
|
||||
int qualityOfProtection,
|
||||
@@ -300,6 +329,15 @@ namespace NSspi.Contexts
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Safely invokes the native VerifySignature function, making sure that handle ref counting is
|
||||
/// performed in a proper CER.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="qualityOfProtection"></param>
|
||||
/// <param name="adapter"></param>
|
||||
/// <param name="sequenceNumber"></param>
|
||||
/// <returns></returns>
|
||||
internal static SecurityStatus SafeVerifySignature(
|
||||
SafeContextHandle handle,
|
||||
int qualityOfProtection,
|
||||
|
||||
@@ -6,21 +6,27 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NSspi.Contexts
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents impersonation performed on a server on behalf of a client.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The handle controls the lifetime of impersonation, and will revert the impersonation
|
||||
/// if it is disposed, or if it is finalized ie by being leaked and garbage collected.
|
||||
///
|
||||
/// If the handle is accidentally leaked while operations are performed on behalf of the user,
|
||||
/// impersonation may be reverted at any arbitrary time, perhaps during those operations.
|
||||
/// This may lead to operations being performed in the security context of the server,
|
||||
/// potentially leading to security vulnerabilities.
|
||||
/// </remarks>
|
||||
public class ImpersonationHandle : IDisposable
|
||||
{
|
||||
// Notes:
|
||||
// Impersonate:
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa375497(v=vs.85).aspx
|
||||
//
|
||||
// Revert:
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379446(v=vs.85).aspx
|
||||
//
|
||||
// QuerySecurityPkgInfo (to learn if it supports impersonation):
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379359(v=vs.85).aspx
|
||||
|
||||
private bool disposed;
|
||||
private ServerContext server;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ImpersonationHandle. Does not perform impersonation.
|
||||
/// </summary>
|
||||
/// <param name="server">The server context that is performing impersonation.</param>
|
||||
internal ImpersonationHandle(ServerContext server)
|
||||
{
|
||||
this.server = server;
|
||||
@@ -32,6 +38,9 @@ namespace NSspi.Contexts
|
||||
Dispose( false );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the impersonation.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose( true );
|
||||
|
||||
@@ -7,7 +7,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NSspi.Contexts
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Captures an unmanaged security context handle.
|
||||
/// </summary>
|
||||
public class SafeContextHandle : SafeSspiHandle
|
||||
{
|
||||
public SafeContextHandle()
|
||||
|
||||
@@ -34,6 +34,28 @@ namespace NSspi.Contexts
|
||||
/// </remarks>
|
||||
public bool SupportsImpersonate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs and continues the authentication cycle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is performed iteratively to continue and end the authentication cycle with the
|
||||
/// client. Each stage works by acquiring a token from one side, presenting it to the other side
|
||||
/// which in turn may generate a new token.
|
||||
///
|
||||
/// The cycle typically starts and ends with the client. On the first invocation on the client,
|
||||
/// no server token exists, and null is provided in its place. The client returns its status, providing
|
||||
/// its output token for the server. The server accepts the clients token as input and provides a
|
||||
/// token as output to send back to the client. This cycle continues until the server and client
|
||||
/// both indicate, typically, a SecurityStatus of 'OK'.
|
||||
/// </remarks>
|
||||
/// <param name="clientToken">The most recently received token from the client.</param>
|
||||
/// <param name="nextToken">The servers next authentication token in the cycle, that must
|
||||
/// be sent to the client.</param>
|
||||
/// <returns>A status message indicating the progression of the authentication cycle.
|
||||
/// A status of 'OK' indicates that the cycle is complete, from the servers's perspective. If the nextToken
|
||||
/// is not null, it must be sent to the client.
|
||||
/// A status of 'Continue' indicates that the output token should be sent to the client and
|
||||
/// a response should be anticipated.</returns>
|
||||
public SecurityStatus AcceptToken( byte[] clientToken, out byte[] nextToken )
|
||||
{
|
||||
SecureBuffer clientBuffer;
|
||||
@@ -125,6 +147,19 @@ namespace NSspi.Contexts
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current thread's security context to impersonate the user of the client.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Requires that the security package provided with the server's credentials, as well as the
|
||||
/// client's credentials, support impersonation.
|
||||
///
|
||||
/// Currently, only one thread may initiate impersonation per security context. Impersonation may
|
||||
/// follow threads created by the initial impersonation thread, however.
|
||||
/// </remarks>
|
||||
/// <returns>A handle to capture the lifetime of the impersonation. Dispose the handle to revert
|
||||
/// impersonation. If the handle is leaked, the impersonation will automatically revert at a
|
||||
/// non-deterministic time when the handle is finalized by the Garbage Collector.</returns>
|
||||
public ImpersonationHandle ImpersonateClient()
|
||||
{
|
||||
ImpersonationHandle handle;
|
||||
@@ -192,6 +227,9 @@ namespace NSspi.Contexts
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the ImpersonationHandle when it is released, either by disposale or finalization.
|
||||
/// </summary>
|
||||
internal void RevertImpersonate()
|
||||
{
|
||||
bool gotRef = false;
|
||||
|
||||
Reference in New Issue
Block a user