Exemple #1
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference?newRef = SafeCredentialReference.CreateReference(newHandle);
                if (newRef == null)
                {
                    return;
                }

                int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize;
#pragma warning disable CS8601 // Possible null reference assignment.
                newRef = Interlocked.Exchange <SafeCredentialReference>(ref s_cacheSlots[index], newRef);
#pragma warning restore CS8601 // Possible null reference assignment.

                newRef?.Dispose();
            }
            catch (Exception e)
            {
                if (NetEventSource.Log.IsEnabled() && !ExceptionCheck.IsFatal(e))
                {
                    NetEventSource.Error(null, $"Attempted to throw: {e}");
                }
            }
        }
Exemple #2
0
            // This method is implicitly reliable and called from a CER.
            protected override bool ReleaseHandle()
            {
                bool ret = false;

#if DEBUG
                try
                {
#endif
                GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")");

                SocketError errorCode = InnerReleaseHandle();
                return(ret = errorCode == SocketError.Success);

#if DEBUG
            }
            catch (Exception exception)
            {
                if (!ExceptionCheck.IsFatal(exception))
                {
                    GlobalLog.Assert("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")", exception.Message);
                }
                ret = true;      // Avoid a second assert.
                throw;
            }
            finally
            {
                _closeSocketThread = Environment.CurrentManagedThreadId;
                _closeSocketTick   = Environment.TickCount;
                GlobalLog.Assert(ret, "SafeCloseSocket::ReleaseHandle(handle:{0:x})|ReleaseHandle failed.", handle);
            }
#endif
            }
Exemple #3
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle);

                if (newRef == null)
                {
                    return;
                }

                unchecked
                {
                    int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize;
                    newRef = Interlocked.Exchange <SafeCredentialReference>(ref s_cacheSlots[index], newRef);
                }

                if (newRef != null)
                {
                    newRef.Dispose();
                }
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString());
                    }

                    Debug.Fail("SSPIHandlCache", "Attempted to throw: " + e.ToString());
                }
            }
        }
        /*++
         *  ProcessHandshakeSuccess -
         *     Called on successful completion of Handshake -
         *     used to set header/trailer sizes for encryption use
         *
         *  Fills in the information about established protocol
         * --*/
        internal void ProcessHandshakeSuccess()
        {
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::ProcessHandshakeSuccess");

            StreamSizes streamSizes;

            SslStreamPal.QueryContextStreamSizes(_securityContext, out streamSizes);

            if (streamSizes != null)
            {
                try
                {
                    _headerSize  = streamSizes.header;
                    _trailerSize = streamSizes.trailer;
                    _maxDataSize = checked (streamSizes.maximumMessage - (_headerSize + _trailerSize));
                }
                catch (Exception e)
                {
                    if (!ExceptionCheck.IsFatal(e))
                    {
                        GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::ProcessHandshakeSuccess", "StreamSizes out of range.");
                    }

                    throw;
                }
            }

            SslStreamPal.QueryContextConnectionInfo(_securityContext, out _connectionInfo);
            GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::ProcessHandshakeSuccess");
        }
        public JniNativeMethods(IntPtr env)
        {
            JniNativeInterface javaNativeInterface = **(JniNativeInterface **)env;

            // Class delegates
            findClass       = (FindClass)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.FindClass, typeof(FindClass));
            newGlobalRef    = (NewGlobalRef)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.NewGlobalRef, typeof(NewGlobalRef));
            deleteLocalRef  = (DeleteLocalRef)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.DeleteLocalRef, typeof(DeleteLocalRef));
            deleteGlobalRef = (DeleteGlobalRef)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.DeleteGlobalRef, typeof(DeleteGlobalRef));
            getObjectClass  = (GetObjectClass)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetObjectClass, typeof(GetObjectClass));
            newObject       = (NewObjectA)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.NewObjectA, typeof(NewObjectA));

            // String conversion delegates
            newStringUTF          = (NewStringUTF)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.NewStringUTF, typeof(NewStringUTF));
            getStringChars        = (GetStringChars)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetStringChars, typeof(GetStringChars));
            releaseStringChars    = (ReleaseStringChars)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ReleaseStringChars, typeof(ReleaseStringChars));
            getStringUTFChars     = (GetStringUTFChars)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetStringUTFChars, typeof(GetStringUTFChars));
            releaseStringUTFChars = (ReleaseStringUTFChars)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ReleaseStringUTFChars, typeof(ReleaseStringUTFChars));
            getStringUTFLength    = (GetStringUTFLength)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetStringUTFLength, typeof(GetStringUTFLength));

            // Method delegates
            registerNatives      = (RegisterNatives)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.RegisterNatives, typeof(RegisterNatives));
            getStaticMethodId    = (GetStaticMethodId)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetStaticMethodID, typeof(GetStaticMethodId));
            getMethodID          = (GetMethodID)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.GetMethodID, typeof(GetMethodID));
            callStaticVoidMethod = (CallStaticVoidMethod)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.CallStaticVoidMethod, typeof(CallStaticVoidMethod));
            callVoidMethod       = (CallVoidMethodA)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.CallVoidMethodA, typeof(CallVoidMethodA));

            // Exception delegates
            exceptionCheck    = (ExceptionCheck)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ExceptionCheck, typeof(ExceptionCheck));
            exceptionOccurred = (ExceptionOccurred)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ExceptionOccurred, typeof(ExceptionOccurred));
            exceptionClear    = (ExceptionClear)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ExceptionClear, typeof(ExceptionClear));
            exceptionDescribe = (ExceptionDescribe)Marshal.GetDelegateForFunctionPointer(javaNativeInterface.ExceptionDescribe, typeof(ExceptionDescribe));
        }
