Inheritance: IAsyncResult
Exemple #1
0
		internal void BeginRenegotiate (LazyAsyncResult lazyResult)
		{
			HandshakeProtocolRequest asyncRequest = new HandshakeProtocolRequest (lazyResult);

			if (Interlocked.Exchange (ref _NestedWrite, 1) == 1)
				throw new NotSupportedException (SR.GetString (SR.net_io_invalidnestedcall, (asyncRequest != null ? "BeginRenegotiate" : "Renegotiate"), "renegotiate"));

			bool failed = false;
			try
			{
				if (_SslState.IsServer) {
					ProtocolToken message = _SslState.CreateHelloRequestMessage ();
					asyncRequest.SetNextRequest (HandshakeProtocolState.SendHelloRequest, message, _ResumeHandshakeWriteCallback);
				} else {
					asyncRequest.SetNextRequest (HandshakeProtocolState.ClientRenegotiation, null, _ResumeHandshakeWriteCallback);
				}

				StartHandshakeWrite (asyncRequest);
			} catch (Exception e) {
				_SslState.FinishWrite ();
				failed = true;
				throw;
			} finally {
				if (failed)
					_NestedWrite = 0;
			}
		}
Exemple #2
0
        private static void ReadCallback(IAsyncResult transportResult)
        {
            if (!(transportResult.AsyncState is LazyAsyncResult))
            {
                NetEventSource.Fail(transportResult, "State type is wrong, expected LazyAsyncResult.");
            }

            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            LazyAsyncResult lazyResult = (LazyAsyncResult)transportResult.AsyncState;

            // Async completion.
            try
            {
                NegoState authState = (NegoState)lazyResult.AsyncObject;
                byte[]    message   = authState._framer.EndReadMessage(transportResult);
                authState.ProcessReceivedBlob(message, lazyResult);
            }
            catch (Exception e)
            {
                if (lazyResult.InternalPeekCompleted)
                {
                    // This will throw on a worker thread.
                    throw;
                }

                lazyResult.InvokeCallback(e);
            }
        }
        private void CheckEnqueueWrite()
        {
            // Clear previous request.
            int lockState = Interlocked.CompareExchange(ref _lockWriteState, LockWrite, LockNone);

            if (lockState != LockHandshake)
            {
                // Proceed with write.
                return;
            }

            LazyAsyncResult lazyResult = null;

            lock (SyncLock)
            {
                if (_lockWriteState != LockHandshake)
                {
                    // Handshake has completed before we grabbed the lock.
                    ThrowIfExceptionalOrNotAuthenticated();
                    return;
                }

                _lockWriteState = LockPendingWrite;
            }

            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            ThrowIfExceptionalOrNotAuthenticated();
            return;
        }
Exemple #4
0
        internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
        {
            var lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback);

            ProcessWrite(buffer, offset, count, lazyResult);
            return(lazyResult);
        }
Exemple #5
0
        internal void EndProcessAuthentication(IAsyncResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            LazyAsyncResult lazyResult = result as LazyAsyncResult;

            if (lazyResult == null)
            {
                throw new ArgumentException(SR.Format(SR.net_io_async_result, result.GetType().FullName), "asyncResult");
            }

            if (Interlocked.Exchange(ref _nestedAuth, 0) == 0)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndAuthenticate"));
            }

            // No "artificial" timeouts implemented so far, InnerStream controls that.
            lazyResult.InternalWaitForCompletion();

            Exception e = lazyResult.Result as Exception;

            if (e != null)
            {
                // Round-trip it through the SetException().
                e = SetException(e);
                throw e;
            }
        }
        // Returns:
        // -1    - proceed
        // 0     - queued
        // X     - some bytes are ready, no need for IO
        private int CheckEnqueueRead(Memory <byte> buffer)
        {
            ThrowIfExceptionalOrNotAuthenticated();

            int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone);

            if (lockState != LockHandshake)
            {
                // Proceed, no concurrent handshake is ongoing so no need for a lock.
                return(-1);
            }

            LazyAsyncResult lazyResult = null;

            lock (SyncLock)
            {
                // Check again under lock.
                if (_lockReadState != LockHandshake)
                {
                    // The other thread has finished before we grabbed the lock.
                    _lockReadState = LockRead;
                    return(-1);
                }

                _lockReadState = LockPendingRead;
            }
            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            ThrowIfExceptionalOrNotAuthenticated();
            return(-1);
        }
        //
        //
        internal void EndWrite(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            LazyAsyncResult lazyResult = asyncResult as LazyAsyncResult;

            if (lazyResult == null)
            {
                throw new ArgumentException(SR.GetString(SR.net_io_async_result, asyncResult.GetType().FullName), "asyncResult");
            }

            if (Interlocked.Exchange(ref _NestedWrite, 0) == 0)
            {
                throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndWrite"));
            }

            // No "artificial" timeouts implemented so far, InnerStream controls timeout.
            lazyResult.InternalWaitForCompletion();

            if (lazyResult.Result is Exception)
            {
                if (lazyResult.Result is IOException)
                {
                    throw (Exception)lazyResult.Result;
                }
                throw new IOException(SR.GetString(SR.net_io_write), (Exception)lazyResult.Result);
            }
        }
