/// <summary> /// Set the AuthState to authorized and update the connection state lifetime /// </summary> /// <param name="data"></param> internal static void AuthenticatedResponse(InternalDataStore data) { if (data.TryGetValueAs(authStateKey, out State? state)) { state !.AuthState = State.WinAuthState.AUTHORIZED; state.UpdatePresence(); } }
/// <summary> /// Validates that the current WinAuth state of the connection matches the /// expectation, used to detect failed authentication /// </summary> /// <param name="data"></param> /// <param name="expectedAuthState"></param> /// <returns></returns> internal static bool ValidateWinAuthState(InternalDataStore data, State.WinAuthState expectedAuthState) { bool stateExists = data.TryGetValueAs(authStateKey, out State? state); if (expectedAuthState == State.WinAuthState.UNAUTHORIZED) { return(!stateExists || state !.AuthState == State.WinAuthState.UNAUTHORIZED || state.AuthState == State.WinAuthState.AUTHORIZED); // Server may require re-authentication on an open connection } if (expectedAuthState == State.WinAuthState.INITIAL_TOKEN) { return(stateExists && (state !.AuthState == State.WinAuthState.INITIAL_TOKEN || state.AuthState == State.WinAuthState.AUTHORIZED)); // Server may require re-authentication on an open connection } throw new Exception("Unsupported validation of WinAuthState"); }
/// <summary> /// Acquire the final token to send /// </summary> /// <param name="hostname"></param> /// <param name="serverChallenge"></param> /// <param name="data"></param> /// <returns></returns> internal static byte[]? AcquireFinalSecurityToken(string hostname, byte[] serverChallenge, InternalDataStore data) { byte[]? token; // user server challenge var serverToken = new SecurityBufferDesciption(serverChallenge); var clientToken = new SecurityBufferDesciption(MaximumTokenSize); try { var state = data.GetAs <State>(authStateKey); state.UpdatePresence(); int result = InitializeSecurityContext(ref state.Credentials, ref state.Context, hostname, StandardContextAttributes, 0, SecurityNativeDataRepresentation, ref serverToken, 0, out state.Context, out clientToken, out NewContextAttributes, out NewLifeTime); if (result != SuccessfulResult) { return(null); } state.AuthState = State.WinAuthState.FINAL_TOKEN; token = clientToken.GetBytes(); } finally { clientToken.Dispose(); serverToken.Dispose(); } return(token); }
/// <summary> /// Acquire the intial client token to send /// </summary> /// <param name="hostname"></param> /// <param name="authScheme"></param> /// <param name="data"></param> /// <returns></returns> internal static byte[]? AcquireInitialSecurityToken(string hostname, string authScheme, InternalDataStore data) { byte[]? token; // null for initial call var serverToken = new SecurityBufferDesciption(); var clientToken = new SecurityBufferDesciption(MaximumTokenSize); try { var state = new State(); int result = AcquireCredentialsHandle( WindowsIdentity.GetCurrent().Name, authScheme, SecurityCredentialsOutbound, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref state.Credentials, ref NewLifeTime); if (result != SuccessfulResult) { return(null); } result = InitializeSecurityContext(ref state.Credentials, IntPtr.Zero, hostname, StandardContextAttributes, 0, SecurityNativeDataRepresentation, ref serverToken, 0, out state.Context, out clientToken, out NewContextAttributes, out NewLifeTime); if (result != IntermediateResult) { return(null); } state.AuthState = State.WinAuthState.INITIAL_TOKEN; token = clientToken.GetBytes(); data.Add(authStateKey, state); } finally { clientToken.Dispose(); serverToken.Dispose(); } return(token); }
/// <summary> /// Get the final token given the server challenge token /// </summary> /// <param name="serverHostname"></param> /// <param name="serverToken"></param> /// <param name="data"></param> /// <returns></returns> internal static string GetFinalAuthToken(string serverHostname, string serverToken, InternalDataStore data) { var tokenBytes = WinAuthEndPoint.AcquireFinalSecurityToken(serverHostname, Convert.FromBase64String(serverToken), data); return(string.Concat(" ", Convert.ToBase64String(tokenBytes))); }
/// <summary> /// Get the initial client token for server /// using credentials of user running the proxy server process /// </summary> /// <param name="serverHostname"></param> /// <param name="authScheme"></param> /// <param name="data"></param> /// <returns></returns> public static string GetInitialAuthToken(string serverHostname, string authScheme, InternalDataStore data) { var tokenBytes = WinAuthEndPoint.AcquireInitialSecurityToken(serverHostname, authScheme, data); return(string.Concat(" ", Convert.ToBase64String(tokenBytes))); }