Exemple #6
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle);

                if (newRef == null)
                {
                    return;
                }

                unchecked
                {
                    int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize;
                    newRef = Interlocked.Exchange <SafeCredentialReference>(ref s_cacheSlots[index], newRef);
                }

                newRef?.Dispose();
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Fail(null, $"Attempted to throw: {e}");
                    }
                }
            }
        }
Exemple #7
0
        public void AddVob(T vob)
        {
            ExceptionCheck.ArgumentNull(vob);

            if (indices.ContainsKey(vob))
            {
                return;
            }

            // Despawn old vob
            T otherVob = vobs[currentIndex];

            if (otherVob != null)
            {
                indices.Remove(otherVob);
                otherVob.OnDespawn -= RemoveVobHandler;
                if (otherVob.IsSpawned)
                {
                    otherVob.Despawn();
                }
            }

            // add new vob
            vobs[currentIndex] = vob;
            indices.Add(vob, currentIndex);
            vob.OnDespawn += RemoveVobHandler;

            // change current index
            if (++currentIndex >= Capacity)
            {
                currentIndex = 0;
            }
        }
        /*++
         *  Encrypt - Encrypts our bytes before we send them over the wire
         *
         *  PERF: make more efficient, this does an extra copy when the offset
         *  is non-zero.
         *
         *  Input:
         *      buffer - bytes for sending
         *      offset -
         *      size   -
         *      output - Encrypted bytes
         * --*/
        internal SecurityStatusPal Encrypt(byte[] buffer, int offset, int size, ref byte[] output, out int resultSize)
        {
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::Encrypt");
            GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::Encrypt() - offset: " + offset.ToString() + " size: " + size.ToString() + " buffersize: " + buffer.Length.ToString());
            GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::Encrypt() buffer:");
            GlobalLog.Dump(buffer, Math.Min(buffer.Length, 128));

            byte[] writeBuffer;
            try
            {
                if (offset < 0 || offset > (buffer == null ? 0 : buffer.Length))
                {
                    throw new ArgumentOutOfRangeException("offset");
                }

                if (size < 0 || size > (buffer == null ? 0 : buffer.Length - offset))
                {
                    throw new ArgumentOutOfRangeException("size");
                }

                resultSize = 0;

                int bufferSizeNeeded = checked (size + _headerSize + _trailerSize);
                if (output != null && bufferSizeNeeded <= output.Length)
                {
                    writeBuffer = output;
                }
                else
                {
                    writeBuffer = new byte[bufferSizeNeeded];
                }

                Buffer.BlockCopy(buffer, offset, writeBuffer, _headerSize, size);
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::Encrypt", "Arguments out of range.");
                }

                throw;
            }

            SecurityStatusPal secStatus = SslStreamPal.EncryptMessage(_securityContext, writeBuffer, size, _headerSize, _trailerSize, out resultSize);

            if (secStatus != SecurityStatusPal.OK)
            {
                GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::Encrypt ERROR", secStatus.ToString());
            }
            else
            {
                output = writeBuffer;
                GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::Encrypt OK", "data size:" + resultSize.ToString());
            }

            return(secStatus);
        }
        public static SecurityStatusPal EncryptMessage(SafeDeleteContext securityContext, byte[] input, int offset, int size, int headerSize, int trailerSize, ref byte[] output, out int resultSize)
        {
            // Ensure that there is sufficient space for the message output.
            try
            {
                int bufferSizeNeeded = checked (size + headerSize + trailerSize);

                if (output == null || output.Length < bufferSizeNeeded)
                {
                    output = new byte[bufferSizeNeeded];
                }
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("SslStreamPal.Windows: SecureChannel#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range.");
                    }

                    Debug.Fail("SslStreamPal.Windows: SecureChannel#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range.");
                }

                throw;
            }

            byte[] writeBuffer = output;

            // Copy the input into the output buffer to prepare for SCHANNEL's expectations
            Buffer.BlockCopy(input, offset, writeBuffer, headerSize, size);

            // Encryption using SCHANNEL requires 4 buffers: header, payload, trailer, empty.
            SecurityBuffer[] securityBuffer = new SecurityBuffer[4];

            securityBuffer[0] = new SecurityBuffer(writeBuffer, 0, headerSize, SecurityBufferType.SECBUFFER_STREAM_HEADER);
            securityBuffer[1] = new SecurityBuffer(writeBuffer, headerSize, size, SecurityBufferType.SECBUFFER_DATA);
            securityBuffer[2] = new SecurityBuffer(writeBuffer, headerSize + size, trailerSize, SecurityBufferType.SECBUFFER_STREAM_TRAILER);
            securityBuffer[3] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY);

            int errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPISecureChannel, securityContext, securityBuffer, 0);

            if (errorCode != 0)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("SslStreamPal.Windows: SecureChannel#" + LoggingHash.HashString(securityContext) + "::Encrypt ERROR" + errorCode.ToString("x"));
                }
                resultSize = 0;
            }
            else
            {
                // The full buffer may not be used.
                resultSize = securityBuffer[0].size + securityBuffer[1].size + securityBuffer[2].size;
            }

            return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode));
        }
