} // StopListening // // end of IChannelReceiver implementation // // Thread for listening void Listen() { InternalRemotingServices.RemotingTrace("Waiting to Accept a Connection on Port: " + _portName); // // Wait for an incoming client connection // IntPtr handle = IntPtr.Zero; bool connected = false; CommonSecurityDescriptor descriptor = _securityDescriptor; // Connect with exlusive flag the first time try{ // If the descriptor is not explicitly set through code use the _authorizedGroup config if (descriptor == null && _authorizedGroup != null) { NTAccount ntAccount = new NTAccount(_authorizedGroup); descriptor = IpcPort.CreateSecurityDescriptor((SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier))); } _port = IpcPort.Create(_portName, descriptor, _bExclusiveAddressUse); } catch (Exception e) { _startListeningException = e; } finally { _bListening = (_startListeningException == null); _waitForStartListening.Set(); // allow main thread to continue now that we have tried to start the socket } if (_port != null) { connected = _port.WaitForConnect(); } while (_bListening) { InternalRemotingServices.RemotingTrace("IpcChannel::Listen"); // For DevDiv#220882, we need to create new IpcPort before handling the current message // to avoid race condition in case the message is handled and finished before // the new IpcPort is created. The client will intermittently fail with Port not found. IpcPort port = IpcPort.Create(_portName, descriptor, false); if (connected) { // Initialize the server handler and perform an async read IpcServerHandler serverHandler = new IpcServerHandler(_port, CoreChannel.RequestQueue, new PipeStream(_port)); serverHandler.DataArrivedCallback = new WaitCallback(_transportSink.ServiceRequest); serverHandler.BeginReadMessage(); } _port = port; connected = _port.WaitForConnect(); } }
internal void ServiceRequest(object state) { IpcServerHandler handler = (IpcServerHandler)state; ITransportHeaders requestHeaders = handler.ReadHeaders(); Stream requestStream = handler.GetRequestStream(); requestHeaders["__CustomErrorsEnabled"] = false; ServerChannelSinkStack sinkStack = new ServerChannelSinkStack(); sinkStack.Push(this, handler); IMessage responseMsg = null; ITransportHeaders responseHeaders = null; Stream responseStream = null; WindowsIdentity current = null; IPrincipal currentPrincipal = null; bool flag = false; bool flag2 = false; ServerProcessing complete = ServerProcessing.Complete; try { if (this._secure) { handler.Port.ImpersonateClient(); currentPrincipal = Thread.CurrentPrincipal; flag2 = true; flag = true; current = WindowsIdentity.GetCurrent(); if (!this._impersonate) { NativePipe.RevertToSelf(); Thread.CurrentPrincipal = new GenericPrincipal(current, null); flag = false; } else { if ((current.ImpersonationLevel != TokenImpersonationLevel.Impersonation) && (current.ImpersonationLevel != TokenImpersonationLevel.Delegation)) { throw new RemotingException(CoreChannel.GetResourceString("Remoting_Ipc_TokenImpersonationFailure")); } Thread.CurrentPrincipal = new WindowsPrincipal(current); } } complete = this._nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); } catch (Exception exception) { handler.CloseOnFatalError(exception); } finally { if (flag2) { Thread.CurrentPrincipal = currentPrincipal; } if (flag) { NativePipe.RevertToSelf(); flag = false; } } switch (complete) { case ServerProcessing.Complete: sinkStack.Pop(this); handler.SendResponse(responseHeaders, responseStream); break; case ServerProcessing.OneWay: handler.SendResponse(responseHeaders, responseStream); break; case ServerProcessing.Async: sinkStack.StoreAndDispatch(this, handler); break; } if (complete != ServerProcessing.Async) { handler.BeginReadMessage(); } }
} // StopListening // // end of IChannelReceiver implementation // // Thread for listening void Listen() { bool bOkToListen = true; InternalRemotingServices.RemotingTrace( "Waiting to Accept a Connection on Port: " + _portName); // // Wait for an incoming client connection // IntPtr handle = IntPtr.Zero; bool connected = false; CommonSecurityDescriptor descriptor = _securityDescriptor; // Connect with exlusive flag the first time if (bOkToListen) { try{ // If the descriptor is not explicitly set through code use the _authorizedGroup config if (descriptor == null && _authorizedGroup != null) { NTAccount ntAccount = new NTAccount(_authorizedGroup); descriptor = IpcPort.CreateSecurityDescriptor((SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier))); } _port = IpcPort.Create(_portName, descriptor, _bExclusiveAddressUse); } catch (Exception e) { _startListeningException = e; } finally { _waitForStartListening.Set(); // allow main thread to continue now that we have tried to start the socket } if (_port != null){ connected = _port.WaitForConnect(); bOkToListen = _bListening; } } while (bOkToListen && _startListeningException == null) { InternalRemotingServices.RemotingTrace("IpcChannel::Listen"); // For DevDiv#220882, we need to create new IpcPort before handling the current message // to avoid race condition in case the message is handled and finished before // the new IpcPort is created. The client will intermittently fail with Port not found. IpcPort port = IpcPort.Create(_portName, descriptor, false); if (connected) { // Initialize the server handler and perform an async read IpcServerHandler serverHandler = new IpcServerHandler(_port, CoreChannel.RequestQueue, new PipeStream(_port)); serverHandler.DataArrivedCallback = new WaitCallback(_transportSink.ServiceRequest); serverHandler.BeginReadMessage(); } _port = port; connected = _port.WaitForConnect(); bOkToListen = _bListening; } }
internal void ServiceRequest(Object state) { IpcServerHandler ipcServerHandler = (IpcServerHandler)state; // Read the headers from the stream, using the header size in the message ITransportHeaders headers = ipcServerHandler.ReadHeaders(); // Get the request Stream Stream requestStream = ipcServerHandler.GetRequestStream(); // customErrors should be disabled, since we are on the same machine headers["__CustomErrorsEnabled"] = false; // process request ServerChannelSinkStack sinkStack = new ServerChannelSinkStack(); sinkStack.Push(this, ipcServerHandler); IMessage responseMessage = null; ITransportHeaders responseHeaders = null; Stream responseStream = null; WindowsIdentity identity = null; IPrincipal oldPrincipal = null; bool impersonated = false; bool principalChanged = false; ServerProcessing processing = ServerProcessing.Complete; try{ if (_secure) { IpcPort port = ipcServerHandler.Port; port.ImpersonateClient(); oldPrincipal = Thread.CurrentPrincipal; principalChanged = true; impersonated = true; identity = WindowsIdentity.GetCurrent(); // If the authentication mode is to identify callers only revert the impersonation immediately if (!_impersonate) { NativePipe.RevertToSelf(); Thread.CurrentPrincipal = new GenericPrincipal(identity, null); impersonated = false; } else { if (identity.ImpersonationLevel == TokenImpersonationLevel.Impersonation || identity.ImpersonationLevel == TokenImpersonationLevel.Delegation) { // Set the current principal Thread.CurrentPrincipal = new WindowsPrincipal(identity); } else { throw new RemotingException(CoreChannel.GetResourceString( "Remoting_Ipc_TokenImpersonationFailure")); } } } processing = _nextSink.ProcessMessage(sinkStack, null, headers, requestStream, out responseMessage, out responseHeaders, out responseStream); } catch (Exception e) { ipcServerHandler.CloseOnFatalError(e); } finally{ // Revert the principal if we had changed the principal if (principalChanged) { Thread.CurrentPrincipal = oldPrincipal; } // Revert the impersonation if we had impersonated if (impersonated) { NativePipe.RevertToSelf(); impersonated = false; } } // handle response switch (processing) { case ServerProcessing.Complete: { // Send the response. Call completed synchronously. sinkStack.Pop(this); // Send the response back to the client ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.Complete case ServerProcessing.OneWay: { // No response needed, but the following method will make sure that // we send at least a skeleton reply if the incoming request was // not marked OneWayRequest (client/server metadata could be out of // [....]). ipcServerHandler.SendResponse(responseHeaders, responseStream); break; } // case ServerProcessing.OneWay case ServerProcessing.Async: { sinkStack.StoreAndDispatch(this, ipcServerHandler); break; } // case ServerProcessing.Async } // switch (processing) // Start waiting for the next request if (processing != ServerProcessing.Async) { ipcServerHandler.BeginReadMessage(); } } // ServiceRequest