Exemple #8
0
        internal void EndWrite(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }
            LazyAsyncResult result = asyncResult as LazyAsyncResult;

            if (result == null)
            {
                throw new ArgumentException(SR.GetString("net_io_async_result", new object[] { asyncResult.GetType().FullName }), "asyncResult");
            }
            if (Interlocked.Exchange(ref this._NestedWrite, 0) == 0)
            {
                throw new InvalidOperationException(SR.GetString("net_io_invalidendcall", new object[] { "EndWrite" }));
            }
            result.InternalWaitForCompletion();
            if (result.Result is Exception)
            {
                if (result.Result is IOException)
                {
                    throw ((Exception)result.Result);
                }
                throw new IOException(SR.GetString("net_io_write"), (Exception)result.Result);
            }
        }
Exemple #9
0
        //
        //
        //
        private static void WriteCallback(IAsyncResult transportResult)
        {
            GlobalLog.Assert(transportResult.AsyncState is LazyAsyncResult, "WriteCallback|State type is wrong, expected LazyAsyncResult.");
            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            LazyAsyncResult lazyResult = (LazyAsyncResult)transportResult.AsyncState;

            // Async completion
            try
            {
                NegoState authState = (NegoState)lazyResult.AsyncObject;
                authState._Framer.EndWriteMessage(transportResult);

                //special case for an error notification
                if (lazyResult.Result is Exception)
                {
                    authState._CanRetryAuthentication = true;
                    throw (Exception)lazyResult.Result;
                }
                authState.CheckCompletionBeforeNextReceive(lazyResult);
            }
            catch (Exception e)
            {
                if (lazyResult.InternalPeekCompleted)
                {
                    // This will throw on a worker thread.
                    throw;
                }
                lazyResult.InvokeCallback(e);
            }
        }
Exemple #10
0
        internal void ProcessAuthentication(LazyAsyncResult lazyResult)
        {
            CheckThrow(false);
            if (Interlocked.Exchange(ref _nestedAuth, 1) == 1)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, lazyResult == null ? "BeginAuthenticate" : "Authenticate", "authenticate"));
            }

            try
            {
                if (_context.IsServer)
                {
                    // Listen for a client blob.
                    StartReceiveBlob(lazyResult);
                }
                else
                {
                    // Start with the first blob.
                    StartSendBlob(null, lazyResult);
                }
            }
            catch (Exception e)
            {
                // Round-trip it through SetException().
                e = SetException(e);
                throw;
            }
            finally
            {
                if (lazyResult == null || _exception != null)
                {
                    _nestedAuth = 0;
                }
            }
        }
Exemple #11
0
        internal void EndWrite(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException(nameof(asyncResult));
            }

            LazyAsyncResult lazyResult = asyncResult as LazyAsyncResult;

            if (lazyResult == null)
            {
                throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult));
            }

            if (Interlocked.Exchange(ref _nestedWrite, 0) == 0)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite"));
            }

            // No "artificial" timeouts implemented so far, InnerStream controls timeout.
            lazyResult.InternalWaitForCompletion();

            if (lazyResult.Result is Exception e)
            {
                if (e is IOException)
                {
                    ExceptionDispatchInfo.Capture(e).Throw();
                }

                throw new IOException(SR.net_io_write, e);
            }
        }
Exemple #12
0
        //
        //
        internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
        {
            LazyAsyncResult      lazyResult   = new LazyAsyncResult(this, asyncState, asyncCallback);
            AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(lazyResult);

            ProcessWrite(buffer, offset, count, asyncRequest);
            return(lazyResult);
        }
        public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel, AsyncCallback asyncCallback, object asyncState)
        {
            this._NegoState.ValidateCreateContext(this._Package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);
            LazyAsyncResult lazyResult = new LazyAsyncResult(this._NegoState, asyncState, asyncCallback);

            this._NegoState.ProcessAuthentication(lazyResult);
            return(lazyResult);
        }
Exemple #14
0
        //
        //  Assumes that InnerStream type == typeof(NetworkStream)
        //
        internal IAsyncResult BeginWrite(BufferOffsetSize[] buffers, AsyncCallback asyncCallback, object asyncState)
        {
            LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback);
            SplitWriteAsyncProtocolRequest asyncRequest = new SplitWriteAsyncProtocolRequest(lazyResult);

            ProcessWrite(buffers, asyncRequest);
            return(lazyResult);
        }
        public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
        {
            this._SslState.ValidateCreateContext(false, targetHost, enabledSslProtocols, null, clientCertificates, true, checkCertificateRevocation);
            LazyAsyncResult lazyResult = new LazyAsyncResult(this._SslState, asyncState, asyncCallback);

            this._SslState.ProcessAuthentication(lazyResult);
            return(lazyResult);
        }