Exemple #10
0
        // Binds the Socket Win32 Handle to the ThreadPool's CompletionPort.
        public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle(bool trySkipCompletionPortOnSuccess)
        {
            if (_released)
            {
                // Keep the exception message pointing at the external type.
                throw new ObjectDisposedException(typeof(Socket).FullName);
            }

            // Check to see if the socket native _handle is already
            // bound to the ThreadPool's completion port.
            if (_iocpBoundHandle == null)
            {
                lock (_iocpBindingLock)
                {
                    if (_iocpBoundHandle == null)
                    {
                        // Bind the socket native _handle to the ThreadPool.
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "calling ThreadPool.BindHandle()");
                        }

                        ThreadPoolBoundHandle boundHandle;
                        try
                        {
                            // The handle (this) may have been already released:
                            // E.g.: The socket has been disposed in the main thread. A completion callback may
                            //       attempt starting another operation.
                            boundHandle = ThreadPoolBoundHandle.BindHandle(this);
                        }
                        catch (Exception exception)
                        {
                            if (ExceptionCheck.IsFatal(exception))
                            {
                                throw;
                            }
                            CloseAsIs();
                            throw;
                        }

                        // Try to disable completions for synchronous success, if requested
                        if (trySkipCompletionPortOnSuccess &&
                            CompletionPortHelper.SkipCompletionPortOnSuccess(boundHandle.Handle))
                        {
                            _skipCompletionPortOnSuccess = true;
                        }

                        // Don't set this until after we've configured the handle above (if we did)
                        _iocpBoundHandle = boundHandle;
                    }
                }
            }

            return(_iocpBoundHandle);
        }
Exemple #11
0
        internal void CloseAsIs(bool abortive)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"_innerSocket={_innerSocket}");
            }

#if DEBUG
            // If this throws it could be very bad.
            try
            {
#endif
            InnerSafeCloseSocket innerSocket = _innerSocket == null ? null : Interlocked.Exchange <InnerSafeCloseSocket>(ref _innerSocket, null);

            Dispose();
            if (innerSocket != null)
            {
                bool canceledOperations = false;

                // Wait until it's safe.
                SpinWait sw = new SpinWait();
                while (!_released)
                {
                    // The socket was not released due to the SafeHandle being used.
                    // Try to make those on-going calls return.
                    // On Linux, TryUnblockSocket will unblock current operations but it doesn't prevent
                    // a new one from starting. So we must call TryUnblockSocket multiple times.
                    canceledOperations |= innerSocket.TryUnblockSocket(abortive, _hasShutdownSend);
                    sw.SpinOnce();
                }

                canceledOperations |= DoReleaseHandle();

                // In case we cancel operations, switch to an abortive close.
                // Unless the user requested a normal close using Socket.Shutdown.
                if (canceledOperations && !_hasShutdownSend)
                {
                    abortive = true;
                }

                innerSocket.Close(abortive);
            }
#if DEBUG
        }

        catch (Exception exception) when(!ExceptionCheck.IsFatal(exception))
        {
            NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
            throw;
        }
