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; } }
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; }
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); }
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); } }
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); } }
// // // 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); } }
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; } } }
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); } }
// // 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); }
// // 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); }
private void RehandshakeCompleteCallback(IAsyncResult result) { LazyAsyncResult result2 = (LazyAsyncResult)result; Exception e = result2.InternalWaitForCompletion() as Exception; if (e != null) { this.FinishHandshake(e, null); } }
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); }
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); }
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); }
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); }
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); }
// // 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); }
private void CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult) { if (this.HandshakeComplete && this._RemoteOk) { if (lazyResult != null) { lazyResult.InvokeCallback(); } } else { this.StartReceiveBlob(lazyResult); } }
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); } }
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); }
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); }
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); }
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); } }
// // 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); }
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); } }
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; } }
// // // 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); }
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; }
// 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; }
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 }
// 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); } }
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); }
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; }
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; }
// 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; }
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); }
// // 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; } } }
public HandshakeProtocolRequest (LazyAsyncResult userAsyncResult) : base (userAsyncResult) { State = HandshakeProtocolState.None; }
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) { }
// // 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; }
// // 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; } } }
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); }