Exemple #16
0
        private void RehandshakeCompleteCallback(IAsyncResult result)
        {
            LazyAsyncResult result2 = (LazyAsyncResult)result;
            Exception       e       = result2.InternalWaitForCompletion() as Exception;

            if (e != null)
            {
                this.FinishHandshake(e, null);
            }
        }
Exemple #17
0
        public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired,
                                                              SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
                                                              AsyncCallback asyncCallback,
                                                              object asyncState)
        {
            _SslState.ValidateCreateContext(true, string.Empty, enabledSslProtocols, serverCertificate, null, clientCertificateRequired, checkCertificateRevocation);
            LazyAsyncResult result = new LazyAsyncResult(_SslState, asyncState, asyncCallback);

            _SslState.ProcessAuthentication(result);
            return(result);
        }
Exemple #18
0
        private IAsyncResult BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
        {
            SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback);

            _sslState.ValidateCreateContext(CreateAuthenticationOptions(sslServerAuthenticationOptions));

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);

            _sslState.ProcessAuthentication(result);
            return(result);
        }
Exemple #19
0
        public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates,
                                                              SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
                                                              AsyncCallback asyncCallback, object asyncState)
        {
            SecurityProtocol.ThrowOnNotAllowed(enabledSslProtocols);
            _sslState.ValidateCreateContext(false, targetHost, enabledSslProtocols, null, clientCertificates, true, checkCertificateRevocation);

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);

            _sslState.ProcessAuthentication(result);
            return(result);
        }
Exemple #20
0
        internal virtual IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
        {
            SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
            SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);

            _sslState.ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate);

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);

            _sslState.ProcessAuthentication(result);
            return(result);
        }
Exemple #21
0
        internal void InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
        {
            lazyResult.InternalWaitForCompletion();
            Exception result = lazyResult.Result as Exception;

            if (result != null)
            {
                this._Framing            = Framing.None;
                this._HandshakeCompleted = false;
                throw this.SetException(result);
            }
        }
        public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
        {
            if (!ComNetOS.IsWin2K)
            {
                throw new PlatformNotSupportedException(SR.GetString("Win2000Required"));
            }
            this._SslState.ValidateCreateContext(true, string.Empty, enabledSslProtocols, serverCertificate, null, clientCertificateRequired, checkCertificateRevocation);
            LazyAsyncResult lazyResult = new LazyAsyncResult(this._SslState, asyncState, asyncCallback);

            this._SslState.ProcessAuthentication(lazyResult);
            return(lazyResult);
        }
        public virtual IAsyncResult BeginAuthenticateAsServer(NetworkCredential credential, ExtendedProtectionPolicy policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel, AsyncCallback asyncCallback, object asyncState)
        {
            if (!ComNetOS.IsWin2K)
            {
                throw new PlatformNotSupportedException(SR.GetString("Win2000Required"));
            }
            this._NegoState.ValidateCreateContext(this._Package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);
            LazyAsyncResult lazyResult = new LazyAsyncResult(this._NegoState, asyncState, asyncCallback);

            this._NegoState.ProcessAuthentication(lazyResult);
            return(lazyResult);
        }
Exemple #24
0
 //
 // This will check and logically complete the auth handshake
 //
 private void CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult)
 {
     if (HandshakeComplete && _RemoteOk)
     {
         //we are done with success
         if (lazyResult != null)
         {
             lazyResult.InvokeCallback();
         }
         return;
     }
     StartReceiveBlob(lazyResult);
 }
        private void ProcessReceivedBlob(byte[] message, LazyAsyncResult lazyResult)
        {
            // This is an EOF otherwise we would get at least *empty* message but not a null one.
            if (message == null)
            {
                throw new AuthenticationException(SR.net_auth_eof, null);
            }

            // Process Header information.
            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeErrId)
            {
                Win32Exception e = null;
                if (message.Length >= 8)    // sizeof(long)
                {
                    // Try to recover remote win32 Exception.
                    long error = 0;
                    for (int i = 0; i < 8; ++i)
                    {
                        error = (error << 8) + message[i];
                    }

                    e = new Win32Exception((int)error);
                }

                if (e != null)
                {
                    if (e.NativeErrorCode == (int)Interop.SecurityStatus.LogonDenied)
                    {
                        throw new InvalidCredentialException(SR.net_auth_bad_client_creds, e);
                    }

                    if (e.NativeErrorCode == ERROR_TRUST_FAILURE)
                    {
                        throw new AuthenticationException(SR.net_auth_context_expectation_remote, e);
                    }
                }

                throw new AuthenticationException(SR.net_auth_alert, e);
            }

            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId)
            {
                _remoteOk = true;
            }
            else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId)
            {
                throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer.ReadHeader.MessageId, FrameHeader.HandshakeId), null);
            }

            CheckCompletionBeforeNextSend(message, lazyResult);
        }
Exemple #26
0
 private void CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult)
 {
     if (this.HandshakeComplete && this._RemoteOk)
     {
         if (lazyResult != null)
         {
             lazyResult.InvokeCallback();
         }
     }
     else
     {
         this.StartReceiveBlob(lazyResult);
     }
 }