#endif
        }
Exemple #12
0
        public void RemoveVob(T vob)
        {
            ExceptionCheck.ArgumentNull(vob);

            if (!indices.TryGetValue(vob, out int index))
            {
                return;
            }

            vobs[index] = null;
            indices.Remove(vob);
            vob.OnDespawn -= RemoveVobHandler;
        }
Exemple #13
0
        private bool CloseHandle(bool abortive, bool canceledOperations)
        {
            bool ret = false;

#if DEBUG
            try
            {
#endif
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"handle:{handle}");
            }

            canceledOperations |= OnHandleClose();

            // In case we cancel operations, switch to an abortive close.
            // Unless the user requested a normal close using Socket.Shutdown.
            if (canceledOperations && !_hasShutdownSend)
            {
                abortive = true;
            }

            SocketError errorCode = DoCloseHandle(abortive);
            return(ret = errorCode == SocketError.Success);

#if DEBUG
        }

        catch (Exception exception)
        {
            if (!ExceptionCheck.IsFatal(exception))
            {
                NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
            }

            ret = true;      // Avoid a second assert.
            throw;
        }
        finally
        {
            _closeSocketThread = Environment.CurrentManagedThreadId;
            _closeSocketTick   = Environment.TickCount;
            if (!ret)
            {
                NetEventSource.Fail(this, $"ReleaseHandle failed. handle:{handle}");
            }
        }
#endif
        }
Exemple #14
0
        internal void CloseAsIs()
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print(
                    "SafeCloseSocket#" + LoggingHash.HashString(this) + "::CloseAsIs() m_InnerSocket=" +
                    _innerSocket == null ? "null" : LoggingHash.HashString(_innerSocket));
            }

#if DEBUG
            // If this throws it could be very bad.
            try
            {
#endif
            InnerSafeCloseSocket innerSocket = _innerSocket == null ? null : Interlocked.Exchange <InnerSafeCloseSocket>(ref _innerSocket, null);

            Dispose();
            if (innerSocket != null)
            {
                // Wait until it's safe.
                SpinWait sw = new SpinWait();
                while (!_released)
                {
                    sw.SpinOnce();
                }

                // Now free it with blocking.
                innerSocket.BlockingRelease();
            }

            InnerReleaseHandle();
#if DEBUG
        }

        catch (Exception exception)
        {
            if (!ExceptionCheck.IsFatal(exception))
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Assert("SafeCloseSocket::CloseAsIs(handle:" + handle.ToString("x") + ")", exception.Message);
                }
                Debug.Fail("SafeCloseSocket::CloseAsIs(handle:" + handle.ToString("x") + ")", exception.Message);
            }
            throw;
        }
#endif
        }
Exemple #15
0
        internal void CloseAsIs(bool abortive)
        {
#if DEBUG
            // If this throws it could be very bad.
            try
            {
#endif
            bool shouldClose = TryOwnClose();

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"shouldClose={shouldClose}");
            }

            Dispose();

            if (shouldClose)
            {
                bool canceledOperations = false;

                // Wait until it's safe.
                SpinWait sw = default;
                while (!_released)
                {
                    // The socket was not released due to the SafeHandle being used.
                    // Try to make those on-going calls return.
                    // On Linux, TryUnblockSocket will unblock current operations but it doesn't prevent
                    // a new one from starting. So we must call TryUnblockSocket multiple times.
                    canceledOperations |= TryUnblockSocket(abortive);
                    sw.SpinOnce();
                }

                CloseHandle(abortive, canceledOperations);
            }
#if DEBUG
        }

        catch (Exception exception) when(!ExceptionCheck.IsFatal(exception))
        {
            NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
            throw;
        }
#endif
        }
