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;
            }
        }
예제 #4
0
 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));
 }
예제 #5
0
        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));
        }
예제 #6
0
        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;
        }
예제 #8
0
 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));
 }
예제 #11
0
        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();
                }
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        // 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);
        }
예제 #15
0
        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;
 }
예제 #17
0
        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);
        }
예제 #18
0
 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);
 }
예제 #19
0
        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));
            }
        }
예제 #20
0
        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);
            }
        }
예제 #21
0
 public SecurityStatus AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
                                             SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
 {
     return(HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired));
 }
예제 #22
0
        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));
        }
예제 #23
0
 public SecurityStatus InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
                                                 string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
 {
     return(HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false));
 }
예제 #24
0
 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));
 }
예제 #25
0
 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));
 }
예제 #26
0
 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));
 }
예제 #27
0
        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);
 }
예제 #29
0
        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;
 }
예제 #31
0
        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;
        }
예제 #33
0
        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;
                    }
                }
예제 #35
0
        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);
        }
예제 #36
0
 public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) {
     return SafeDeleteContext.CompleteAuthToken(Library, ref refContext, inputBuffers);
 }
예제 #37
0
        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();
                        }
                    }
                }
            }
        }
예제 #38
0
 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);
 }
예제 #39
0
        // 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;
        }
예제 #41
0
 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));
 }