Exemple #27
0
		internal void EndRenegotiate (LazyAsyncResult lazyResult)
		{
			if (Interlocked.Exchange (ref _NestedWrite, 0) == 0)
				throw new InvalidOperationException (SR.GetString (SR.net_io_invalidendcall, "EndRenegotiate"));

			// No "artificial" timeouts implemented so far, InnerStream controls timeout.
			lazyResult.InternalWaitForCompletion();

			if (lazyResult.Result is Exception) {
				if (lazyResult.Result is IOException)
					throw (Exception)lazyResult.Result;
				throw new IOException (SR.GetString (SR.mono_net_io_renegotiate), (Exception)lazyResult.Result);
			}
		}
Exemple #28
0
        private IAsyncResult BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
        {
            SecurityProtocol.ThrowOnNotAllowed(sslServerAuthenticationOptions.EnabledSslProtocols);
            SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback);

            // Set the delegate on the options.
            sslServerAuthenticationOptions._certValidationDelegate = _certValidationDelegate;

            _sslState.ValidateCreateContext(sslServerAuthenticationOptions);

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);

            _sslState.ProcessAuthentication(result, cancellationToken);
            return(result);
        }
Exemple #29
0
        internal virtual IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
        {
            SecurityProtocol.ThrowOnNotAllowed(sslClientAuthenticationOptions.EnabledSslProtocols);
            SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
            SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);

            // Set the delegates on the options.
            sslClientAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
            sslClientAuthenticationOptions._certSelectionDelegate  = _certSelectionDelegate;

            _sslState.ValidateCreateContext(sslClientAuthenticationOptions);

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);

            _sslState.ProcessAuthentication(result);
            return(result);
        }
Exemple #30
0
 private void StartReceiveBlob(LazyAsyncResult lazyResult)
 {
     byte[] buffer;
     if (lazyResult == null)
     {
         buffer = this._Framer.ReadMessage();
     }
     else
     {
         IAsyncResult asyncResult = this._Framer.BeginReadMessage(_ReadCallback, lazyResult);
         if (!asyncResult.CompletedSynchronously)
         {
             return;
         }
         buffer = this._Framer.EndReadMessage(asyncResult);
     }
     this.ProcessReceivedBlob(buffer, lazyResult);
 }
Exemple #31
0
 private void CheckCompletionBeforeNextSend(byte[] message, LazyAsyncResult lazyResult)
 {
     if (this.HandshakeComplete)
     {
         if (!this._RemoteOk)
         {
             throw new AuthenticationException(SR.GetString("net_io_header_id", new object[] { "MessageId", this._Framer.ReadHeader.MessageId, 20 }), null);
         }
         if (lazyResult != null)
         {
             lazyResult.InvokeCallback();
         }
     }
     else
     {
         this.StartSendBlob(message, lazyResult);
     }
 }
Exemple #32
0
 //
 // Server side starts here, but client also loops through this method
 //
 private void StartReceiveBlob(LazyAsyncResult lazyResult)
 {
     byte[] message;
     if (lazyResult == null)
     {
         message = _Framer.ReadMessage();
     }
     else
     {
         IAsyncResult ar = _Framer.BeginReadMessage(_ReadCallback, lazyResult);
         if (!ar.CompletedSynchronously)
         {
             return;
         }
         message = _Framer.EndReadMessage(ar);
     }
     ProcessReceivedBlob(message, lazyResult);
 }
Exemple #33
0
		internal IAsyncResult BeginRenegotiate (AsyncCallback asyncCallback, object asyncState)
		{
			var lazyResult = new LazyAsyncResult (this, asyncState, asyncCallback);

			if (Interlocked.Exchange (ref _NestedAuth, 1) == 1)
				throw new InvalidOperationException (SR.GetString (SR.net_io_invalidnestedcall, "BeginRenegotiate", "renegotiate"));
			if (Interlocked.CompareExchange (ref _PendingReHandshake, 1, 0) == 1)
				throw new InvalidOperationException (SR.GetString (SR.net_io_invalidnestedcall, "BeginRenegotiate", "renegotiate"));

			try {
				CheckThrow (false);
				SecureStream.BeginRenegotiate (lazyResult);
				return lazyResult;
			} catch (Exception e) {
				_NestedAuth = 0;
				if (e is IOException)
					throw;
				throw new IOException (SR.GetString (SR.mono_net_io_renegotiate), e);
			}
		}
Exemple #34
0
		internal void BeginShutdown (LazyAsyncResult lazyResult)
		{
			HandshakeProtocolRequest asyncRequest = new HandshakeProtocolRequest (lazyResult);

			if (Interlocked.Exchange (ref _NestedWrite, 1) == 1)
				throw new NotSupportedException (SR.GetString (SR.net_io_invalidnestedcall, (asyncRequest != null ? "BeginShutdown" : "Shutdown"), "shutdown"));

			bool failed = false;
			try
			{
				ProtocolToken message = _SslState.CreateShutdownMessage ();
				asyncRequest.SetNextRequest (HandshakeProtocolState.Shutdown, message, _ResumeHandshakeWriteCallback);

				StartHandshakeWrite (asyncRequest);
			} catch (Exception e) {
				_SslState.FinishWrite ();
				failed = true;
				throw;
			} finally {
				if (failed)
					_NestedWrite = 0;
			}
		}