Exemple #16
0
        internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state)
        {
            bool canRead = CanRead; // Prevent race with Dispose.

            if (_cleanedUp)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            if (!canRead)
            {
                throw new InvalidOperationException(SR.net_writeonlystream);
            }

            Socket chkStreamSocket = _streamSocket;

            if (chkStreamSocket == null)
            {
                throw new IOException(SR.Format(SR.net_io_readfailure, SR.net_io_connectionclosed));
            }

            try
            {
                IAsyncResult asyncResult = chkStreamSocket.UnsafeBeginReceive(
                    buffer,
                    offset,
                    size,
                    SocketFlags.None,
                    callback,
                    state);

                return(asyncResult);
            }
            catch (Exception exception)
            {
                if (ExceptionCheck.IsFatal(exception))
                {
                    throw;
                }

                // Some sort of error occurred on the socket call,
                // set the SocketException as InnerException and throw.
                throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
            }
        }
Exemple #17
0
        // Binds the Socket Win32 Handle to the ThreadPool's CompletionPort.
        public ThreadPoolBoundHandle GetOrAllocateThreadPoolBoundHandle()
        {
            if (_released)
            {
                // Keep the exception message pointing at the external type.
                throw new ObjectDisposedException(typeof(Socket).FullName);
            }

            // Check to see if the socket native _handle is already
            // bound to the ThreadPool's completion port.
            if (_iocpBoundHandle == null)
            {
                lock (_iocpBindingLock)
                {
                    if (_iocpBoundHandle == null)
                    {
                        // Bind the socket native _handle to the ThreadPool.
                        if (GlobalLog.IsEnabled)
                        {
                            GlobalLog.Print("SafeCloseSocket#" + LoggingHash.HashString(this) + "::BindToCompletionPort() calling ThreadPool.BindHandle()");
                        }

                        try
                        {
                            // The handle (this) may have been already released:
                            // E.g.: The socket has been disposed in the main thread. A completion callback may
                            //       attempt starting another operation.
                            _iocpBoundHandle = ThreadPoolBoundHandle.BindHandle(this);
                        }
                        catch (Exception exception)
                        {
                            if (ExceptionCheck.IsFatal(exception))
                            {
                                throw;
                            }
                            CloseAsIs();
                            throw;
                        }
                    }
                }
            }

            return(_iocpBoundHandle);
        }
Exemple #18
0
        internal void CloseAsIs(bool abortive)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"_innerSocket={_innerSocket}");
            }

#if DEBUG
            // If this throws it could be very bad.
            try
            {
#endif
            InnerSafeCloseSocket innerSocket = _innerSocket == null ? null : Interlocked.Exchange <InnerSafeCloseSocket>(ref _innerSocket, null);

            Dispose();
            if (innerSocket != null)
            {
                // Wait until it's safe.
                SpinWait sw = new SpinWait();
                while (!_released)
                {
                    // The socket was not released due to the SafeHandle being used.
                    // Try to make those on-going calls return.
                    // On Linux, TryUnblockSocket will unblock current operations but it doesn't prevent
                    // a new one from starting. So we must call TryUnblockSocket multiple times.
                    abortive |= innerSocket.TryUnblockSocket();
                    sw.SpinOnce();
                }

                abortive |= InnerReleaseHandle();

                innerSocket.Close(abortive);
            }
#if DEBUG
        }

        catch (Exception exception) when(!ExceptionCheck.IsFatal(exception))
        {
            NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
            throw;
        }
#endif
        }
            // This method is implicitly reliable and called from a CER.
            protected override bool ReleaseHandle()
            {
                bool ret = false;

#if DEBUG
                try
                {
#endif
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"handle:{handle}");
                }

                SocketError errorCode = InnerReleaseHandle();
                return(ret = errorCode == SocketError.Success);

#if DEBUG
            }

            catch (Exception exception)
            {
                if (!ExceptionCheck.IsFatal(exception))
                {
                    NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
                }

                ret = true;      // Avoid a second assert.
                throw;
            }
            finally
            {
                _closeSocketThread = Environment.CurrentManagedThreadId;
                _closeSocketTick   = Environment.TickCount;
                if (!ret)
                {
                    NetEventSource.Fail(this, $"ReleaseHandle failed. handle:{handle}");
                }
            }
#endif
            }
Exemple #20
0
        internal void CloseAsIs()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"_innerSocket={_innerSocket}");
            }

