public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) { if (ComNetOS.IsWin9x) { throw new NotSupportedException(); } return SafeDeleteContext.CompleteAuthToken(Library, ref refContext, inputBuffers); }
internal static int AcceptSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, ContextFlags inFlags, Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlags outFlags) { if (Logging.On) { Logging.PrintInfo(Logging.Web, string.Concat(new object[] { "AcceptSecurityContext(credential = ", credential.ToString(), ", context = ", ValidationHelper.ToString(context), ", inFlags = ", inFlags, ")" })); } int num = SecModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, inFlags, datarep, outputBuffer, ref outFlags); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.GetString("net_log_sspi_security_context_input_buffer", new object[] { "AcceptSecurityContext", (inputBuffer == null) ? 0 : inputBuffer.size, outputBuffer.size, (SecurityStatus) num })); } return num; }
private static unsafe int EncryptDecryptHelper(OP op, SSPIInterface SecModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { SecurityBufferDescriptor inputOutput = new SecurityBufferDescriptor(input.Length); SecurityBufferStruct[] structArray = new SecurityBufferStruct[input.Length]; fixed (SecurityBufferStruct* structRef = structArray) { int num6; inputOutput.UnmanagedPointer = (void*) structRef; GCHandle[] handleArray = new GCHandle[input.Length]; byte[][] bufferArray = new byte[input.Length][]; try { int num2; for (int i = 0; i < input.Length; i++) { SecurityBuffer buffer = input[i]; structArray[i].count = buffer.size; structArray[i].type = buffer.type; if ((buffer.token == null) || (buffer.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.token, buffer.offset); bufferArray[i] = buffer.token; } } switch (op) { case OP.Encrypt: num2 = SecModule.EncryptMessage(context, inputOutput, sequenceNumber); break; case OP.Decrypt: num2 = SecModule.DecryptMessage(context, inputOutput, sequenceNumber); break; case OP.MakeSignature: num2 = SecModule.MakeSignature(context, inputOutput, sequenceNumber); break; case OP.VerifySignature: num2 = SecModule.VerifySignature(context, inputOutput, sequenceNumber); break; default: throw ExceptionHelper.MethodNotImplementedException; } for (int j = 0; j < input.Length; j++) { SecurityBuffer buffer2 = input[j]; buffer2.size = structArray[j].count; buffer2.type = structArray[j].type; if (buffer2.size == 0) { buffer2.offset = 0; buffer2.token = null; } else { int index = 0; while (index < input.Length) { if (bufferArray[index] != null) { byte* numPtr = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(bufferArray[index], 0); if ((((void*) structArray[j].token) >= numPtr) && ((((void*) structArray[j].token) + buffer2.size) <= (numPtr + bufferArray[index].Length))) { buffer2.offset = (int) ((long) ((((void*) structArray[j].token) - numPtr) / 1)); buffer2.token = bufferArray[index]; break; } } index++; } if (index >= input.Length) { buffer2.size = 0; buffer2.offset = 0; buffer2.token = null; } } } if ((num2 != 0) && Logging.On) { if (num2 == 0x90321) { Logging.PrintError(Logging.Web, SR.GetString("net_log_operation_returned_something", new object[] { op, "SEC_I_RENEGOTIATE" })); } else { Logging.PrintError(Logging.Web, SR.GetString("net_log_operation_failed_with_error", new object[] { op, string.Format(CultureInfo.CurrentCulture, "0X{0:X}", new object[] { num2 }) })); } } num6 = num2; } finally { for (int k = 0; k < handleArray.Length; k++) { if (handleArray[k].IsAllocated) { handleArray[k].Free(); } } } return num6; } }
public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { return(SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, inputBuffer, null, outputBuffer, ref outFlags)); }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { Interop.Secur32.ContextFlags unusedAttributes = default(Interop.Secur32.ContextFlags); int errorCode = SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, targetName, RequiredFlags | Interop.Secur32.ContextFlags.InitManualCredValidation, Interop.Secur32.Endianness.Native, inputBuffers, outputBuffer, ref unusedAttributes); return(GetSecurityStatusPalFromWin32Int(errorCode)); }
internal static int AcceptSecurityContext(ISSPIInterface secModule, SafeFreeCredentials?credential, ref SafeDeleteSslContext?context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Log.AcceptSecurityContext(credential, context, inFlags); } int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, ref outputBuffer, ref outFlags); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), inputBuffers.Count, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return(errorCode); }
//------------------------------------------------------------------- internal unsafe static int AcceptSecurityContext( SecurDll dll, ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, ContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref ContextFlags outFlags) { #if TRAVE GlobalLog.Enter("SafeDeleteContext::AcceptSecurityContex"); GlobalLog.Print(" DLL = " + dll); GlobalLog.Print(" credential = " + inCredentials.ToString()); GlobalLog.Print(" refContext = " + ValidationHelper.ToString(refContext)); GlobalLog.Print(" inFlags = " + inFlags); // GlobalLog.Print(" endianness = " + endianness); // GlobalLog.Print(" inSecBuffer = " + SecurityBuffer.ToString(inSecBuffer)); // if (inSecBuffers==null) { GlobalLog.Print(" inSecBuffers = (null)"); } else { GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); // for (int index=0; index<inSecBuffers.Length; index++) { GlobalLog.Print(" inSecBuffers[" + index + "] = " + SecurityBuffer.ToString(inSecBuffers[index])); } } // GlobalLog.Print(" newContext = {ref} inContext"); // GlobalLog.Print(" outSecBuffer = " + SecurityBuffer.ToString(outSecBuffer)); // GlobalLog.Print(" outFlags = {ref} " + outFlags); // GlobalLog.Print(" timestamp = null"); #endif GlobalLog.Assert(outSecBuffer != null, "SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); GlobalLog.Assert(inSecBuffer == null || inSecBuffers == null, "SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null"); if (inCredentials == null) { throw new ArgumentNullException("inCredentials"); } SecurityBufferDescriptor inSecurityBufferDescriptor = null; if (inSecBuffer!=null) { inSecurityBufferDescriptor = new SecurityBufferDescriptor(1); } else if (inSecBuffers!=null) { inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length); } SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1); // actually this is returned in outFlags bool isSspiAllocated = (inFlags & ContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; SSPIHandle contextHandle = new SSPIHandle(); if (refContext != null) contextHandle = refContext._handle; // these are pinned user byte arrays passed along with SecurityBuffers GCHandle[] pinnedInBytes = null; GCHandle pinnedOutBytes = new GCHandle(); // optional output buffer that may need to be freed SafeFreeContextBuffer outFreeContextBuffer = null; try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor==null ? 1:inSecurityBufferDescriptor.Count]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor!=null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffer!=null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer!=null) { // Copy the SecurityBuffer content into unmanaged place holder inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // use the unmanaged token if it's not null; otherwise use the managed buffer if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRAVE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); #endif } } } SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1]; fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; // Copy the SecurityBuffer content into unmanaged place holder outUnmanagedBuffer[0].count = outSecBuffer.size; outUnmanagedBuffer[0].type = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) outUnmanagedBuffer[0].token = IntPtr.Zero; else outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); if (isSspiAllocated) outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle(dll); switch (dll) { case SecurDll.SECURITY: if (refContext == null || refContext.IsInvalid) refContext = new SafeDeleteContext_SECURITY(); errorCode = MustRunAcceptSecurityContext_SECURITY( ref inCredentials, contextHandle.IsZero? null: &contextHandle, inSecurityBufferDescriptor, inFlags, endianness, refContext, outSecurityBufferDescriptor, ref outFlags, outFreeContextBuffer ); break; default: throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SecurDll"), "Dll"); } GlobalLog.Print("SafeDeleteContext:AcceptSecurityContext Marshalling OUT buffer"); // Get unmanaged buffer with index 0 as the only one passed into PInvoke outSecBuffer.size = outUnmanagedBuffer[0].count; outSecBuffer.type = outUnmanagedBuffer[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); } else { outSecBuffer.token = null; } } } } finally { if (pinnedInBytes!=null) { for (int index=0; index<pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) pinnedInBytes[index].Free(); } } if (pinnedOutBytes.IsAllocated) pinnedOutBytes.Free(); if (outFreeContextBuffer != null) outFreeContextBuffer.Close(); } GlobalLog.Leave("SafeDeleteContext::AcceptSecurityContex() unmanaged AcceptSecurityContex()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext)); return errorCode; }
public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) { throw new NotSupportedException(); }
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags) { return(SafeDeleteContext.InitializeSecurityContext(Library, ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags)); }
public int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, ContextFlags inFlags, Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags) { return(SafeDeleteContext.AcceptSecurityContext(Library, ref credential, ref context, inFlags, endianness, inputBuffer, null, outputBuffer, ref outFlags)); }
private SecurityStatus HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); bool gotCredReference = false; bool gotContextReference = false; try { credential.DangerousAddRef(ref gotCredReference); if ((null == context) || context.IsInvalid) { long options = GetOptions(credential.Protocols); IntPtr contextPtr = Interop.OpenSsl.AllocateSslContext( options, credential.CertHandle, credential.CertKeyHandle, isServer, remoteCertRequired); context = new SafeDeleteContext(contextPtr, credential); } context.DangerousAddRef(ref gotContextReference); IntPtr inputPtr = IntPtr.Zero, outputPtr = IntPtr.Zero; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(context.DangerousGetHandle(), inputPtr, 0, out outputPtr, out outputSize); } else { unsafe { fixed(byte *tokenPtr = inputBuffer.token) { inputPtr = new IntPtr(tokenPtr + inputBuffer.offset); done = Interop.OpenSsl.DoSslHandshake(context.DangerousGetHandle(), inputPtr, inputBuffer.size, out outputPtr, out outputSize); } } } outputBuffer.size = outputSize; outputBuffer.offset = 0; if (outputSize > 0) { outputBuffer.token = new byte[outputBuffer.size]; Marshal.Copy(outputPtr, outputBuffer.token, 0, outputBuffer.size); } else { outputBuffer.token = null; } if (outputPtr != IntPtr.Zero) { Marshal.FreeHGlobal(outputPtr); outputPtr = IntPtr.Zero; } return(done ? SecurityStatus.OK : SecurityStatus.ContinueNeeded); } catch (Exception ex) { Debug.Fail("Exception Caught. - " + ex); return(SecurityStatus.InternalError); } finally { if (gotContextReference) { context.DangerousRelease(); } if (gotCredReference) { credential.DangerousRelease(); } } }
internal int Decrypt(byte[] payload, int offset, int count, out int newOffset, uint expectedSeqNumber) { if (offset < 0 || offset > (payload == null ? 0 : payload.Length)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'offset' out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || count > (payload == null ? 0 : payload.Length - offset)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'count' out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); } if (IsNTLM) { return(DecryptNtlm(payload, offset, count, out newOffset, expectedSeqNumber)); } // // Kerberos and up // var securityBuffer = new SecurityBuffer[2]; securityBuffer[0] = new SecurityBuffer(payload, offset, count, SecurityBufferType.Stream); securityBuffer[1] = new SecurityBuffer(0, SecurityBufferType.Data); int errorCode; if (IsConfidentialityFlag) { errorCode = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPIAuth, _securityContext, securityBuffer, expectedSeqNumber); } else { errorCode = SSPIWrapper.VerifySignature(GlobalSSPI.SSPIAuth, _securityContext, securityBuffer, expectedSeqNumber); } if (errorCode != 0) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } throw new Win32Exception(errorCode); } if (securityBuffer[1].type != SecurityBufferType.Data) { throw new InternalException(); } newOffset = securityBuffer[1].offset; return(securityBuffer[1].size); }
internal int Encrypt(byte[] buffer, int offset, int count, ref byte[] output, uint sequenceNumber) { SecSizes sizes = Sizes; try { int maxCount = checked (Int32.MaxValue - 4 - sizes.BlockSize - sizes.SecurityTrailer); if (count > maxCount || count < 0) { throw new ArgumentOutOfRangeException("count", SR.Format(SR.net_io_out_range, maxCount)); } } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } throw; } int resultSize = count + sizes.SecurityTrailer + sizes.BlockSize; if (output == null || output.Length < resultSize + 4) { output = new byte[resultSize + 4]; } // Make a copy of user data for in-place encryption. Buffer.BlockCopy(buffer, offset, output, 4 + sizes.SecurityTrailer, count); // Prepare buffers TOKEN(signature), DATA and Padding. var securityBuffer = new SecurityBuffer[3]; securityBuffer[0] = new SecurityBuffer(output, 4, sizes.SecurityTrailer, SecurityBufferType.Token); securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer, count, SecurityBufferType.Data); securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer + count, sizes.BlockSize, SecurityBufferType.Padding); int errorCode; if (IsConfidentialityFlag) { errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, _securityContext, securityBuffer, sequenceNumber); } else { if (IsNTLM) { securityBuffer[1].type |= SecurityBufferType.ReadOnlyFlag; } errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, _securityContext, securityBuffer, 0); } if (errorCode != 0) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::Encrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } throw new Win32Exception(errorCode); } // Compacting the result. resultSize = securityBuffer[0].size; bool forceCopy = false; if (resultSize != sizes.SecurityTrailer) { forceCopy = true; Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size); } resultSize += securityBuffer[1].size; if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.SecurityTrailer))) { Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size); } resultSize += securityBuffer[2].size; unchecked { output[0] = (byte)((resultSize) & 0xFF); output[1] = (byte)(((resultSize) >> 8) & 0xFF); output[2] = (byte)(((resultSize) >> 16) & 0xFF); output[3] = (byte)(((resultSize) >> 24) & 0xFF); } return(resultSize + 4); }
// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Interop.SecurityStatus statusCode) { if (GlobalLog.IsEnabled) { GlobalLog.Enter("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes"); } var list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.Token)); } if (_channelBinding != null) { list.Add(new SecurityBuffer(_channelBinding)); } SecurityBuffer[] inSecurityBufferArray = null; if (list.Count > 0) { inSecurityBufferArray = list.ToArray(); } var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.Token); bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = (Interop.SecurityStatus)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, _credentialsHandle, ref _securityContext, _spn, _requestedContextFlags, Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } if (statusCode == Interop.SecurityStatus.CompleteNeeded) { var inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = (Interop.SecurityStatus)SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref _securityContext, inSecurityBuffers); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } outSecurityBuffer.token = null; } } else { // Server session. statusCode = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, _credentialsHandle, ref _securityContext, _requestedContextFlags, Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime && _credentialsHandle != null) { _credentialsHandle.Dispose(); } } if (((int)statusCode & unchecked ((int)0x80000000)) != 0) { CloseContext(); _isCompleted = true; if (throwOnError) { var exception = new Win32Exception((int)statusCode); if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception); } throw exception; } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value from SSPI will tell us correctly if the // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm // we also have to consider the case in which SSPI formed a new context, in this case we're done as well. if (statusCode == Interop.SecurityStatus.OK) { // Success. if (statusCode != Interop.SecurityStatus.OK) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", LoggingHash.HashString(this), (int)statusCode, statusCode, LoggingHash.HashString(_securityContext), LoggingHash.ObjectToString(_securityContext)); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob()|statusCode:[0x" + ((int)statusCode).ToString("x8") + "] (" + statusCode + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:[" + LoggingHash.ObjectToString(_securityContext) + "] [STATUS != OK]"); } _isCompleted = true; } else if (GlobalLog.IsEnabled) { // We need to continue. GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:" + LoggingHash.ObjectToString(_securityContext) + "]"); } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString()); } return(outSecurityBuffer.token); }
internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.InitializeSecurityContext(credential.ToString(), LoggingHash.ObjectToString(context), targetName, inFlags); } int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags); if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.SecurityContextInputBuffer("InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode); } return(errorCode); }
internal static unsafe int CompleteAuthToken(SecurDll dll, ref SafeDeleteContext refContext, SecurityBuffer[] inSecBuffers) { SecurityBufferStruct[] structArray2; SecurityBufferDescriptor inputBuffers = new SecurityBufferDescriptor(inSecBuffers.Length); int num = -2146893055; GCHandle[] handleArray = null; SecurityBufferStruct[] structArray = new SecurityBufferStruct[inputBuffers.Count]; if (((structArray2 = structArray) != null) && (structArray2.Length != 0)) { goto Label_002F; } fixed (IntPtr* ptrRef = null) { goto Label_0039; Label_002F: ptrRef = structArray2; Label_0039: inputBuffers.UnmanagedPointer = (void*) ptrRef; handleArray = new GCHandle[inputBuffers.Count]; for (int i = 0; i < inputBuffers.Count; i++) { SecurityBuffer buffer = inSecBuffers[i]; if (buffer != null) { structArray[i].count = buffer.size; structArray[i].type = buffer.type; if (buffer.unmanagedToken != null) { structArray[i].token = buffer.unmanagedToken.DangerousGetHandle(); } else if ((buffer.token == null) || (buffer.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.token, buffer.offset); } } } SSPIHandle handle = new SSPIHandle(); if (refContext != null) { handle = refContext._handle; } try { if (dll == SecurDll.SECURITY) { if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { try { refContext.DangerousAddRef(ref success); } catch (Exception exception) { if (success) { refContext.DangerousRelease(); success = false; } if (!(exception is ObjectDisposedException)) { throw; } } goto Label_0201; } finally { if (success) { num = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.CompleteAuthToken(handle.IsZero ? null : ((void*) &handle), inputBuffers); refContext.DangerousRelease(); } } } throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SecurDll" }), "Dll"); } finally { if (handleArray != null) { for (int j = 0; j < handleArray.Length; j++) { if (handleArray[j].IsAllocated) { handleArray[j].Free(); } } } } } Label_0201:; return num; }
internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.AcceptSecurityContext(credential.ToString(), LoggingHash.ObjectToString(context), inFlags); } int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags); if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.SecurityContextInputBuffers("AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode); } return(errorCode); }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, ContextFlags inFlags, Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags) { return SafeDeleteContext.AcceptSecurityContext(Library, ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, isServer, remoteCertRequired); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return(new SecurityStatusPal(done ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded)); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteContext(credential, isServer, remoteCertRequired); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return(done ? SecurityStatusPal.OK : SecurityStatusPal.ContinueNeeded); } catch { // TODO: This Debug.Fail is triggering on Linux in many test cases #4317 // Debug.Fail("Exception Caught. - " + ex); return(SecurityStatusPal.InternalError); } }
public SecurityStatus AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { return(HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired)); }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { Interop.Secur32.ContextFlags unusedAttributes = default(Interop.Secur32.ContextFlags); int errorCode = SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPISecureChannel, ref credentialsHandle, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.Secur32.ContextFlags.MutualAuth : Interop.Secur32.ContextFlags.Zero), Interop.Secur32.Endianness.Native, inputBuffer, outputBuffer, ref unusedAttributes); return(GetSecurityStatusPalFromWin32Int(errorCode)); }
public SecurityStatus InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { return(HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false)); }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { return(SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags)); }
public SecurityStatus InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { Debug.Assert(inputBuffers.Length == 2); Debug.Assert(inputBuffers[1].token == null); return(HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, false, false)); }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return(SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags)); }
internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName + ", " + "inFlags = " + inFlags + ")"); } int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffer, "InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode)); } return(errorCode); }
public static int VerifySignature(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { return EncryptDecryptHelper(OP.VerifySignature, secModule, context, input, sequenceNumber); }
internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "AcceptSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "inFlags = " + inFlags + ")"); } int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffers, "AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode)); } return(errorCode); }
internal static int CompleteAuthToken(SSPIInterface SecModule, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers) { int num = SecModule.CompleteAuthToken(ref context, inputBuffers); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.GetString("net_log_operation_returned_something", new object[] { "CompleteAuthToken()", (SecurityStatus) num })); } return num; }
private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { Interop.Secur32.SecurityBufferDescriptor sdcInOut = new Interop.Secur32.SecurityBufferDescriptor(input.Length); var unmanagedBuffer = new Interop.Secur32.SecurityBufferStruct[input.Length]; fixed(Interop.Secur32.SecurityBufferStruct *unmanagedBufferPtr = unmanagedBuffer) { sdcInOut.UnmanagedPointer = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; byte[][] buffers = new byte[input.Length][]; try { for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; unmanagedBuffer[i].count = iBuffer.size; unmanagedBuffer[i].type = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { unmanagedBuffer[i].token = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } // The result is written in the input Buffer passed as type=BufferType.Data. int errorCode; switch (op) { case OP.Encrypt: errorCode = secModule.EncryptMessage(context, sdcInOut, sequenceNumber); break; case OP.Decrypt: errorCode = secModule.DecryptMessage(context, sdcInOut, sequenceNumber); break; case OP.MakeSignature: errorCode = secModule.MakeSignature(context, sdcInOut, sequenceNumber); break; case OP.VerifySignature: errorCode = secModule.VerifySignature(context, sdcInOut, sequenceNumber); break; default: GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Unknown OP: " + op); throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } // Marshalling back returned sizes / data. for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; iBuffer.size = unmanagedBuffer[i].count; iBuffer.type = unmanagedBuffer[i].type; if (iBuffer.size == 0) { iBuffer.offset = 0; iBuffer.token = null; } else { checked { // Find the buffer this is inside of. Usually they all point inside buffer 0. int j; for (j = 0; j < input.Length; j++) { if (buffers[j] == null) { continue; } byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); if ((byte *)unmanagedBuffer[i].token >= bufferAddress && (byte *)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) { iBuffer.offset = (int)((byte *)unmanagedBuffer[i].token - bufferAddress); iBuffer.token = buffers[j]; break; } } if (j >= input.Length) { GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range."); iBuffer.size = 0; iBuffer.offset = 0; iBuffer.token = null; } } } // Backup validate the new sizes. GlobalLog.Assert(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length), "SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [{0}]", iBuffer.offset); GlobalLog.Assert(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset), "SSPIWrapper::EncryptDecryptHelper|'size' out of range. [{0}]", iBuffer.size); } if (errorCode != 0 && Logging.On) { if (errorCode == Interop.Secur32.SEC_I_RENEGOTIATE) { Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_returned_something, op, "SEC_I_RENEGOTIATE")); } else { Logging.PrintError(Logging.Web, SR.Format(SR.net_log_operation_failed_with_error, op, String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode))); } } return(errorCode); } finally { for (int i = 0; i < pinnedBuffers.Length; ++i) { if (pinnedBuffers[i].IsAllocated) { pinnedBuffers[i].Free(); } } } } }
internal static unsafe int AcceptSecurityContext(SecurDll dll, ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, ContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref ContextFlags outFlags) { if (inCredentials == null) { throw new ArgumentNullException("inCredentials"); } SecurityBufferDescriptor inputBuffer = null; if (inSecBuffer != null) { inputBuffer = new SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length); } SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1); bool flag = (inFlags & ContextFlags.AllocateMemory) != ContextFlags.Zero; int num = -1; SSPIHandle handle = new SSPIHandle(); if (refContext != null) { handle = refContext._handle; } GCHandle[] handleArray = null; GCHandle handle2 = new GCHandle(); SafeFreeContextBuffer handleTemplate = null; try { handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count]; try { SecurityBufferStruct[] structArray3; if (((structArray3 = structArray) == null) || (structArray3.Length == 0)) { ptrRef = null; goto Label_00A5; } fixed (IntPtr* ptrRef = structArray3) { Label_00A5: if (inputBuffer != null) { inputBuffer.UnmanagedPointer = (void*) ptrRef; handleArray = new GCHandle[inputBuffer.Count]; for (int i = 0; i < inputBuffer.Count; i++) { SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i]; if (buffer2 != null) { structArray[i].count = buffer2.size; structArray[i].type = buffer2.type; if (buffer2.unmanagedToken != null) { structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle(); } else if ((buffer2.token == null) || (buffer2.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset); } } } } SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1]; try { SecurityBufferStruct[] structArray4; if (((structArray4 = structArray2) == null) || (structArray4.Length == 0)) { ptrRef2 = null; goto Label_01CB; } fixed (IntPtr* ptrRef2 = structArray4) { Label_01CB: outputBuffer.UnmanagedPointer = (void*) ptrRef2; structArray2[0].count = outSecBuffer.size; structArray2[0].type = outSecBuffer.type; if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0)) { structArray2[0].token = IntPtr.Zero; } else { structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (flag) { handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle(dll); } switch (dll) { case SecurDll.SECURITY: if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } num = MustRunAcceptSecurityContext_SECURITY(ref inCredentials, handle.IsZero ? null : ((void*) &handle), inputBuffer, inFlags, endianness, refContext, outputBuffer, ref outFlags, handleTemplate); break; case SecurDll.SECUR32: if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECUR32(); } num = MustRunAcceptSecurityContext_SECUR32(ref inCredentials, handle.IsZero ? null : ((void*) &handle), inputBuffer, inFlags, endianness, refContext, outputBuffer, ref outFlags, handleTemplate); break; case SecurDll.SCHANNEL: if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SCHANNEL(); } num = MustRunAcceptSecurityContext_SCHANNEL(ref inCredentials, handle.IsZero ? null : ((void*) &handle), inputBuffer, inFlags, endianness, refContext, outputBuffer, ref outFlags, handleTemplate); break; default: throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SecurDll" }), "Dll"); } outSecBuffer.size = structArray2[0].count; outSecBuffer.type = structArray2[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size); return num; } outSecBuffer.token = null; return num; } } finally { ptrRef2 = null; } return num; } } finally { ptrRef = null; } } finally { if (handleArray != null) { for (int j = 0; j < handleArray.Length; j++) { if (handleArray[j].IsAllocated) { handleArray[j].Free(); } } } if (handle2.IsAllocated) { handle2.Free(); } if (handleTemplate != null) { handleTemplate.Close(); } } return num; }
internal static int InitializeSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (NetEventSource.IsEnabled) { NetEventSource.Log.InitializeSecurityContext(credential, context, targetName, inFlags); } int errorCode = secModule.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffers, outputBuffer, ref outFlags); if (NetEventSource.IsEnabled) { NetEventSource.Log.SecurityContextInputBuffers(nameof(InitializeSecurityContext), inputBuffers?.Length ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return(errorCode); }
internal static unsafe int InitializeSecurityContext(SecurDll dll, ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref ContextFlags outFlags) { if (inCredentials == null) { throw new ArgumentNullException("inCredentials"); } SecurityBufferDescriptor inputBuffer = null; if (inSecBuffer != null) { inputBuffer = new SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length); } SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1); bool flag = (inFlags & ContextFlags.AllocateMemory) != ContextFlags.Zero; int num = -1; SSPIHandle handle = new SSPIHandle(); if (refContext != null) { handle = refContext._handle; } GCHandle[] handleArray = null; GCHandle handle2 = new GCHandle(); SafeFreeContextBuffer handleTemplate = null; try { handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count]; try { SecurityBufferStruct[] structArray3; if (((structArray3 = structArray) == null) || (structArray3.Length == 0)) { ptrRef = null; goto Label_00A6; } fixed (IntPtr* ptrRef = structArray3) { Label_00A6: if (inputBuffer != null) { inputBuffer.UnmanagedPointer = (void*) ptrRef; handleArray = new GCHandle[inputBuffer.Count]; for (int i = 0; i < inputBuffer.Count; i++) { SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i]; if (buffer2 != null) { structArray[i].count = buffer2.size; structArray[i].type = buffer2.type; if (buffer2.unmanagedToken != null) { structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle(); } else if ((buffer2.token == null) || (buffer2.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset); } } } } SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1]; try { SecurityBufferStruct[] structArray4; if (((structArray4 = structArray2) == null) || (structArray4.Length == 0)) { ptrRef2 = null; goto Label_01CC; } fixed (IntPtr* ptrRef2 = structArray4) { ref byte pinned numRef; ref byte pinned numRef2; Label_01CC: outputBuffer.UnmanagedPointer = (void*) ptrRef2; structArray2[0].count = outSecBuffer.size; structArray2[0].type = outSecBuffer.type; if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0)) { structArray2[0].token = IntPtr.Zero; } else { structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (flag) { handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle(dll); } switch (dll) { case SecurDll.SECURITY: if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } if ((targetName == null) || (targetName.Length == 0)) { targetName = " "; } fixed (char* str = ((char*) targetName)) { char* chPtr = str; num = MustRunInitializeSecurityContext_SECURITY(ref inCredentials, handle.IsZero ? null : ((void*) &handle), (targetName == " ") ? null : ((byte*) chPtr), inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate); goto Label_044B; } break; case SecurDll.SECUR32: break; case SecurDll.SCHANNEL: goto Label_0381; default: goto Label_0423; } if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECUR32(); } byte[] dummyBytes = SafeDeleteContext.dummyBytes; if ((targetName != null) && (targetName.Length != 0)) { dummyBytes = new byte[targetName.Length + 2]; Encoding.Default.GetBytes(targetName, 0, targetName.Length, dummyBytes, 0); } try { byte[] buffer5; if (((buffer5 = dummyBytes) == null) || (buffer5.Length == 0)) { numRef = null; } else { numRef = buffer5; } num = MustRunInitializeSecurityContext_SECUR32(ref inCredentials, handle.IsZero ? null : ((void*) &handle), (dummyBytes == SafeDeleteContext.dummyBytes) ? null : numRef, inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate); goto Label_044B; } finally { numRef = null; } Label_0381: if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext_SCHANNEL(); } byte[] bytes = SafeDeleteContext.dummyBytes; if ((targetName != null) && (targetName.Length != 0)) { bytes = new byte[targetName.Length + 2]; Encoding.Default.GetBytes(targetName, 0, targetName.Length, bytes, 0); } try { byte[] buffer6; if (((buffer6 = bytes) == null) || (buffer6.Length == 0)) { numRef2 = null; } else { numRef2 = buffer6; } num = MustRunInitializeSecurityContext_SCHANNEL(ref inCredentials, handle.IsZero ? null : ((void*) &handle), (bytes == SafeDeleteContext.dummyBytes) ? null : numRef2, inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate); goto Label_044B; } finally { numRef2 = null; } Label_0423:; throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SecurDll" }), "Dll"); Label_044B: outSecBuffer.size = structArray2[0].count; outSecBuffer.type = structArray2[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size); return num; } outSecBuffer.token = null; return num; } } finally { ptrRef2 = null; } return num; } }
internal static int AcceptSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (NetEventSource.IsEnabled) { NetEventSource.Log.AcceptSecurityContext(credential, context, inFlags); } int errorCode = secModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, inFlags, datarep, outputBuffer, ref outFlags); if (NetEventSource.IsEnabled) { NetEventSource.Log.SecurityContextInputBuffer(nameof(AcceptSecurityContext), inputBuffer?.size ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return(errorCode); }
public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) { return SafeDeleteContext.CompleteAuthToken(Library, ref refContext, inputBuffers); }
private static unsafe int EncryptDecryptHelper(OP op, SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(input.Length); var unmanagedBuffer = new Interop.SspiCli.SecBuffer[input.Length]; fixed(Interop.SspiCli.SecBuffer *unmanagedBufferPtr = unmanagedBuffer) { sdcInOut.pBuffers = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; byte[][] buffers = new byte[input.Length][]; try { for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; unmanagedBuffer[i].cbBuffer = iBuffer.size; unmanagedBuffer[i].BufferType = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { unmanagedBuffer[i].pvBuffer = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); unmanagedBuffer[i].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } // The result is written in the input Buffer passed as type=BufferType.Data. int errorCode; switch (op) { case OP.Encrypt: errorCode = secModule.EncryptMessage(context, ref sdcInOut, sequenceNumber); break; case OP.Decrypt: errorCode = secModule.DecryptMessage(context, ref sdcInOut, sequenceNumber); break; case OP.MakeSignature: errorCode = secModule.MakeSignature(context, ref sdcInOut, sequenceNumber); break; case OP.VerifySignature: errorCode = secModule.VerifySignature(context, ref sdcInOut, sequenceNumber); break; default: NetEventSource.Fail(null, $"Unknown OP: {op}"); throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } // Marshalling back returned sizes / data. for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; iBuffer.size = unmanagedBuffer[i].cbBuffer; iBuffer.type = unmanagedBuffer[i].BufferType; if (iBuffer.size == 0) { iBuffer.offset = 0; iBuffer.token = null; } else { checked { // Find the buffer this is inside of. Usually they all point inside buffer 0. int j; for (j = 0; j < input.Length; j++) { if (buffers[j] == null) { continue; } byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); if ((byte *)unmanagedBuffer[i].pvBuffer >= bufferAddress && (byte *)unmanagedBuffer[i].pvBuffer + iBuffer.size <= bufferAddress + buffers[j].Length) { iBuffer.offset = (int)((byte *)unmanagedBuffer[i].pvBuffer - bufferAddress); iBuffer.token = buffers[j]; break; } } if (j >= input.Length) { NetEventSource.Fail(null, "Output buffer out of range."); iBuffer.size = 0; iBuffer.offset = 0; iBuffer.token = null; } } } // Backup validate the new sizes. if (iBuffer.offset < 0 || iBuffer.offset > (iBuffer.token == null ? 0 : iBuffer.token.Length)) { NetEventSource.Fail(null, $"'offset' out of range. [{iBuffer.offset}]"); } if (iBuffer.size < 0 || iBuffer.size > (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset)) { NetEventSource.Fail(null, $"'size' out of range. [{iBuffer.size}]"); } } if (NetEventSource.IsEnabled && errorCode != 0) { if (errorCode == Interop.SspiCli.SEC_I_RENEGOTIATE) { NetEventSource.Error(null, SR.Format(SR.event_OperationReturnedSomething, op, "SEC_I_RENEGOTIATE")); } else { NetEventSource.Error(null, SR.Format(SR.net_log_operation_failed_with_error, op, $"0x{0:X}")); } } return(errorCode); } finally { for (int i = 0; i < pinnedBuffers.Length; ++i) { if (pinnedBuffers[i].IsAllocated) { pinnedBuffers[i].Free(); } } } } }
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags) { return SafeDeleteContext.InitializeSecurityContext(Library, ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { if (GlobalLog.IsEnabled) { GlobalLog.Enter("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes"); } var list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)); } if (_channelBinding != null) { list.Add(new SecurityBuffer(_channelBinding)); } SecurityBuffer[] inSecurityBufferArray = null; if (list.Count > 0) { inSecurityBufferArray = list.ToArray(); } var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.SECBUFFER_TOKEN); bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = NegotiateStreamPal.InitializeSecurityContext( _credentialsHandle, ref _securityContext, _spn, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { var inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, inSecurityBuffers); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } outSecurityBuffer.token = null; } } else { // Server session. statusCode = NegotiateStreamPal.AcceptSecurityContext( _credentialsHandle, ref _securityContext, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime && _credentialsHandle != null) { _credentialsHandle.Dispose(); } } if (NegoState.IsError(statusCode)) { CloseContext(); _isCompleted = true; if (throwOnError) { Exception exception = NegotiateStreamPal.CreateExceptionFromError(statusCode); if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception); } throw exception; } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value will tell us correctly if the handshake is over or not if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK) { // Success. _isCompleted = true; } else if (GlobalLog.IsEnabled) { // We need to continue. GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:" + LoggingHash.ObjectToString(_securityContext) + "]"); } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString()); } return(outSecurityBuffer.token); }
// // // internal unsafe static int CompleteAuthToken( SecurDll dll, ref SafeDeleteContext refContext, SecurityBuffer[] inSecBuffers) { GlobalLog.Enter("SafeDeleteContext::CompleteAuthToken"); GlobalLog.Print(" DLL = " + dll); GlobalLog.Print(" refContext = " + ValidationHelper.ToString(refContext)); #if TRAVE GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); // for (int index=0; index<inSecBuffers.Length; index++) { GlobalLog.Print(" inSecBuffers[" + index + "] = " + SecurityBuffer.ToString(inSecBuffers[index])); } #endif GlobalLog.Assert(inSecBuffers != null, "SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); SecurityBufferDescriptor inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length); int errorCode = (int)SecurityStatus.InvalidHandle; // these are pinned user byte arrays passed along with SecurityBuffers GCHandle[] pinnedInBytes = null; SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor.Count]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffers[index]; if (securityBuffer!=null) { inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // use the unmanaged token if it's not null; otherwise use the managed buffer if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token==null || securityBuffer.token.Length==0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRAVE GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); // securityBuffer.DebugDump(); #endif } } SSPIHandle contextHandle = new SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } try { if (dll==SecurDll.SECURITY) { if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext_SECURITY(); } bool b = false; RuntimeHelpers.PrepareConstrainedRegions(); try { refContext.DangerousAddRef(ref b); } catch(Exception e) { if (b) { refContext.DangerousRelease(); b = false; } if (!(e is ObjectDisposedException)) throw; } finally { if (b) { errorCode = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.CompleteAuthToken(contextHandle.IsZero? null: &contextHandle, inSecurityBufferDescriptor); refContext.DangerousRelease(); } } } else { throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SecurDll"), "Dll"); } } finally { if (pinnedInBytes!=null) { for (int index=0; index<pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } } } GlobalLog.Leave("SafeDeleteContext::CompleteAuthToken() unmanaged CompleteAuthToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext)); return errorCode; }
public int InitializeSecurityContext(ref SafeFreeCredentials?credential, ref SafeDeleteSslContext?context, string?targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return(SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags)); }