Exemple #35
0
        //
        //
        //
        internal void InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
        {
            // No "artificial" timeouts implemented so far, InnerStream controls that.
            lazyResult.InternalWaitForCompletion();
            Exception e = lazyResult.Result as Exception;

            if (e != null)
            {
                // Failed auth, reset the framing if any.
                _Framing = Framing.Unknown;
                _handshakeCompleted = false;

                SetException(e).Throw();
            }
        }
        //
        // This will check and logically complete the auth handshake.
        //
        private void CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult)
        {
            if (HandshakeComplete && _remoteOk)
            {
                // We are done with success.
                if (lazyResult != null)
                {
                    lazyResult.InvokeCallback();
                }

                return;
            }

            StartReceiveBlob(lazyResult);
        }
Exemple #37
0
 internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
 {
     LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback);
     AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(lazyResult);
     ProcessWrite(buffer, offset, count, asyncRequest);
     return lazyResult;
 }
        //
        // Server side starts here, but client also loops through this method.
        //
        private void StartReceiveBlob(LazyAsyncResult lazyResult)
        {
            byte[] message;
            if (lazyResult == null)
            {
                message = _framer.ReadMessage();
            }
            else
            {
                IAsyncResult ar = _framer.BeginReadMessage(s_readCallback, lazyResult);
                if (!ar.CompletedSynchronously)
                {
                    return;
                }

                message = _framer.EndReadMessage(ar);
            }

            ProcessReceivedBlob(message, lazyResult);
        }
        //
        //
        private bool CheckEnqueueHandshakeRead(ref byte[] buffer, AsyncProtocolRequest request)
        {
            LazyAsyncResult lazyResult = null;
            lock (this)
            {
                if (_LockReadState == LockPendingRead)
                {
                    // we own the whole process and will never let read to take over until completed.
                    return false;
                }
                int lockState = Interlocked.Exchange(ref _LockReadState, LockHandshake);
                if (lockState != LockRead)
                {
                    // we came first
                    return false;
                }

                if (request != null)
                {
                    // Request queued
                    _QueuedReadStateRequest = request;
                    return true;
                }
                lazyResult = new LazyAsyncResult(null, null,/*must be */ null);
                _QueuedReadStateRequest = lazyResult;
            }
            // need to exit from lock before waiting
            lazyResult.InternalWaitForCompletion();
            buffer = (byte[])lazyResult.Result;
            return false;
        }
Exemple #40
0
        // Returns:
        // true  - operation queued
        // false - operation can proceed
        private bool CheckEnqueueHandshake(byte[] buffer, AsyncProtocolRequest asyncRequest)
        {
            LazyAsyncResult lazyResult = null;

            lock (this)
            {
                if (_lockWriteState == LockPendingWrite)
                {
                    return false;
                }

                int lockState = Interlocked.Exchange(ref _lockWriteState, LockHandshake);
                if (lockState != LockWrite)
                {
                    // Proceed with handshake.
                    return false;
                }

                if (asyncRequest != null)
                {
                    asyncRequest.Buffer = buffer;
                    _queuedWriteStateRequest = asyncRequest;
                    return true;
                }

                lazyResult = new LazyAsyncResult(null, null, /*must be*/null);
                _queuedWriteStateRequest = lazyResult;
            }
            lazyResult.InternalWaitForCompletion();
            return false;
        }
Exemple #41
0
        private IAsyncResult BeginAuthenticateAsServer(
            NetworkCredential credential,
            ExtendedProtectionPolicy policy,
            ProtectionLevel requiredProtectionLevel,
            TokenImpersonationLevel requiredImpersonationLevel,
            AsyncCallback asyncCallback,
            object asyncState)
        {
#if DEBUG
            using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
            {
#endif
                _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel);

                LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
                _negoState.ProcessAuthentication(result);

                return result;
#if DEBUG
            }
#endif
        }