#if DEBUG
            // If this throws it could be very bad.
            try
            {
#endif
            InnerSafeCloseSocket innerSocket = _innerSocket == null ? null : Interlocked.Exchange <InnerSafeCloseSocket>(ref _innerSocket, null);

            Dispose();
            if (innerSocket != null)
            {
                // Wait until it's safe.
                SpinWait sw = new SpinWait();
                while (!_released)
                {
                    sw.SpinOnce();
                }

                InnerReleaseHandle();

                // Now free it with blocking.
                innerSocket.BlockingRelease();
            }

#if DEBUG
        }

        catch (Exception exception) when(!ExceptionCheck.IsFatal(exception))
        {
            NetEventSource.Fail(this, $"handle:{handle}, error:{exception}");
            throw;
        }
#endif
        }
Exemple #21
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference?newRef = SafeCredentialReference.CreateReference(newHandle);
                if (newRef == null)
                {
                    return;
                }

                int index = Interlocked.Increment(ref s_current) & MaxCacheSize;

                Interlocked.Exchange(ref s_cacheSlots[index], newRef)?.Dispose();
            }
            catch (Exception e)
            {
                if (NetEventSource.Log.IsEnabled() && !ExceptionCheck.IsFatal(e))
                {
                    NetEventSource.Error(null, $"Attempted to throw: {e}");
                }
            }
        }
Exemple #22
0
        internal static int Encrypt(
            SafeDeleteContext securityContext,
            byte[] buffer,
            int offset,
            int count,
            bool isConfidential,
            bool isNtlm,
            ref byte[] output,
            uint sequenceNumber)
        {
            SecPkgContext_Sizes sizes = default;
            bool success = SSPIWrapper.QueryBlittableContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES, ref sizes);

            Debug.Assert(success);

            try
            {
                int maxCount = checked (int.MaxValue - 4 - sizes.cbBlockSize - sizes.cbSecurityTrailer);

                if (count > maxCount || count < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount));
                }
            }
            catch (Exception e) when(!ExceptionCheck.IsFatal(e))
            {
                NetEventSource.Fail(null, "Arguments out of range.");
                throw;
            }

            int resultSize = count + sizes.cbSecurityTrailer + sizes.cbBlockSize;

            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.cbSecurityTrailer, count);

            // Prepare buffers TOKEN(signature), DATA and Padding.
            ThreeSecurityBuffers buffers = default;
            var securityBuffer           = MemoryMarshal.CreateSpan(ref buffers._item0, 3);

            securityBuffer[0] = new SecurityBuffer(output, 4, sizes.cbSecurityTrailer, SecurityBufferType.SECBUFFER_TOKEN);
            securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, count, SecurityBufferType.SECBUFFER_DATA);
            securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + count, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING);

            int errorCode;

            if (isConfidential)
            {
                errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber);
            }
            else
            {
                if (isNtlm)
                {
                    securityBuffer[1].type |= SecurityBufferType.SECBUFFER_READONLY;
                }

                errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0);
            }

            if (errorCode != 0)
            {
                Exception e = new Win32Exception(errorCode);
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, e);
                }
                throw e;
            }

            // Compacting the result.
            resultSize = securityBuffer[0].size;
            bool forceCopy = false;

            if (resultSize != sizes.cbSecurityTrailer)
            {
                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.cbSecurityTrailer)))
            {
                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);
        }
        public static void Attach(int pid, string path, string arguments = "")
        {
            IntPtr vm = IntPtr.Zero, env = IntPtr.Zero;

            JavaVMInitArgs args = new JavaVMInitArgs();

            args.version  = 0x00010008;
            args.nOptions = 0;

            int result = JNI_CreateJavaVM(ref vm, ref env, ref args);

            Console.WriteLine("result " + result);


            IntPtr real      = Marshal.ReadIntPtr(env);
            IntPtr function  = Marshal.ReadIntPtr(real, 668);
            IntPtr functionL = Marshal.ReadIntPtr(real, 656);

            IntPtr realVmStruct = Marshal.ReadIntPtr(vm);


            StringDelegate  newStringUTF   = Marshal.GetDelegateForFunctionPointer <StringDelegate>(function);
            GetStringLength stringLen      = Marshal.GetDelegateForFunctionPointer <GetStringLength>(functionL);
            ExceptionCheck  checkException = Marshal.GetDelegateForFunctionPointer <ExceptionCheck>(Marshal.ReadIntPtr(real, 912));

            ExceptionDescribe printException = Marshal.GetDelegateForFunctionPointer <ExceptionDescribe>(Marshal.ReadIntPtr(real, 64));

            NewObjectArray newObjectArray = Marshal.GetDelegateForFunctionPointer <NewObjectArray>(Marshal.ReadIntPtr(real, 688));
            FindClass      findClass      = Marshal.GetDelegateForFunctionPointer <FindClass>(Marshal.ReadIntPtr(real, 24));

            SetArray setArray = Marshal.GetDelegateForFunctionPointer <SetArray>(Marshal.ReadIntPtr(real, 696));

            DestroyJavaVM destroyVM = Marshal.GetDelegateForFunctionPointer <DestroyJavaVM>(Marshal.ReadIntPtr(realVmStruct, 12));

            //attach api start

            Java_sun_tools_attach_WindowsVirtualMachine_init(env, IntPtr.Zero);
            IntPtr stub = Java_sun_tools_attach_WindowsVirtualMachine_generateStub(env, IntPtr.Zero);

            long process = Java_sun_tools_attach_WindowsVirtualMachine_openProcess(env, IntPtr.Zero, pid);

            Console.WriteLine("exception " + checkException(env));


            IntPtr cmd      = newStringUTF(env, "load");
            IntPtr pipeName = newStringUTF(env, "\\\\.\\pipe\\javatool22");

            IntPtr pathJStr       = newStringUTF(env, path);
            IntPtr unknownBoolean = newStringUTF(env, "true");
            IntPtr argumentsJ     = newStringUTF(env, arguments);

            Console.WriteLine("exception " + checkException(env));


            IntPtr clazz = findClass(env, "java/lang/String");

            IntPtr array = newObjectArray(env, 3, clazz, IntPtr.Zero);

            setArray(env, array, 0, pathJStr);
            setArray(env, array, 1, unknownBoolean);
            setArray(env, array, 2, argumentsJ);



            Java_sun_tools_attach_WindowsVirtualMachine_enqueue(env, IntPtr.Zero,
                                                                process, stub, cmd, pipeName, array);

            Console.WriteLine("exception " + checkException(env));
            printException(env);


            /*
             *
             * var pipe = new NamedPipeServerStream("javatool22");
             * pipe.WaitForConnection();
             * BinaryReader reader = new BinaryReader(pipe);
             * char callback = reader.ReadChar();
             *
             *
             * Console.WriteLine("pipe result " + callback);
             */

            Java_sun_tools_attach_WindowsVirtualMachine_closeProcess(env, IntPtr.Zero, process);


            int rr = destroyVM(vm);

            Console.WriteLine("destroyed vm: " + result);
        }
