private SafeCredentialReference(SafeFreeCredentials target)
        {
            bool success = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                target.DangerousAddRef(ref success);
            }
            catch
            {
                if (success)
                {
                    target.DangerousRelease();
                    success = false;
                }
            }
            finally
            {
                if (success)
                {
                    this._Target = target;
                    base.SetHandle(new IntPtr(0));
                }
            }
        }
 private SafeCredentialReference(SafeFreeCredentials target)
 {
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         target.DangerousAddRef(ref success);
     }
     catch
     {
         if (success)
         {
             target.DangerousRelease();
             success = false;
         }
     }
     finally
     {
         if (success)
         {
             this._Target = target;
             base.SetHandle(new IntPtr(0));
         }
     }
 }
        protected override bool ReleaseHandle()
        {
            SafeFreeCredentials credentials = this._Target;

            if (credentials != null)
            {
                credentials.DangerousRelease();
            }
            this._Target = null;
            return(true);
        }
        //
        // After PINvoke call the method will fix the handleTemplate.handle with the returned value.
        // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned.
        //
        // Since it has a CER, this method can't have any references to imports from DLLs that may not exist on the system.
        //
        private static unsafe int MustRunAcceptSecurityContext_SECURITY(
                                                  ref SafeFreeCredentials     inCredentials,
                                                  void*            inContextPtr,
                                                  SecurityBufferDescriptor inputBuffer,
                                                  ContextFlags     inFlags,
                                                  Endianness       endianness,
                                                  SafeDeleteContext outContext,
                                                  SecurityBufferDescriptor outputBuffer,
                                                  ref ContextFlags outFlags,
                                                  SafeFreeContextBuffer handleTemplate)
        {
            int errorCode = (int) SecurityStatus.InvalidHandle;
            bool b1 = false;
            bool b2 = false;

            // Run the body of this method as a non-interruptible block.
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                inCredentials.DangerousAddRef(ref b1);
                outContext.DangerousAddRef(ref b2);
            }
            catch(Exception e)
            {
                if (b1)
                {
                    inCredentials.DangerousRelease();
                    b1 = false;
                }
                if (b2)
                {
                    outContext.DangerousRelease();
                    b2 = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally {
                SSPIHandle credentialHandle = inCredentials._handle;
                long timeStamp;

                if (!b1)
                {
                    // caller should retry
                    inCredentials = null;
                }
                else if (b1 && b2)
                {
                    errorCode = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.AcceptSecurityContext(
                                ref credentialHandle,
                                inContextPtr,
                                inputBuffer,
                                inFlags,
                                endianness,
                                ref outContext._handle,
                                outputBuffer,
                                ref outFlags,
                                out timeStamp);

                    //
                    // When a credential handle is first associated with the context we keep credential
                    // ref count bumped up to ensure ordered finalization.
                    // If the credential handle has been changed we de-ref the old one and associate the
                    //  context with the new cred handle but only if the call was successful.
                    if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
                    {
                        // Disassociate the previous credential handle
                        if (outContext._EffectiveCredential != null)
                            outContext._EffectiveCredential.DangerousRelease();
                        outContext._EffectiveCredential = inCredentials;
                    }
                    else
                    {
                        inCredentials.DangerousRelease();
                    }

                    outContext.DangerousRelease();

                    // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
                    if (handleTemplate != null)
                    {
                        handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
                        if (handleTemplate.IsInvalid)
                        {
                            handleTemplate.SetHandleAsInvalid();
                        }
                    }
                }

                if (inContextPtr == null && (errorCode & 0x80000000) != 0)
                {
                    // an error on the first call, need to set the out handle to invalid value
                    outContext._handle.SetToInvalid();
                }
            }

            return errorCode;
        }
 private SafeCredentialReference(SafeFreeCredentials target): base()
 {
     // Bumps up the refcount on Target to signify that target handle is statically cached so
     // its dispose should be postponed
     bool b = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         target.DangerousAddRef(ref b);
     }
     catch
     {
         if (b)
         {
             target.DangerousRelease();
             b = false;
         }
     }
     finally
     {
         if (b)
         {
             _Target = target;
             SetHandle(new IntPtr(0));   // make this handle valid
         }
     }
 }
示例#6
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();
                }
            }
        }