Exemple #42
0
        // Returns:
        // -1    - proceed
        // 0     - queued
        // X     - some bytes are ready, no need for IO
        internal int CheckEnqueueRead(byte[] buffer, int offset, int count, AsyncProtocolRequest request)
        {
            int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone);

            if (lockState != LockHandshake)
            {
                // Proceed, no concurrent handshake is ongoing so no need for a lock.
                return CheckOldKeyDecryptedData(buffer, offset, count);
            }

            LazyAsyncResult lazyResult = null;
            lock (this)
            {
                int result = CheckOldKeyDecryptedData(buffer, offset, count);
                if (result != -1)
                {
                    return result;
                }

                // Check again under lock.
                if (_lockReadState != LockHandshake)
                {
                    // The other thread has finished before we grabbed the lock.
                    _lockReadState = LockRead;
                    return -1;
                }

                _lockReadState = LockPendingRead;

                if (request != null)
                {
                    // Request queued.
                    _queuedReadStateRequest = request;
                    return 0;
                }
                lazyResult = new LazyAsyncResult(null, null, /*must be */ null);
                _queuedReadStateRequest = lazyResult;
            }
            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            lock (this)
            {
                return CheckOldKeyDecryptedData(buffer, offset, count);
            }
        }
        private void ProcessReceivedBlob(byte[] message, LazyAsyncResult lazyResult)
        {
            // This is an EOF otherwise we would get at least *empty* message but not a null one.
            if (message == null)
            {
                throw new AuthenticationException(SR.net_auth_eof, null);
            }

            // Process Header information.
            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeErrId)
            {
                Win32Exception e = null;
                if (message.Length >= 8)    // sizeof(long)
                {
                    // Try to recover remote win32 Exception.
                    long error = 0;
                    for (int i = 0; i < 8; ++i)
                    {
                        error = (error << 8) + message[i];
                    }

                    e = new Win32Exception((int)error);
                }

                if (e != null)
                {
                    if (e.NativeErrorCode == (int)Interop.SecurityStatus.LogonDenied)
                    {
                        throw new InvalidCredentialException(SR.net_auth_bad_client_creds, e);
                    }

                    if (e.NativeErrorCode == ERROR_TRUST_FAILURE)
                    {
                        throw new AuthenticationException(SR.net_auth_context_expectation_remote, e);
                    }
                }

                throw new AuthenticationException(SR.net_auth_alert, e);
            }

            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId)
            {
                _remoteOk = true;
            }
            else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId)
            {
                throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer.ReadHeader.MessageId, FrameHeader.HandshakeId), null);
            }

            CheckCompletionBeforeNextSend(message, lazyResult);
        }
Exemple #44
0
 internal void ProcessAuthentication(LazyAsyncResult lazyResult)
 {
     throw new PlatformNotSupportedException();
 }
        //
        //  This is to reset auth state on the remote side.
        //  If this write succeeds we will allow auth retrying.
        //
        private void StartSendAuthResetSignal(LazyAsyncResult lazyResult, byte[] message, Exception exception)
        {
            _framer.WriteHeader.MessageId = FrameHeader.HandshakeErrId;

            Win32Exception win32exception = exception as Win32Exception;

            if (win32exception != null && win32exception.NativeErrorCode == (int)Interop.SecurityStatus.LogonDenied)
            {
                if (IsServer)
                {
                    exception = new InvalidCredentialException(SR.net_auth_bad_client_creds, exception);
                }
                else
                {
                    exception = new InvalidCredentialException(SR.net_auth_bad_client_creds_or_target_mismatch, exception);
                }
            }

            if (!(exception is AuthenticationException))
            {
                exception = new AuthenticationException(SR.net_auth_SSPI, exception);
            }

            if (lazyResult == null)
            {
                _framer.WriteMessage(message);
            }
            else
            {
                lazyResult.Result = exception;
                IAsyncResult ar = _framer.BeginWriteMessage(message, s_writeCallback, lazyResult);
                if (!ar.CompletedSynchronously)
                {
                    return;
                }

                _framer.EndWriteMessage(ar);
            }

            _canRetryAuthentication = true;
            throw exception;
        }
        //
        // This will check and logically complete the auth handshake.
        //
        private void CheckCompletionBeforeNextSend(byte[] message, LazyAsyncResult lazyResult)
        {
            //If we are done don't go into send.
            if (HandshakeComplete)
            {
                if (!_remoteOk)
                {
                    throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer.ReadHeader.MessageId, FrameHeader.HandshakeDoneId), null);
                }
                if (lazyResult != null)
                {
                    lazyResult.InvokeCallback();
                }

                return;
            }

            // Not yet done, get a new blob and send it if any.
            StartSendBlob(message, lazyResult);
        }
Exemple #47
0
        private bool CheckEnqueueHandshakeRead(ref byte[] buffer, AsyncProtocolRequest request)
        {
            LazyAsyncResult lazyResult = null;
            lock (this)
            {
                if (_lockReadState == LockPendingRead)
                {
                    return false;
                }

                int lockState = Interlocked.Exchange(ref _lockReadState, LockHandshake);
                if (lockState != LockRead)
                {
                    return false;
                }

                if (request != null)
                {
                    _queuedReadStateRequest = request;
                    return true;
                }

                lazyResult = new LazyAsyncResult(null, null, /*must be */ null);
                _queuedReadStateRequest = lazyResult;
            }

            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            buffer = (byte[])lazyResult.Result;
            return false;
        }
Exemple #48
0
 internal virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired,
                                                     SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
                                                     AsyncCallback asyncCallback,
                                                     object asyncState)
 {
     _sslState.ValidateCreateContext(true, string.Empty, enabledSslProtocols, serverCertificate, null, clientCertificateRequired, checkCertificateRevocation);
     LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);
     _sslState.ProcessAuthentication(result);
     return result;
 }