Exemple #24
0
        public void Connect(string hostname, int port)
        {
            ThrowIfDisposed();

            if (hostname == null)
            {
                throw new ArgumentNullException(nameof(hostname));
            }
            if (!TcpValidationHelpers.ValidatePortNumber(port))
            {
                throw new ArgumentOutOfRangeException(nameof(port));
            }

            // We must now look for addresses that use a compatible address family to the client socket. However, in the
            // case of the <hostname,port> constructor we will have deferred creating the socket and will do that here
            // instead.

            IPAddress[] addresses = Dns.GetHostAddresses(hostname);

            Exception lastex     = null;
            Socket    ipv6Socket = null;
            Socket    ipv4Socket = null;

            try
            {
                if (_clientSocket == null)
                {
                    if (Socket.OSSupportsIPv4)
                    {
                        ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    }
                    if (Socket.OSSupportsIPv6)
                    {
                        ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
                    }
                }


                foreach (IPAddress address in addresses)
                {
                    try
                    {
                        if (_clientSocket == null)
                        {
                            // We came via the <hostname,port> constructor. Set the
                            // address family appropriately, create the socket and
                            // try to connect.
                            if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null)
                            {
                                ipv4Socket.Connect(address, port);
                                _clientSocket = ipv4Socket;
                                if (ipv6Socket != null)
                                {
                                    ipv6Socket.Close();
                                }
                            }
                            else if (ipv6Socket != null)
                            {
                                ipv6Socket.Connect(address, port);
                                _clientSocket = ipv6Socket;
                                if (ipv4Socket != null)
                                {
                                    ipv4Socket.Close();
                                }
                            }


                            _family = address.AddressFamily;
                            _active = true;
                            break;
                        }
                        else if (IsAddressFamilyCompatible(address.AddressFamily))
                        {
                            // Only use addresses with a matching family
                            Connect(new IPEndPoint(address, port));
                            _active = true;
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ExceptionCheck.IsFatal(ex))
                        {
                            throw;
                        }
                        lastex = ex;
                    }
                }
            }

            catch (Exception ex)
            {
                if (ExceptionCheck.IsFatal(ex))
                {
                    throw;
                }
                lastex = ex;
            }
            finally
            {
                //cleanup temp sockets if failed
                //main socket gets closed when tcpclient gets closed

                //did we connect?
                if (!_active)
                {
                    if (ipv6Socket != null)
                    {
                        ipv6Socket.Close();
                    }

                    if (ipv4Socket != null)
                    {
                        ipv4Socket.Close();
                    }

                    // The connect failed - rethrow the last error we had
                    if (lastex != null)
                    {
                        throw lastex;
                    }
                    else
                    {
                        throw new SocketException((int)SocketError.NotConnected);
                    }
                }
            }
        }