Exemple #49
0
        // Returns: 
        // true  - operation queued
        // false - operation can proceed
        internal bool CheckEnqueueWrite(AsyncProtocolRequest asyncRequest)
        {
            // Clear previous request.
            _queuedWriteStateRequest = null;
            int lockState = Interlocked.CompareExchange(ref _lockWriteState, LockWrite, LockNone);
            if (lockState != LockHandshake)
            {
                // Proceed with write.
                return false;
            }

            LazyAsyncResult lazyResult = null;
            lock (this)
            {
                if (_lockWriteState != LockHandshake)
                {
                    // Handshake has completed before we grabbed the lock.
                    CheckThrow(true);
                    return false;
                }

                _lockWriteState = LockPendingWrite;

                // Still pending, wait or enqueue.
                if (asyncRequest != null)
                {
                    _queuedWriteStateRequest = asyncRequest;
                    return true;
                }

                lazyResult = new LazyAsyncResult(null, null, /*must be */null);
                _queuedWriteStateRequest = lazyResult;
            }

            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            CheckThrow(true);
            return false;
        }
Exemple #50
0
        private void ProcessReceivedBlob(byte[] message, LazyAsyncResult lazyResult)
        {
            // This is an EOF otherwise we would get at least *empty* message but not a null one.
            if (message == null)
            {
                throw new AuthenticationException(SR.net_auth_eof, null);
            }

            // Process Header information.
            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeErrId)
            {
                if (message.Length >= 8)    // sizeof(long)
                {
                    // Try to recover remote win32 Exception.
                    long error = 0;
                    for (int i = 0; i < 8; ++i)
                    {
                        error = (error << 8) + message[i];
                    }

                    ThrowCredentialException(error);
                }

                throw new AuthenticationException(SR.net_auth_alert, null);
            }

            if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId)
            {
                _remoteOk = true;
            }
            else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId)
            {
                throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer.ReadHeader.MessageId, FrameHeader.HandshakeId), null);
            }

            CheckCompletionBeforeNextSend(message, lazyResult);
        }
Exemple #51
0
        //
        // This method assumes that a SSPI context is already in a good shape.
        // For example it is either a fresh context or already authenticated context that needs renegotiation.
        //
        internal void ProcessAuthentication(LazyAsyncResult lazyResult)
        {
            if (Interlocked.Exchange(ref _nestedAuth, 1) == 1)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, lazyResult == null ? "BeginAuthenticate" : "Authenticate", "authenticate"));
            }

            try
            {
                CheckThrow(false);
                AsyncProtocolRequest asyncRequest = null;
                if (lazyResult != null)
                {
                    asyncRequest = new AsyncProtocolRequest(lazyResult);
                    asyncRequest.Buffer = null;
#if DEBUG
                    lazyResult._debugAsyncChain = asyncRequest;
#endif
                }

                //  A trick to discover and avoid cached sessions.
                _CachedSession = CachedSessionStatus.Unknown;

                ForceAuthentication(Context.IsServer, null, asyncRequest);

                // Not aync so the connection is completed at this point.
                if (lazyResult == null && SecurityEventSource.Log.IsEnabled())
                {
                    SecurityEventSource.Log.SspiSelectedCipherSuite("ProcessAuthentication",
                        SslProtocol,
                        CipherAlgorithm,
                        CipherStrength,
                        HashAlgorithm,
                        HashStrength,
                        KeyExchangeAlgorithm,
                        KeyExchangeStrength);
                }
            }
            catch (Exception)
            {
                // If an exception emerges synchronously, the asynchronous operation was not
                // initiated, so no operation is in progress.
                _nestedAuth = 0;
                throw;
            }
            finally
            {
                // For synchronous operations, the operation has completed.
                if (lazyResult == null)
                {
                    _nestedAuth = 0;
                }
            }
        }
Exemple #52
0
			public HandshakeProtocolRequest (LazyAsyncResult userAsyncResult)
				: base (userAsyncResult)
			{
				State = HandshakeProtocolState.None;
			}
Exemple #53
0
        internal virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates,
                                                            SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
                                                            AsyncCallback asyncCallback, object asyncState)
        {
            _sslState.ValidateCreateContext(false, targetHost, enabledSslProtocols, null, clientCertificates, true, checkCertificateRevocation);

            LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);
            _sslState.ProcessAuthentication(result);
            return result;
        }
            internal SplitWritesState SplitWritesState;  // If one buffer is no enough (such as for multiple writes)

            internal SplitWriteAsyncProtocolRequest(LazyAsyncResult userAsyncResult): base (userAsyncResult)
            {
            }
Exemple #55
0
 //
 // This method assumes that a SSPI context is already in a good shape.
 // For example it is either a fresh context or already authenticated context that needs renegotiation.
 //
 internal void ProcessAuthentication(LazyAsyncResult lazyResult)
 {
 }
 //
 //  Assumes that InnerStream type == typeof(NetworkStream)
 //
 internal IAsyncResult BeginWrite(BufferOffsetSize[] buffers, AsyncCallback asyncCallback, object asyncState)
 {
     LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback);
     SplitWriteAsyncProtocolRequest asyncRequest = new SplitWriteAsyncProtocolRequest(lazyResult);
     ProcessWrite(buffers, asyncRequest);
     return lazyResult;
 }
        internal void ProcessAuthentication(LazyAsyncResult lazyResult)
        {
            CheckThrow(false);
            if (Interlocked.Exchange(ref _nestedAuth, 1) == 1)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, lazyResult == null ? "BeginAuthenticate" : "Authenticate", "authenticate"));
            }

            try
            {
                if (_context.IsServer)
                {
                    // Listen for a client blob.
                    StartReceiveBlob(lazyResult);
                }
                else
                {
                    // Start with the first blob.
                    StartSendBlob(null, lazyResult);
                }
            }
            catch (Exception e)
            {
                // Round-trip it through SetException().
                e = SetException(e);
                throw;
            }
            finally
            {
                if (lazyResult == null || _exception != null)
                {
                    _nestedAuth = 0;
                }
            }
        }
Exemple #58
0
        //
        // This method assumes that a SSPI context is already in a good shape.
        // For example it is either a fresh context or already authenticated context that needs renegotiation.
        //
        internal void ProcessAuthentication(LazyAsyncResult lazyResult)
        {
            if (Interlocked.Exchange(ref _nestedAuth, 1) == 1)
            {
                throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, lazyResult == null ? "BeginAuthenticate" : "Authenticate", "authenticate"));
            }

            try
            {
                CheckThrow(false);
                AsyncProtocolRequest asyncRequest = null;
                if (lazyResult != null)
                {
                    asyncRequest = new AsyncProtocolRequest(lazyResult);
                    asyncRequest.Buffer = null;
#if DEBUG
                    lazyResult._DebugAsyncChain = asyncRequest;
#endif
                }

                //  A trick to discover and avoid cached sessions.
                _CachedSession = CachedSessionStatus.Unknown;

                ForceAuthentication(Context.IsServer, null, asyncRequest);

                // Not aync so the connection is completed at this point.
                if (lazyResult == null && Logging.On)
                {
                    Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_selected_cipher_suite,
                        "ProcessAuthentication",
                        SslProtocol,
                        CipherAlgorithm,
                        CipherStrength,
                        HashAlgorithm,
                        HashStrength,
                        KeyExchangeAlgorithm,
                        KeyExchangeStrength));
                }
            }
            finally
            {
                if (lazyResult == null || _exception != null)
                {
                    _nestedAuth = 0;
                }
            }
        }
Exemple #59
0
        private IAsyncResult BeginAuthenticateAsClient(
            NetworkCredential credential,
            ChannelBinding binding,
            string targetName,
            ProtectionLevel requiredProtectionLevel,
            TokenImpersonationLevel allowedImpersonationLevel,
            AsyncCallback asyncCallback,
            object asyncState)
        {
#if DEBUG
            using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async))
            {
#endif
                _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel);

                LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback);
                _negoState.ProcessAuthentication(result);

                return result;
#if DEBUG
            }
#endif
        }
        //
        // Client side starts here, but server also loops through this method.
        //
        private void StartSendBlob(byte[] message, LazyAsyncResult lazyResult)
        {
            Win32Exception win32exception = null;
            if (message != s_emptyMessage)
            {
                message = GetOutgoingBlob(message, ref win32exception);
            }

            if (win32exception != null)
            {
                // Signal remote side on a failed attempt.
                StartSendAuthResetSignal(lazyResult, message, win32exception);
                return;
            }

            if (HandshakeComplete)
            {
                if (_context.IsServer && !CheckSpn())
                {
                    Exception exception = new AuthenticationException(SR.net_auth_bad_client_creds_or_target_mismatch);
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                if (PrivateImpersonationLevel < _expectedImpersonationLevel)
                {
                    Exception exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, _expectedImpersonationLevel.ToString(), PrivateImpersonationLevel.ToString()));
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                ProtectionLevel result = _context.IsConfidentialityFlag ? ProtectionLevel.EncryptAndSign : _context.IsIntegrityFlag ? ProtectionLevel.Sign : ProtectionLevel.None;

                if (result < _expectedProtectionLevel)
                {
                    Exception exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, result.ToString(), _expectedProtectionLevel.ToString()));
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                // Signal remote party that we are done
                _framer.WriteHeader.MessageId = FrameHeader.HandshakeDoneId;
                if (_context.IsServer)
                {
                    // Server may complete now because client SSPI would not complain at this point.
                    _remoteOk = true;

                    // However the client will wait for server to send this ACK
                    //Force signaling server OK to the client
                    if (message == null)
                    {
                        message = s_emptyMessage;
                    }
                }
            }
            else if (message == null || message == s_emptyMessage)
            {
                throw new InternalException();
            }

            if (message != null)
            {
                //even if we are completed, there could be a blob for sending.
                if (lazyResult == null)
                {
                    _framer.WriteMessage(message);
                }
                else
                {
                    IAsyncResult ar = _framer.BeginWriteMessage(message, s_writeCallback, lazyResult);
                    if (!ar.CompletedSynchronously)
                    {
                        return;
                    }
                    _framer.EndWriteMessage(ar);
                }
            }
            CheckCompletionBeforeNextReceive(lazyResult);
        }