Exemple #25
0
        // Establishes a connection to the specified port on the specified host.
        public void Connect(string hostname, int port)
        {
            // Validate input parameters.
            if (_cleanedUp)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (hostname == null)
            {
                throw new ArgumentNullException("hostname");
            }
            if (!TcpValidationHelpers.ValidatePortNumber(port))
            {
                throw new ArgumentOutOfRangeException("port");
            }

            // IPv6 Changes: instead of just using the first address in the list,
            //               we must now look for addresses that use a compatible
            //               address family to the client socket.
            //               However, in the case of the <hostname,port> constructor
            //               we will have deferred creating the socket and will
            //               do that here instead.
            //               In addition, the redundant CheckForBroadcast call was
            //               removed here since it is called from Connect().
            IPAddress[] addresses = Dns.GetHostAddressesAsync(hostname).GetAwaiter().GetResult();

            Exception lastex     = null;
            Socket    ipv6Socket = null;
            Socket    ipv4Socket = null;

            try
            {
                if (_clientSocket == null)
                {
                    if (Socket.OSSupportsIPv4)
                    {
                        ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    }
                    if (Socket.OSSupportsIPv6)
                    {
                        ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
                    }
                }

                foreach (IPAddress address in addresses)
                {
                    try
                    {
                        if (_clientSocket == null)
                        {
                            // We came via the <hostname,port> constructor. Set the
                            // address family appropriately, create the socket and
                            // try to connect.
                            if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null)
                            {
                                ipv4Socket.Connect(address, port);
                                _clientSocket = ipv4Socket;
                                if (ipv6Socket != null)
                                {
                                    ipv6Socket.Dispose();
                                }
                            }
                            else if (ipv6Socket != null)
                            {
                                ipv6Socket.Connect(address, port);
                                _clientSocket = ipv6Socket;
                                if (ipv4Socket != null)
                                {
                                    ipv4Socket.Dispose();
                                }
                            }

                            _family = address.AddressFamily;
                            _active = true;
                            break;
                        }
                        else if (address.AddressFamily == _family)
                        {
                            // Only use addresses with a matching family.
                            Connect(new IPEndPoint(address, port));
                            _active = true;
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ExceptionCheck.IsFatal(ex))
                        {
                            throw;
                        }
                        lastex = ex;
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionCheck.IsFatal(ex))
                {
                    throw;
                }
                lastex = ex;
            }
            finally
            {
                // Cleanup temp sockets on failure. The main socket gets closed when the UDPClient
                // gets closed.

                // Did we connect?
                if (!_active)
                {
                    if (ipv6Socket != null)
                    {
                        ipv6Socket.Dispose();
                    }

                    if (ipv4Socket != null)
                    {
                        ipv4Socket.Dispose();
                    }

                    // The connect failed - rethrow the last error we had.
                    if (lastex != null)
                    {
                        throw lastex;
                    }
                    else
                    {
                        throw new SocketException((int)SocketError.NotConnected);
                    }
                }
            }
        }
Exemple #26
0
        internal static int Encrypt(
            SafeDeleteContext securityContext,
            byte[] buffer,
            int offset,
            int count,
            bool isConfidential,
            bool isNtlm,
            ref byte[] output,
            uint sequenceNumber)
        {
            SecSizes sizes = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPIAuth,
                securityContext,
                Interop.SspiCli.ContextAttribute.Sizes
                ) as SecSizes;

            try
            {
                int maxCount = checked (Int32.MaxValue - 4 - sizes.BlockSize - sizes.SecurityTrailer);

                if (count > maxCount || count < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount));
                }
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range.");
                    }

                    Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::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 (isConfidential)
            {
                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(securityContext) + "::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
            {
                // TODO (Issue #6063): Should be offset by offset
                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);
        }