private void HandleResponseReceived(object sender, RemoteDataEventArgs <PSObject> eventArgs) { PSObject data = eventArgs.Data; object propertyValue = RemotingDecoder.GetPropertyValue <object>(data, "SetMinMaxRunspacesResponse"); this.dispatchTable.SetResponse(RemotingDecoder.GetPropertyValue <long>(data, "ci"), propertyValue); }
private void HandleInformationalMessageReceived(object sender, RemoteDataEventArgs <InformationalMessage> eventArgs) { using (tracer.TraceEventHandlers()) { InformationalMessage data = eventArgs.Data; switch (data.DataType) { case RemotingDataType.PowerShellDebug: this.informationalBuffers.AddDebug((DebugRecord)data.Message); return; case RemotingDataType.PowerShellVerbose: this.informationalBuffers.AddVerbose((VerboseRecord)data.Message); return; case RemotingDataType.PowerShellWarning: this.informationalBuffers.AddWarning((WarningRecord)data.Message); return; case RemotingDataType.PowerShellProgress: break; default: return; } ProgressRecord item = (ProgressRecord)LanguagePrimitives.ConvertTo(data.Message, typeof(ProgressRecord), CultureInfo.InvariantCulture); this.informationalBuffers.AddProgress(item); } }
private void HandleHostCallReceived(object sender, RemoteDataEventArgs <RemoteHostCall> eventArgs) { using (tracer.TraceEventHandlers()) { Collection <RemoteHostCall> collection = eventArgs.Data.PerformSecurityChecksOnHostMessage(this.computerName); if (this.HostCallReceived != null) { if (collection.Count > 0) { foreach (RemoteHostCall call in collection) { RemoteDataEventArgs <RemoteHostCall> args = new RemoteDataEventArgs <RemoteHostCall>(call); this.HostCallReceived.SafeInvoke <RemoteDataEventArgs <RemoteHostCall> >(this, args); } } this.HostCallReceived.SafeInvoke <RemoteDataEventArgs <RemoteHostCall> >(this, eventArgs); } else { if (collection.Count > 0) { foreach (RemoteHostCall call2 in collection) { this.ExecuteHostCall(call2); } } this.ExecuteHostCall(eventArgs.Data); } } }
internal void DispatchInputQueueData(object sender, RemoteDataEventArgs dataArg) { using (ClientRemoteSessionDSHandlerImpl._trace.TraceMethod()) { RemoteDataObject <PSObject> remoteDataObject = dataArg != null ? dataArg.ReceivedData : throw ClientRemoteSessionDSHandlerImpl._trace.NewArgumentNullException(nameof(dataArg)); RemotingDestination remotingDestination = remoteDataObject != null ? remoteDataObject.Destination : throw ClientRemoteSessionDSHandlerImpl._trace.NewArgumentException(nameof(dataArg)); if ((remotingDestination & RemotingDestination.Client) != RemotingDestination.Client) { throw new PSRemotingDataStructureException(PSRemotingErrorId.RemotingDestinationNotForMe, new object[2] { (object)RemotingDestination.Client, (object)remotingDestination }); } switch (remoteDataObject.TargetInterface) { case RemotingTargetInterface.Session: this.ProcessSessionMessages(dataArg); break; case RemotingTargetInterface.RunspacePool: case RemotingTargetInterface.PowerShell: RemoteSessionStateMachineEventArgs machineEventArgs = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived, (Exception)null); if (this.StateMachine.CanByPassRaiseEvent(machineEventArgs)) { this.ProcessNonSessionMessages(dataArg.ReceivedData); break; } this.StateMachine.RaiseEvent(machineEventArgs); break; } } }
private void HandleInvocationStateInfoReceived(object sender, RemoteDataEventArgs <PSInvocationStateInfo> eventArgs) { using (tracer.TraceEventHandlers()) { PSInvocationStateInfo data = eventArgs.Data; if (data.State == PSInvocationState.Disconnected) { this.SetStateInfo(data); } else if (((data.State == PSInvocationState.Stopped) || (data.State == PSInvocationState.Failed)) || (data.State == PSInvocationState.Completed)) { this.UnblockCollections(); if (this.stopCalled) { this.stopCalled = false; this.stateInfoQueue.Enqueue(new PSInvocationStateInfo(PSInvocationState.Stopped, data.Reason)); this.CheckAndCloseRunspaceAfterStop(data.Reason); } else { this.stateInfoQueue.Enqueue(data); } this.dataStructureHandler.CloseConnectionAsync(null); } } }
/// <summary> /// Handles notification from RunspacePool indicating /// that the pool is broken. This sets the state of /// all the powershell objects associated with the /// runspace pool to Failed /// </summary> /// <param name="sender">sender of this information, unused.</param> /// <param name="eventArgs">arguments describing this event /// contains information on the reason associated with the /// runspace pool entering a Broken state</param> private void HandleBrokenNotificationFromRunspacePool(object sender, RemoteDataEventArgs <Exception> eventArgs) { // RunspacePool is closed...so going to set the state of PowerShell // to stopped here. // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); // Since this is a terminal state..close the transport manager. dataStructureHandler.RaiseRemoveAssociationEvent(); if (stopCalled) { // Reset stop called flag. stopCalled = false; // if a Stop method has been called, then powershell // would have already raised a Stopping event, after // which only a Stopped should be raised SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Stopped, eventArgs.Data)); } else { SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Failed, eventArgs.Data)); } // Not calling dataStructureHandler.CloseConnection() as this must // have already been called by RunspacePool.Close() }
private void HandleURIDirectionReported(object sender, RemoteDataEventArgs <Uri> eventArgs) { string message = StringUtil.Format(RemotingErrorIdStrings.URIRedirectWarningToHost, eventArgs.Data.OriginalString); Action <Cmdlet> action = cmdlet => cmdlet.WriteWarning(message); this.stream.Write(action); }
/// <summary> /// Handles an encrypted session key received from the other side /// </summary> /// <param name="sender">Sender of this event.</param> /// <param name="eventArgs">arguments that contain the remote /// public key</param> private void HandleEncryptedSessionKeyReceived(object sender, RemoteDataEventArgs <string> eventArgs) { if (SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeySent) { string encryptedSessionKey = eventArgs.Data; bool ret = _cryptoHelper.ImportEncryptedSessionKey(encryptedSessionKey); RemoteSessionStateMachineEventArgs args = null; if (!ret) { // importing remote public key failed // set state to closed args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } // complete the key exchange process CompleteKeyExchange(); args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } }
internal override void RaiseDataReceivedEvent(RemoteDataEventArgs dataArg) { if (dataArg == null) { throw PSTraceSource.NewArgumentNullException("dataArg"); } RemoteDataObject <PSObject> receivedData = dataArg.ReceivedData; RemotingTargetInterface targetInterface = receivedData.TargetInterface; RemotingDataType dataType = receivedData.DataType; switch (dataType) { case RemotingDataType.SessionCapability: { RemoteSessionCapability remoteSessionCapability = null; try { remoteSessionCapability = RemotingDecoder.GetSessionCapability(receivedData.Data); } catch (PSRemotingDataStructureException exception2) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerNotFoundCapabilityProperties, new object[] { exception2.Message, PSVersionInfo.BuildVersion, RemotingConstants.ProtocolVersion }); } RemoteSessionStateMachineEventArgs fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationReceived) { RemoteSessionCapability = remoteSessionCapability }; this._stateMachine.RaiseEvent(fsmEventArg); if (this.NegotiationReceived != null) { RemoteSessionNegotiationEventArgs eventArgs = new RemoteSessionNegotiationEventArgs(remoteSessionCapability) { RemoteData = receivedData }; this.NegotiationReceived.SafeInvoke <RemoteSessionNegotiationEventArgs>(this, eventArgs); } return; } case RemotingDataType.CloseSession: { PSRemotingDataStructureException reason = new PSRemotingDataStructureException(RemotingErrorIdStrings.ClientRequestedToCloseSession); RemoteSessionStateMachineEventArgs args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.Close, reason); this._stateMachine.RaiseEvent(args); return; } case RemotingDataType.CreateRunspacePool: this.CreateRunspacePoolReceived.SafeInvoke <RemoteDataEventArgs>(this, dataArg); return; case RemotingDataType.PublicKey: { string publicKey = RemotingDecoder.GetPublicKey(receivedData.Data); this.PublicKeyReceived.SafeInvoke <RemoteDataEventArgs <string> >(this, new RemoteDataEventArgs <string>(publicKey)); return; } } throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ReceivedUnsupportedAction, new object[] { dataType }); }
internal void HandleApplicationPrivateDataReceived( object sender, RemoteDataEventArgs <PSPrimitiveDictionary> eventArgs) { using (RemoteRunspacePoolInternal.tracer.TraceMethod()) this.SetApplicationPrivateData(eventArgs.Data); }
/// <summary> /// Dispatches data when it arrives from the input queue /// </summary> /// <param name="sender"></param> /// <param name="dataArg"> /// arg which contains the data received from input queue /// </param> internal void DispatchInputQueueData(object sender, RemoteDataEventArgs dataArg) { if (dataArg == null) { throw PSTraceSource.NewArgumentNullException("dataArg"); } RemoteDataObject <PSObject> rcvdData = dataArg.ReceivedData; if (rcvdData == null) { throw PSTraceSource.NewArgumentException("dataArg"); } RemotingDestination destination = rcvdData.Destination; if ((destination & RemotingDestination.Client) != RemotingDestination.Client) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.RemotingDestinationNotForMe, RemotingDestination.Client, destination); } RemotingTargetInterface targetInterface = rcvdData.TargetInterface; switch (targetInterface) { case RemotingTargetInterface.Session: { //Messages for session can cause statemachine state to change. //These messages are first processed by Sessiondata structure handler and depending //on the type of message, appropriate event is raised in state machine ProcessSessionMessages(dataArg); break; } case RemotingTargetInterface.RunspacePool: case RemotingTargetInterface.PowerShell: //Non Session messages do not change the state of the statemachine. //However instead of forwarding them to Runspace/pipeline here, an //event is raised in state machine which verified that state is //suitable for accepting these messages. if state is suitable statemachine //will call DoMessageForwading which will forward the messages appropriately RemoteSessionStateMachineEventArgs msgRcvArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived, null); if (StateMachine.CanByPassRaiseEvent(msgRcvArg)) { ProcessNonSessionMessages(dataArg.ReceivedData); } else { StateMachine.RaiseEvent(msgRcvArg); } break; default: { Dbg.Assert(false, "we should not be encountering this"); } break; } }
private void HandleSessionRCDisconnecting(object sender, RemoteDataEventArgs <Exception> e) { lock (base.syncObject) { this.SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Disconnecting, e.Data)); } base.RaiseStateChangeEvent(base.stateInfo); }
/// <summary> /// An error record is received from the powershell at the /// server side. It is added to the error collection of the /// client powershell /// </summary> /// <param name="sender">sender of this event, unused.</param> /// <param name="eventArgs">arguments describing this event.</param> private void HandleErrorReceived(object sender, RemoteDataEventArgs <ErrorRecord> eventArgs) { using (s_tracer.TraceEventHandlers()) { shell.SetHadErrors(true); errorstream.Write(eventArgs.Data); } }
internal static void ExitHandler(object sender, RemoteDataEventArgs <RemoteHostCall> eventArgs) { RemoteHostCall data = eventArgs.Data; if (!data.IsSetShouldExitOrPopRunspace) { ((ClientRemotePowerShell)sender).ExecuteHostCall(data); } }
private void HandleURIDirectionReported(object sender, RemoteDataEventArgs <Uri> eventArgs) { WSManConnectionInfo connectionInfo = this.connectionInfo as WSManConnectionInfo; if (connectionInfo != null) { connectionInfo.ConnectionUri = eventArgs.Data; this.URIRedirectionReported.SafeInvoke <RemoteDataEventArgs <Uri> >(this, eventArgs); } }
private void ProcessSessionMessages(RemoteDataEventArgs arg) { using (ClientRemoteSessionDSHandlerImpl._trace.TraceMethod()) { RemoteDataObject <PSObject> remoteDataObject = arg != null && arg.ReceivedData != null ? arg.ReceivedData : throw ClientRemoteSessionDSHandlerImpl._trace.NewArgumentNullException(nameof(arg)); int targetInterface = (int)remoteDataObject.TargetInterface; RemotingDataType dataType = remoteDataObject.DataType; switch (dataType) { case RemotingDataType.SessionCapability: RemoteSessionCapability sessionCapability; try { sessionCapability = RemotingDecoder.GetSessionCapability((object)remoteDataObject.Data); } catch (PSRemotingDataStructureException ex) { throw new PSRemotingDataStructureException(PSRemotingErrorId.ClientNotFoundCapabilityProperties, new object[3] { (object)ex.Message, (object)PSVersionInfo.BuildVersion, (object)RemotingConstants.ProtocolVersion }); } this._stateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationReceived) { RemoteSessionCapability = sessionCapability }); if (this.NegotiationReceived == null) { break; } this.NegotiationReceived((object)this, new RemoteSessionNegotiationEventArgs(sessionCapability)); break; case RemotingDataType.CloseSession: this._stateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.Close, (Exception) new PSRemotingDataStructureException(PSRemotingErrorId.ServerRequestedToCloseSession, new object[0]))); break; case RemotingDataType.EncryptedSessionKey: this.EncryptedSessionKeyReceived((object)this, new RemoteDataEventArgs <string>((object)RemotingDecoder.GetEncryptedSessionKey(remoteDataObject.Data))); break; case RemotingDataType.PublicKeyRequest: this.PublicKeyRequestReceived((object)this, new RemoteDataEventArgs <string>((object)string.Empty)); break; default: throw new PSRemotingDataStructureException(PSRemotingErrorId.ReceivedUnsupportedAction, new object[1] { (object)dataType }); } } }
private void HandlePublicKeyRequestReceived( object sender, RemoteDataEventArgs <string> eventArgs) { if (this.SessionDataStructureHandler.StateMachine.State != RemoteSessionState.Established) { return; } this.SessionDataStructureHandler.StateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyRequested)); this.StartKeyExchange(); }
/// <summary> /// Handles a request for public key from the server /// </summary> /// <param name="sender">Send of this event, unused.</param> /// <param name="eventArgs">Arguments describing this event, unused.</param> private void HandlePublicKeyRequestReceived(object sender, RemoteDataEventArgs <string> eventArgs) { if (SessionDataStructureHandler.StateMachine.State == RemoteSessionState.Established) { RemoteSessionStateMachineEventArgs args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyRequested); SessionDataStructureHandler.StateMachine.RaiseEvent(args); StartKeyExchange(); } }
private void ProcessSessionMessages(RemoteDataEventArgs arg) { if ((arg == null) || (arg.ReceivedData == null)) { throw PSTraceSource.NewArgumentNullException("arg"); } RemoteDataObject <PSObject> receivedData = arg.ReceivedData; RemotingTargetInterface targetInterface = receivedData.TargetInterface; RemotingDataType dataType = receivedData.DataType; switch (dataType) { case RemotingDataType.SessionCapability: { RemoteSessionCapability remoteSessionCapability = null; try { remoteSessionCapability = RemotingDecoder.GetSessionCapability(receivedData.Data); } catch (PSRemotingDataStructureException exception2) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ClientNotFoundCapabilityProperties, new object[] { exception2.Message, PSVersionInfo.BuildVersion, RemotingConstants.ProtocolVersion }); } RemoteSessionStateMachineEventArgs args2 = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationReceived) { RemoteSessionCapability = remoteSessionCapability }; this._stateMachine.RaiseEvent(args2, false); RemoteSessionNegotiationEventArgs eventArgs = new RemoteSessionNegotiationEventArgs(remoteSessionCapability); this.NegotiationReceived.SafeInvoke <RemoteSessionNegotiationEventArgs>(this, eventArgs); return; } case RemotingDataType.CloseSession: { PSRemotingDataStructureException reason = new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerRequestedToCloseSession); RemoteSessionStateMachineEventArgs args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.Close, reason); this._stateMachine.RaiseEvent(args, false); return; } case RemotingDataType.EncryptedSessionKey: { string encryptedSessionKey = RemotingDecoder.GetEncryptedSessionKey(receivedData.Data); this.EncryptedSessionKeyReceived.SafeInvoke <RemoteDataEventArgs <string> >(this, new RemoteDataEventArgs <string>(encryptedSessionKey)); return; } case RemotingDataType.PublicKeyRequest: this.PublicKeyRequestReceived.SafeInvoke <RemoteDataEventArgs <string> >(this, new RemoteDataEventArgs <string>(string.Empty)); return; } throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ReceivedUnsupportedAction, new object[] { dataType }); }
private void HandlePublicKeyReceived(object sender, RemoteDataEventArgs <string> eventArgs) { if (this.SessionDataStructureHandler.StateMachine.State != RemoteSessionState.Established && this.SessionDataStructureHandler.StateMachine.State != RemoteSessionState.EstablishedAndKeyRequested) { return; } if (!this._cryptoHelper.ImportRemotePublicKey(eventArgs.Data)) { this.SessionDataStructureHandler.StateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed)); } this.SessionDataStructureHandler.StateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived)); }
private void HandleSessionClosed(object sender, RemoteDataEventArgs <Exception> eventArgs) { RunspacePoolState state; RunspacePoolStateInfo info; if (eventArgs.Data != null) { this.closingReason = eventArgs.Data; } lock (base.syncObject) { state = base.stateInfo.State; switch (state) { case RunspacePoolState.Opening: case RunspacePoolState.Opened: case RunspacePoolState.Disconnecting: case RunspacePoolState.Disconnected: case RunspacePoolState.Connecting: this.SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Broken, this.closingReason)); break; case RunspacePoolState.Closing: this.SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Closed, this.closingReason)); break; } info = new RunspacePoolStateInfo(base.stateInfo.State, base.stateInfo.Reason); } try { base.RaiseStateChangeEvent(info); } catch (Exception exception) { CommandProcessorBase.CheckForSevereException(exception); } switch (state) { case RunspacePoolState.Disconnecting: case RunspacePoolState.Disconnected: this.SetDisconnectAsCompleted(); break; default: if (state == RunspacePoolState.Connecting) { this.SetReconnectAsCompleted(); } break; } this.SetCloseAsCompleted(); }
private void HandleURIDirectionReported(object sender, RemoteDataEventArgs <Uri> eventArgs) { if (!(this.connectionInfo is WSManConnectionInfo connectionInfo)) { return; } connectionInfo.SetConnectionUri(eventArgs.Data); if (this.URIRedirectionReported == null) { return; } this.URIRedirectionReported((object)this, eventArgs); }
/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> internal static void ExitHandler(object sender, RemoteDataEventArgs <RemoteHostCall> eventArgs) { RemoteHostCall hostcall = eventArgs.Data; if (hostcall.IsSetShouldExitOrPopRunspace) { return; } // use the method from the RemotePowerShell to indeed execute this call ClientRemotePowerShell remotePowerShell = (ClientRemotePowerShell)sender; remotePowerShell.ExecuteHostCall(hostcall); }
private void HandleBrokenNotificationFromRunspacePool(object sender, RemoteDataEventArgs <Exception> eventArgs) { this.UnblockCollections(); this.dataStructureHandler.RaiseRemoveAssociationEvent(); if (this.stopCalled) { this.stopCalled = false; this.SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Stopped, eventArgs.Data)); } else { this.SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Failed, eventArgs.Data)); } }
private void HandleOutputReceived(object sender, RemoteDataEventArgs <object> eventArgs) { using (tracer.TraceEventHandlers()) { object data = eventArgs.Data; try { this.outputstream.Write(data); } catch (PSInvalidCastException exception) { this.shell.SetStateChanged(new PSInvocationStateInfo(PSInvocationState.Failed, exception)); } } }
private void HandleEncryptedSessionKeyReceived( object sender, RemoteDataEventArgs <string> eventArgs) { if (this.SessionDataStructureHandler.StateMachine.State != RemoteSessionState.EstablishedAndKeySent) { return; } if (!this._cryptoHelper.ImportEncryptedSessionKey(eventArgs.Data)) { this.SessionDataStructureHandler.StateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed)); } this.CompleteKeyExchange(); this.SessionDataStructureHandler.StateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived)); }
private void HandleCreateRunspacePool(object sender, RemoteDataEventArgs createRunspaceEventArg) { using (ServerRemoteSession._trace.TraceMethod()) { RemoteDataObject <PSObject> remoteDataObject = createRunspaceEventArg != null ? createRunspaceEventArg.ReceivedData : throw ServerRemoteSession._trace.NewArgumentNullException(nameof(createRunspaceEventArg)); if (this._context != null) { this._senderInfo.ClientTimeZone = this._context.ClientCapability.TimeZone; } this._senderInfo.ApplicationArguments = RemotingDecoder.GetApplicationArguments(remoteDataObject.Data); ConfigurationDataFromXML configData = PSSessionConfiguration.LoadEndPointConfiguration(this._configProviderId, this._initParameters); configData.InitializationScriptForOutOfProcessRunspace = this._initScriptForOutOfProcRS; this.maxRecvdObjectSize = configData.MaxReceivedObjectSizeMB; this.maxRecvdDataSizeCommand = configData.MaxReceivedCommandSizeMB; this._sessionConfigProvider = configData.CreateEndPointConfigurationInstance(); PSPrimitiveDictionary applicationPrivateData = this._sessionConfigProvider.GetApplicationPrivateData(this._senderInfo); InitialSessionState initialSessionState = this._sessionConfigProvider.GetInitialSessionState(this._senderInfo); if (initialSessionState == null) { throw ServerRemoteSession._trace.NewInvalidOperationException("RemotingErrorIdStrings", "InitialSessionStateNull", (object)this._configProviderId); } initialSessionState.ThrowOnRunspaceOpenError = true; initialSessionState.Variables.Add(new SessionStateVariableEntry("PSSenderInfo", (object)this._senderInfo, PSRemotingErrorInvariants.FormatResourceString(PSRemotingErrorId.PSSenderInfoDescription), ScopedItemOptions.ReadOnly)); if (!string.IsNullOrEmpty(configData.EndPointConfigurationTypeName)) { this.maxRecvdObjectSize = this._sessionConfigProvider.GetMaximumReceivedObjectSize(this._senderInfo); this.maxRecvdDataSizeCommand = this._sessionConfigProvider.GetMaximumReceivedDataSizePerCommand(this._senderInfo); } this._sessionDSHandler.TransportManager.ReceivedDataCollection.MaximumReceivedObjectSize = this.maxRecvdObjectSize; Guid runspacePoolId = remoteDataObject.RunspacePoolId; int minRunspaces = RemotingDecoder.GetMinRunspaces(remoteDataObject.Data); int maxRunspaces = RemotingDecoder.GetMaxRunspaces(remoteDataObject.Data); PSThreadOptions threadOptions = RemotingDecoder.GetThreadOptions(remoteDataObject.Data); ApartmentState apartmentState = RemotingDecoder.GetApartmentState((object)remoteDataObject.Data); HostInfo hostInfo = RemotingDecoder.GetHostInfo(remoteDataObject.Data); if (this._runspacePoolDriver != null) { throw new PSRemotingDataStructureException(PSRemotingErrorId.RunspaceAlreadyExists, new object[1] { (object)this._runspacePoolDriver.InstanceId }); } bool isAdministrator = this._senderInfo.UserInfo.IsInRole(WindowsBuiltInRole.Administrator); this._runspacePoolDriver = new ServerRunspacePoolDriver(runspacePoolId, minRunspaces, maxRunspaces, threadOptions, apartmentState, hostInfo, initialSessionState, applicationPrivateData, configData, this.SessionDataStructureHandler.TransportManager, isAdministrator, this._context.ServerCapability); this._runspacePoolDriver.Closed += new EventHandler <EventArgs>(this.HandleResourceClosing); this._runspacePoolDriver.Start(); } }
/// <summary> /// Handler for handling any informational message received /// from the server side. /// </summary> /// <param name="sender">sender of this event, unused.</param> /// <param name="eventArgs">arguments describing this event.</param> private void HandleInformationalMessageReceived(object sender, RemoteDataEventArgs <InformationalMessage> eventArgs) { using (s_tracer.TraceEventHandlers()) { InformationalMessage infoMessage = eventArgs.Data; switch (infoMessage.DataType) { case RemotingDataType.PowerShellDebug: { informationalBuffers.AddDebug((DebugRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellVerbose: { informationalBuffers.AddVerbose((VerboseRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellWarning: { informationalBuffers.AddWarning((WarningRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellProgress: { ProgressRecord progress = (ProgressRecord)LanguagePrimitives.ConvertTo(infoMessage.Message, typeof(ProgressRecord), System.Globalization.CultureInfo.InvariantCulture); informationalBuffers.AddProgress(progress); } break; case RemotingDataType.PowerShellInformationStream: { informationalBuffers.AddInformation((InformationRecord)infoMessage.Message); } break; } } }
private void HandlePublicKeyReceived(object sender, RemoteDataEventArgs <string> eventArgs) { if (((this.SessionDataStructureHandler.StateMachine.State == RemoteSessionState.Established) || (this.SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeyRequested)) || (this.SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeyExchanged)) { string data = eventArgs.Data; bool flag = this._cryptoHelper.ImportRemotePublicKey(data); RemoteSessionStateMachineEventArgs fsmEventArg = null; if (!flag) { fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed); this.SessionDataStructureHandler.StateMachine.RaiseEvent(fsmEventArg); } fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived); this.SessionDataStructureHandler.StateMachine.RaiseEvent(fsmEventArg); } }
private void HandleEncryptedSessionKeyReceived(object sender, RemoteDataEventArgs <string> eventArgs) { if (base.SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeySent) { string data = eventArgs.Data; bool flag = this._cryptoHelper.ImportEncryptedSessionKey(data); RemoteSessionStateMachineEventArgs arg = null; if (!flag) { arg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed); base.SessionDataStructureHandler.StateMachine.RaiseEvent(arg, false); } this.CompleteKeyExchange(); arg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived); base.SessionDataStructureHandler.StateMachine.RaiseEvent(arg, false); } }
/// <summary> /// When a response to a SetMaxRunspaces or SetMinRunspaces is received, /// from the server, this method sets the response and thereby unblocks /// corresponding call /// </summary> /// <param name="sender">sender of this message, unused</param> /// <param name="eventArgs">contains response and call id</param> private void HandleResponseReceived(object sender, RemoteDataEventArgs<PSObject> eventArgs) { PSObject data = eventArgs.Data; object response = RemotingDecoder.GetPropertyValue<object>(data, RemoteDataNameStrings.RunspacePoolOperationResponse); long callId = RemotingDecoder.GetPropertyValue<long>(data, RemoteDataNameStrings.CallId); DispatchTable.SetResponse(callId, response); }
/// <summary> /// When the client remote session reports a URI redirection, this method will report the /// message to the user as a Warning using Host method calls. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void HandleURIDirectionReported(object sender, RemoteDataEventArgs<Uri> eventArgs) { WSManConnectionInfo wsmanConnectionInfo = _connectionInfo as WSManConnectionInfo; if (null != wsmanConnectionInfo) { wsmanConnectionInfo.ConnectionUri = eventArgs.Data; URIRedirectionReported.SafeInvoke(this, eventArgs); } }
/// <summary> /// This method is used by the input queue dispatching mechanism. /// It examines the data and takes appropriate actions. /// </summary> /// <param name="dataArg"> /// The received client data. /// </param> /// /// <exception cref="ArgumentNullException"> /// If the parameter is null. /// </exception> internal override void RaiseDataReceivedEvent(RemoteDataEventArgs dataArg) { if (dataArg == null) { throw PSTraceSource.NewArgumentNullException("dataArg"); } RemoteDataObject<PSObject> rcvdData = dataArg.ReceivedData; RemotingTargetInterface targetInterface = rcvdData.TargetInterface; RemotingDataType dataType = rcvdData.DataType; Dbg.Assert(targetInterface == RemotingTargetInterface.Session, "targetInterface must be Session"); switch (dataType) { case RemotingDataType.CreateRunspacePool: { // At this point, the negotiation is complete, so // need to import the clients public key CreateRunspacePoolReceived.SafeInvoke(this, dataArg); } break; case RemotingDataType.CloseSession: PSRemotingDataStructureException reasonOfClose = new PSRemotingDataStructureException(RemotingErrorIdStrings.ClientRequestedToCloseSession); RemoteSessionStateMachineEventArgs closeSessionArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.Close, reasonOfClose); _stateMachine.RaiseEvent(closeSessionArg); break; case RemotingDataType.SessionCapability: RemoteSessionCapability capability = null; try { capability = RemotingDecoder.GetSessionCapability(rcvdData.Data); } catch (PSRemotingDataStructureException dse) { // this will happen if expected properties are not // received for session capability throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerNotFoundCapabilityProperties, dse.Message, PSVersionInfo.BuildVersion, RemotingConstants.ProtocolVersion); } RemoteSessionStateMachineEventArgs capabilityArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationReceived); capabilityArg.RemoteSessionCapability = capability; _stateMachine.RaiseEvent(capabilityArg); if (NegotiationReceived != null) { RemoteSessionNegotiationEventArgs negotiationArg = new RemoteSessionNegotiationEventArgs(capability); negotiationArg.RemoteData = rcvdData; NegotiationReceived.SafeInvoke(this, negotiationArg); } break; case RemotingDataType.PublicKey: { string remotePublicKey = RemotingDecoder.GetPublicKey(rcvdData.Data); PublicKeyReceived.SafeInvoke(this, new RemoteDataEventArgs<string>(remotePublicKey)); } break; default: throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ReceivedUnsupportedAction, dataType); } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void HandleHostCall(object sender, RemoteDataEventArgs<RemoteHostCall> eventArgs) { System.Management.Automation.Runspaces.Internal.ClientRemotePowerShell.ExitHandler(sender, eventArgs); }
// TODO: If this is not used remove this // internal override event EventHandler<RemoteDataEventArgs> DataReceived; /// <summary> /// This processes the object received from transport which are /// targeted for session /// </summary> /// <param name="arg"> /// argument contains the data object /// </param> private void ProcessSessionMessages(RemoteDataEventArgs arg) { if (arg == null || arg.ReceivedData == null) { throw PSTraceSource.NewArgumentNullException("arg"); } RemoteDataObject<PSObject> rcvdData = arg.ReceivedData; RemotingTargetInterface targetInterface = rcvdData.TargetInterface; Dbg.Assert(targetInterface == RemotingTargetInterface.Session, "targetInterface must be Session"); RemotingDataType dataType = rcvdData.DataType; switch (dataType) { case RemotingDataType.CloseSession: PSRemotingDataStructureException reasonOfClose = new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerRequestedToCloseSession); RemoteSessionStateMachineEventArgs closeSessionArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.Close, reasonOfClose); _stateMachine.RaiseEvent(closeSessionArg); break; case RemotingDataType.SessionCapability: RemoteSessionCapability capability = null; try { capability = RemotingDecoder.GetSessionCapability(rcvdData.Data); } catch (PSRemotingDataStructureException dse) { // this will happen if expected properties are not // received for session capability throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ClientNotFoundCapabilityProperties, dse.Message, PSVersionInfo.BuildVersion, RemotingConstants.ProtocolVersion); } RemoteSessionStateMachineEventArgs capabilityArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationReceived); capabilityArg.RemoteSessionCapability = capability; _stateMachine.RaiseEvent(capabilityArg); RemoteSessionNegotiationEventArgs negotiationArg = new RemoteSessionNegotiationEventArgs(capability); NegotiationReceived.SafeInvoke(this, negotiationArg); break; case RemotingDataType.EncryptedSessionKey: { String encryptedSessionKey = RemotingDecoder.GetEncryptedSessionKey(rcvdData.Data); EncryptedSessionKeyReceived.SafeInvoke(this, new RemoteDataEventArgs<string>(encryptedSessionKey)); } break; case RemotingDataType.PublicKeyRequest: { PublicKeyRequestReceived.SafeInvoke(this, new RemoteDataEventArgs<string>(String.Empty)); } break; default: { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ReceivedUnsupportedAction, dataType); } } }
private void HandleSessionDisconnected(object sender, RemoteDataEventArgs<Exception> eventArgs) { bool stateChange = false; lock (this.syncObject) { if (stateInfo.State == RunspacePoolState.Disconnecting) { UpdateDisconnectedExpiresOn(); SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Disconnected, eventArgs.Data)); stateChange = true; } // Set boolean indicating this object has previous connection state and so // can be reconnected as opposed to the alternative where the connection // state has to be reconstructed then connected. _canReconnect = true; } // Do state change work outside of lock. if (stateChange) { RaiseStateChangeEvent(this.stateInfo); SetDisconnectAsCompleted(); } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void HandleCloseNotificationFromRunspacePool(object sender, RemoteDataEventArgs<Exception> eventArgs) { // RunspacePool is closed...so going to set the state of PowerShell // to stopped here. // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); // Since this is a terminal state..close the transport manager. dataStructureHandler.RaiseRemoveAssociationEvent(); // RunspacePool is closed...so going to set the state of PowerShell // to stopped here. SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Stopped, eventArgs.Data)); // Not calling dataStructureHandler.CloseConnection() as this must // have already been called by RunspacePool.Close() }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="createRunspaceEventArg"></param> /// <exception cref="InvalidOperationException"> /// 1. InitialSessionState cannot be null. /// 2. Non existent InitialSessionState provider for the shellID /// </exception> private void HandleCreateRunspacePool(object sender, RemoteDataEventArgs createRunspaceEventArg) { if (createRunspaceEventArg == null) { throw PSTraceSource.NewArgumentNullException("createRunspaceEventArg"); } RemoteDataObject<PSObject> rcvdData = createRunspaceEventArg.ReceivedData; Dbg.Assert(rcvdData != null, "rcvdData must be non-null"); // set the PSSenderInfo sent in the first packets // This is used by the initial session state configuration providers like Exchange. if (Context != null) { #if !CORECLR // TimeZone Not In CoreCLR _senderInfo.ClientTimeZone = Context.ClientCapability.TimeZone; #endif } _senderInfo.ApplicationArguments = RemotingDecoder.GetApplicationArguments(rcvdData.Data); // Get Initial Session State from custom session config suppliers // like Exchange. ConfigurationDataFromXML configurationData = PSSessionConfiguration.LoadEndPointConfiguration(_configProviderId, _initParameters); // used by Out-Of-Proc (IPC) runspace. configurationData.InitializationScriptForOutOfProcessRunspace = _initScriptForOutOfProcRS; // start with data from configuration XML and then override with data // from EndPointConfiguration type. _maxRecvdObjectSize = configurationData.MaxReceivedObjectSizeMB; _maxRecvdDataSizeCommand = configurationData.MaxReceivedCommandSizeMB; DISCPowerShellConfiguration discProvider = null; if (String.IsNullOrEmpty(configurationData.ConfigFilePath)) { _sessionConfigProvider = configurationData.CreateEndPointConfigurationInstance(); } else { System.Security.Principal.WindowsPrincipal windowsPrincipal = new System.Security.Principal.WindowsPrincipal(_senderInfo.UserInfo.WindowsIdentity); Func<string, bool> validator = (role) => windowsPrincipal.IsInRole(role); discProvider = new DISCPowerShellConfiguration(configurationData.ConfigFilePath, validator); _sessionConfigProvider = discProvider; } // exchange of ApplicationArguments and ApplicationPrivateData is be done as early as possible // (i.e. to let the _sessionConfigProvider bail out if it can't comply with client's versioning request) PSPrimitiveDictionary applicationPrivateData = _sessionConfigProvider.GetApplicationPrivateData(_senderInfo); InitialSessionState rsSessionStateToUse = null; if (configurationData.SessionConfigurationData != null) { try { rsSessionStateToUse = _sessionConfigProvider.GetInitialSessionState(configurationData.SessionConfigurationData, _senderInfo, _configProviderId); } catch (NotImplementedException) { rsSessionStateToUse = _sessionConfigProvider.GetInitialSessionState(_senderInfo); } } else { rsSessionStateToUse = _sessionConfigProvider.GetInitialSessionState(_senderInfo); } if (null == rsSessionStateToUse) { throw PSTraceSource.NewInvalidOperationException(RemotingErrorIdStrings.InitialSessionStateNull, _configProviderId); } rsSessionStateToUse.ThrowOnRunspaceOpenError = true; // this might throw if the sender info is already present rsSessionStateToUse.Variables.Add( new SessionStateVariableEntry(RemoteDataNameStrings.SenderInfoPreferenceVariable, _senderInfo, Remoting.PSRemotingErrorInvariants.FormatResourceString( RemotingErrorIdStrings.PSSenderInfoDescription), ScopedItemOptions.ReadOnly)); // check if the current scenario is Win7(client) to Win8(server). Add back the PSv2 version TabExpansion // function if necessary. Version psClientVersion = null; if (_senderInfo.ApplicationArguments != null && _senderInfo.ApplicationArguments.ContainsKey("PSversionTable")) { var value = PSObject.Base(_senderInfo.ApplicationArguments["PSversionTable"]) as PSPrimitiveDictionary; if (value != null) { if (value.ContainsKey("WSManStackVersion")) { var wsmanStackVersion = PSObject.Base(value["WSManStackVersion"]) as Version; if (wsmanStackVersion != null && wsmanStackVersion.Major < 3) { // The client side is PSv2. This is the Win7 to Win8 scenario. We need to add the PSv2 // TabExpansion function back in to keep the tab expansion functionable on the client side. rsSessionStateToUse.Commands.Add( new SessionStateFunctionEntry( RemoteDataNameStrings.PSv2TabExpansionFunction, RemoteDataNameStrings.PSv2TabExpansionFunctionText)); } } if (value.ContainsKey("PSVersion")) { psClientVersion = PSObject.Base(value["PSVersion"]) as Version; } } } if (!string.IsNullOrEmpty(configurationData.EndPointConfigurationTypeName)) { // user specified a type to load for configuration..use the values from this type. _maxRecvdObjectSize = _sessionConfigProvider.GetMaximumReceivedObjectSize(_senderInfo); _maxRecvdDataSizeCommand = _sessionConfigProvider.GetMaximumReceivedDataSizePerCommand(_senderInfo); } SessionDataStructureHandler.TransportManager.ReceivedDataCollection.MaximumReceivedObjectSize = _maxRecvdObjectSize; // MaximumReceivedDataSize is not set for session transport manager...see the constructor // for more info. Guid clientRunspacePoolId = rcvdData.RunspacePoolId; int minRunspaces = RemotingDecoder.GetMinRunspaces(rcvdData.Data); int maxRunspaces = RemotingDecoder.GetMaxRunspaces(rcvdData.Data); PSThreadOptions threadOptions = RemotingDecoder.GetThreadOptions(rcvdData.Data); #if !CORECLR // No ApartmentState In CoreCLR ApartmentState apartmentState = RemotingDecoder.GetApartmentState(rcvdData.Data); #endif HostInfo hostInfo = RemotingDecoder.GetHostInfo(rcvdData.Data); if (_runspacePoolDriver != null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.RunspaceAlreadyExists, _runspacePoolDriver.InstanceId); } #if !UNIX bool isAdministrator = _senderInfo.UserInfo.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator); #else bool isAdministrator = false; #endif ServerRunspacePoolDriver tmpDriver = new ServerRunspacePoolDriver( clientRunspacePoolId, minRunspaces, maxRunspaces, threadOptions, #if !CORECLR // No ApartmentState In CoreCLR apartmentState, #endif hostInfo, rsSessionStateToUse, applicationPrivateData, configurationData, this.SessionDataStructureHandler.TransportManager, isAdministrator, Context.ServerCapability, psClientVersion, _configurationName); // attach the necessary event handlers and start the driver. Interlocked.Exchange(ref _runspacePoolDriver, tmpDriver); _runspacePoolDriver.Closed += HandleResourceClosing; _runspacePoolDriver.Start(); }
private void HandleSessionReconnected(object sender, RemoteDataEventArgs<Exception> eventArgs) { bool stateChange = false; lock (this.syncObject) { if (stateInfo.State == RunspacePoolState.Connecting) { ResetDisconnectedOnExpiresOn(); SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Opened, null)); stateChange = true; } } // Do state change work outside of lock. if (stateChange) { RaiseStateChangeEvent(this.stateInfo); SetReconnectAsCompleted(); } }
/// <summary> /// The session is closing set the state and reason accordingly /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleSessionClosing(object sender, RemoteDataEventArgs<Exception> eventArgs) { // just capture the reason for closing here..handle the session closed event // to change state appropriately. _closingReason = eventArgs.Data; }
/// <summary> /// The session closed, set the state and reason accordingly /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleSessionClosed(object sender, RemoteDataEventArgs<Exception> eventArgs) { if (eventArgs.Data != null) { _closingReason = eventArgs.Data; } // Set state under lock. RunspacePoolState prevState; RunspacePoolStateInfo finishedStateInfo; lock (syncObject) { prevState = stateInfo.State; switch (prevState) { case RunspacePoolState.Opening: case RunspacePoolState.Opened: case RunspacePoolState.Disconnecting: case RunspacePoolState.Disconnected: case RunspacePoolState.Connecting: // Since RunspacePool is not in closing state, this close is // happening because of data structure handler error. Set the state to broken. SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Broken, _closingReason)); break; case RunspacePoolState.Closing: SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Closed, _closingReason)); break; } finishedStateInfo = new RunspacePoolStateInfo(stateInfo.State, stateInfo.Reason); } // Raise notification event outside of lock. try { RaiseStateChangeEvent(finishedStateInfo); } catch (Exception e) { // Don't throw exception on notification thread. CommandProcessor.CheckForSevereException(e); } // Check if we have either an existing disconnect or connect async object // and if so make sure they are set to completed since this is a // final state for the runspace pool. SetDisconnectAsCompleted(); SetReconnectAsCompleted(); // Ensure an existing Close async object is completed. SetCloseAsCompleted(); }
/// <summary> /// Handles an encrypted session key received from the other side /// </summary> /// <param name="sender">sender of this event</param> /// <param name="eventArgs">arguments that contain the remote /// public key</param> private void HandleEncryptedSessionKeyReceived(object sender, RemoteDataEventArgs<string> eventArgs) { if (SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeySent) { string encryptedSessionKey = eventArgs.Data; bool ret = _cryptoHelper.ImportEncryptedSessionKey(encryptedSessionKey); RemoteSessionStateMachineEventArgs args = null; if (!ret) { // importing remote public key failed // set state to closed args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } // complete the key exchange process CompleteKeyExchange(); args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void HandleHostCallReceived(object sender, RemoteDataEventArgs<RemoteHostCall> eventArgs) { using (s_tracer.TraceEventHandlers()) { Collection<RemoteHostCall> prerequisiteCalls = eventArgs.Data.PerformSecurityChecksOnHostMessage(computerName); if (HostCallReceived != null) { // raise events for all prerequisite calls if (prerequisiteCalls.Count > 0) { foreach (RemoteHostCall hostcall in prerequisiteCalls) { RemoteDataEventArgs<RemoteHostCall> args = new RemoteDataEventArgs<RemoteHostCall>(hostcall); HostCallReceived.SafeInvoke(this, args); } } HostCallReceived.SafeInvoke(this, eventArgs); } else { // execute any prerequisite calls before // executing this host call if (prerequisiteCalls.Count > 0) { foreach (RemoteHostCall hostcall in prerequisiteCalls) { ExecuteHostCall(hostcall); } } ExecuteHostCall(eventArgs.Data); } } }
/// <summary> /// The server sent application private data. Store the data so that user /// can get it later. /// </summary> /// <param name="eventArgs">argument describing this event</param> /// <param name="sender">sender of this event</param> internal void HandleApplicationPrivateDataReceived(object sender, RemoteDataEventArgs<PSPrimitiveDictionary> eventArgs) { this.SetApplicationPrivateData(eventArgs.Data); }
/// <summary> /// Handler for ConnectCompleted and ReconnectCompleted events from the /// PSRP layer. /// </summary> /// <param name="sender">Sender of this event, unused.</param> /// <param name="e">Event arguments.</param> private void HandleConnectCompleted(object sender, RemoteDataEventArgs<Exception> e) { // After initial connect/reconnect set state to "Running". Later events // will update state to appropriate command execution state. SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Running, null)); }
/// <summary> /// Have received a public key from the other side /// Import or take other action based on the state /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">event arguments which contains the /// remote public key</param> private void HandlePublicKeyReceived(object sender, RemoteDataEventArgs<string> eventArgs) { if (SessionDataStructureHandler.StateMachine.State == RemoteSessionState.Established || SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeyRequested || //this is only for legacy clients SessionDataStructureHandler.StateMachine.State == RemoteSessionState.EstablishedAndKeyExchanged) { string remotePublicKey = eventArgs.Data; bool ret = _cryptoHelper.ImportRemotePublicKey(remotePublicKey); RemoteSessionStateMachineEventArgs args = null; if (!ret) { // importing remote public key failed // set state to closed args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceiveFailed); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyReceived); SessionDataStructureHandler.StateMachine.RaiseEvent(args); } }
/// <summary> /// Handles notification from RunspacePool indicating /// that the pool is broken. This sets the state of /// all the powershell objects associated with the /// runspace pool to Failed /// </summary> /// <param name="sender">sender of this information, unused</param> /// <param name="eventArgs">arguments describing this event /// contains information on the reason associated with the /// runspace pool entering a Broken state</param> private void HandleBrokenNotificationFromRunspacePool(object sender, RemoteDataEventArgs<Exception> eventArgs) { // RunspacePool is closed...so going to set the state of PowerShell // to stopped here. // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); // Since this is a terminal state..close the transport manager. dataStructureHandler.RaiseRemoveAssociationEvent(); if (stopCalled) { // Reset stop called flag. stopCalled = false; // if a Stop method has been called, then powershell // would have already raised a Stopping event, after // which only a Stopped should be raised SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Stopped, eventArgs.Data)); } else { SetStateInfo(new PSInvocationStateInfo(PSInvocationState.Failed, eventArgs.Data)); } // Not calling dataStructureHandler.CloseConnection() as this must // have already been called by RunspacePool.Close() }
/// <summary> /// When the server sends a PSEventArgs this method will add it to the local event queue /// </summary> private void HandlePSEventArgsReceived(object sender, RemoteDataEventArgs<PSEventArgs> e) { OnForwardEvent(e.Data); }
internal void HandleInitInfoReceived(object sender, RemoteDataEventArgs<RunspacePoolInitInfo> eventArgs) { RunspacePoolStateInfo info = new RunspacePoolStateInfo(RunspacePoolState.Opened, null); bool raiseEvents = false; lock (syncObject) { minPoolSz = eventArgs.Data.MinRunspaces; maxPoolSz = eventArgs.Data.MaxRunspaces; if (stateInfo.State == RunspacePoolState.Connecting) { ResetDisconnectedOnExpiresOn(); raiseEvents = true; SetRunspacePoolState(info); } } if (raiseEvents) { // Private application data is sent after (post) connect. We need // to wait for application data before raising the state change // Connecting -> Opened event. ThreadPool.QueueUserWorkItem(WaitAndRaiseConnectEventsProc, info); } }
/// <summary> /// An error record is received from the powershell at the /// server side. It is added to the error collection of the /// client powershell /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleErrorReceived(object sender, RemoteDataEventArgs<ErrorRecord> eventArgs) { using (s_tracer.TraceEventHandlers()) { shell.SetHadErrors(true); errorstream.Write(eventArgs.Data); } }
/// <summary> /// This is the data dispatcher for the whole remote connection. /// This dispatcher is registered with the server side input queue's InputDataReady event. /// When the input queue has received data from client, it calls the InputDataReady listeners. /// /// This dispatcher distinguishes the negotiation packet as a special case. For all other data, /// it dispatches the data through Finite State Machines DoMessageReceived handler by raising the event /// MessageReceived. The FSM's DoMessageReceived handler further dispatches to the receiving /// components: such as runspace or pipeline which have their own data dispatching methods. /// </summary> /// <param name="sender"> /// This parameter is not used by the method, in this implementation. /// </param> /// <param name="dataEventArg"> /// This parameter contains the remote data received from client. /// </param> /// /// <exception cref="ArgumentNullException"> /// If the parameter <paramref name="dataEventArg" /> is null. /// </exception> /// /// <exception cref="ArgumentException"> /// If the parameter <paramref name="dataEventArg" /> does not contain remote data. /// </exception> /// /// <exception cref="PSRemotingDataStructureException"> /// If the destination of the data is not for server. /// </exception> internal void DispatchInputQueueData(object sender, RemoteDataEventArgs dataEventArg) { if (dataEventArg == null) { throw PSTraceSource.NewArgumentNullException("dataEventArg"); } RemoteDataObject<PSObject> rcvdData = dataEventArg.ReceivedData; if (rcvdData == null) { throw PSTraceSource.NewArgumentException("dataEventArg"); } RemotingDestination destination = rcvdData.Destination; if ((destination & MySelf) != MySelf) { // this packet is not target for me. throw new PSRemotingDataStructureException(RemotingErrorIdStrings.RemotingDestinationNotForMe, MySelf, destination); } RemotingTargetInterface targetInterface = rcvdData.TargetInterface; RemotingDataType dataType = rcvdData.DataType; RemoteSessionStateMachineEventArgs messageReceivedArg = null; switch (targetInterface) { case RemotingTargetInterface.Session: { switch (dataType) { // TODO: Directly calling an event handler in StateMachine bypassing the StateMachine's // loop of ProcessEvents()..This is needed as connection is already established and the // following message does not change state. An ideal solution would be to process // non-session messages in this class rather than by StateMachine. case RemotingDataType.CreateRunspacePool: messageReceivedArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived); if (SessionDataStructureHandler.StateMachine.CanByPassRaiseEvent(messageReceivedArg)) { messageReceivedArg.RemoteData = rcvdData; SessionDataStructureHandler.StateMachine.DoMessageReceived(this, messageReceivedArg); } else { SessionDataStructureHandler.StateMachine.RaiseEvent(messageReceivedArg); } break; case RemotingDataType.CloseSession: SessionDataStructureHandler.RaiseDataReceivedEvent(dataEventArg); break; case RemotingDataType.SessionCapability: SessionDataStructureHandler.RaiseDataReceivedEvent(dataEventArg); break; case RemotingDataType.PublicKey: SessionDataStructureHandler.RaiseDataReceivedEvent(dataEventArg); break; default: Dbg.Assert(false, "Should never reach here"); break; } } break; // TODO: Directly calling an event handler in StateMachine bypassing the StateMachine's // loop of ProcessEvents()..This is needed as connection is already established and the // following message does not change state. An ideal solution would be to process // non-session messages in this class rather than by StateMachine. case RemotingTargetInterface.RunspacePool: case RemotingTargetInterface.PowerShell: // GETBACK messageReceivedArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived); if (SessionDataStructureHandler.StateMachine.CanByPassRaiseEvent(messageReceivedArg)) { messageReceivedArg.RemoteData = rcvdData; SessionDataStructureHandler.StateMachine.DoMessageReceived(this, messageReceivedArg); } else { SessionDataStructureHandler.StateMachine.RaiseEvent(messageReceivedArg); } break; } }
/// <summary> /// An output object is received from the powershell at the /// server side. It is added to the output collection of the /// client powershell /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleOutputReceived(object sender, RemoteDataEventArgs<object> eventArgs) { using (s_tracer.TraceEventHandlers()) { object data = eventArgs.Data; try { outputstream.Write(data); } catch (PSInvalidCastException e) { shell.SetStateChanged(new PSInvocationStateInfo(PSInvocationState.Failed, e)); } } }
/// <summary> /// This is the handler for MessageReceived event. It dispatches the data to various components /// that uses the data. /// </summary> /// <param name="sender"></param> /// <param name="fsmEventArg"> /// This parameter contains the FSM event. /// </param> /// /// <exception cref="ArgumentNullException"> /// If the parameter <paramref name="fsmEventArg"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If the parameter <paramref name="fsmEventArg"/> does not contain remote data. /// </exception> internal void DoMessageReceived(object sender, RemoteSessionStateMachineEventArgs fsmEventArg) { using (s_trace.TraceEventHandlers()) { if (fsmEventArg == null) { throw PSTraceSource.NewArgumentNullException("fsmEventArg"); } if (fsmEventArg.RemoteData == null) { throw PSTraceSource.NewArgumentException("fsmEventArg"); } Dbg.Assert(_state == RemoteSessionState.Established || _state == RemoteSessionState.EstablishedAndKeyExchanged || _state == RemoteSessionState.EstablishedAndKeyReceived || _state == RemoteSessionState.EstablishedAndKeySent, //server session will never be in this state.. TODO- remove this "State must be Established or EstablishedAndKeySent or EstablishedAndKeyReceived or EstablishedAndKeyExchanged"); RemotingTargetInterface targetInterface = fsmEventArg.RemoteData.TargetInterface; RemotingDataType dataType = fsmEventArg.RemoteData.DataType; Guid clientRunspacePoolId; ServerRunspacePoolDriver runspacePoolDriver; //string errorMessage = null; RemoteDataEventArgs remoteDataForSessionArg = null; switch (targetInterface) { case RemotingTargetInterface.Session: { switch (dataType) { // GETBACK case RemotingDataType.CreateRunspacePool: remoteDataForSessionArg = new RemoteDataEventArgs(fsmEventArg.RemoteData); _session.SessionDataStructureHandler.RaiseDataReceivedEvent(remoteDataForSessionArg); break; default: Dbg.Assert(false, "Should never reach here"); break; } } break; case RemotingTargetInterface.RunspacePool: // GETBACK clientRunspacePoolId = fsmEventArg.RemoteData.RunspacePoolId; runspacePoolDriver = _session.GetRunspacePoolDriver(clientRunspacePoolId); if (runspacePoolDriver != null) { runspacePoolDriver.DataStructureHandler.ProcessReceivedData(fsmEventArg.RemoteData); } else { s_trace.WriteLine(@"Server received data for Runspace (id: {0}), but the Runspace cannot be found", clientRunspacePoolId); PSRemotingDataStructureException reasonOfFailure = new PSRemotingDataStructureException(RemotingErrorIdStrings.RunspaceCannotBeFound, clientRunspacePoolId); RemoteSessionStateMachineEventArgs runspaceNotFoundArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.FatalError, reasonOfFailure); RaiseEvent(runspaceNotFoundArg); } break; case RemotingTargetInterface.PowerShell: clientRunspacePoolId = fsmEventArg.RemoteData.RunspacePoolId; runspacePoolDriver = _session.GetRunspacePoolDriver(clientRunspacePoolId); runspacePoolDriver.DataStructureHandler.DispatchMessageToPowerShell(fsmEventArg.RemoteData); break; default: s_trace.WriteLine("Server received data unknown targetInterface: {0}", targetInterface); PSRemotingDataStructureException reasonOfFailure2 = new PSRemotingDataStructureException(RemotingErrorIdStrings.ReceivedUnsupportedRemotingTargetInterfaceType, targetInterface); RemoteSessionStateMachineEventArgs unknownTargetArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.FatalError, reasonOfFailure2); RaiseEvent(unknownTargetArg); break; } } }
/// <summary> /// The invocation state of the server powershell has changed. /// The state of the client powershell is reflected accordingly /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleInvocationStateInfoReceived(object sender, RemoteDataEventArgs<PSInvocationStateInfo> eventArgs) { using (s_tracer.TraceEventHandlers()) { PSInvocationStateInfo stateInfo = eventArgs.Data; // we should not receive any transient state from // the server Dbg.Assert(!(stateInfo.State == PSInvocationState.Running || stateInfo.State == PSInvocationState.Stopping), "Transient states should not be received from the server"); if (stateInfo.State == PSInvocationState.Disconnected) { SetStateInfo(stateInfo); } else if (stateInfo.State == PSInvocationState.Stopped || stateInfo.State == PSInvocationState.Failed || stateInfo.State == PSInvocationState.Completed) { // Special case for failure error due to ErrorCode==-2144108453 (no ShellId found). // In this case terminate session since there is no longer a shell to communicate // with. bool terminateSession = false; if (stateInfo.State == PSInvocationState.Failed) { PSRemotingTransportException remotingTransportException = stateInfo.Reason as PSRemotingTransportException; terminateSession = (remotingTransportException != null) && (remotingTransportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_TARGETSESSION_DOESNOTEXIST); } // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); if (stopCalled || terminateSession) { // Reset stop called flag. stopCalled = false; // if a Stop method has been called, then powershell // would have already raised a Stopping event, after // which only a Stopped should be raised _stateInfoQueue.Enqueue(new PSInvocationStateInfo(PSInvocationState.Stopped, stateInfo.Reason)); // If the stop call failed due to network problems then close the runspace // since it is now unusable. CheckAndCloseRunspaceAfterStop(stateInfo.Reason); } else { _stateInfoQueue.Enqueue(stateInfo); } // calling close async only after making sure all the internal members are prepared // to handle close complete. dataStructureHandler.CloseConnectionAsync(null); } } }
/// <summary> /// The state of the server RunspacePool has changed. Handle /// the same and reflect local states accordingly /// </summary> /// <param name="eventArgs">argument describing this event</param> /// <param name="sender">sender of this event</param> internal void HandleStateInfoReceived(object sender, RemoteDataEventArgs<RunspacePoolStateInfo> eventArgs) { RunspacePoolStateInfo newStateInfo = eventArgs.Data; bool raiseEvents = false; Dbg.Assert(newStateInfo != null, "state information should not be null"); if (newStateInfo.State == RunspacePoolState.Opened) { lock (syncObject) { if (stateInfo.State == RunspacePoolState.Opening) { SetRunspacePoolState(newStateInfo); raiseEvents = true; } } if (raiseEvents) { // this needs to be done outside the lock to avoid a // deadlock scenario RaiseStateChangeEvent(stateInfo); SetOpenAsCompleted(); } } else if (newStateInfo.State == RunspacePoolState.Closed || newStateInfo.State == RunspacePoolState.Broken) { bool doClose = false; lock (syncObject) { if (stateInfo.State == RunspacePoolState.Closed || stateInfo.State == RunspacePoolState.Broken) { // there is nothing to do here return; } if (stateInfo.State == RunspacePoolState.Opening || stateInfo.State == RunspacePoolState.Opened || stateInfo.State == RunspacePoolState.Closing) { doClose = true; SetRunspacePoolState(newStateInfo); } } if (doClose) { // if closeAsyncResult is null, BeginClose is not called. That means // we are getting close event from server, in this case release the // local resources if (null == _closeAsyncResult) { // Close the local resources. DataStructureHandler.CloseRunspacePoolAsync(); } // Delay notifying upper layers of finished state change event // until after transport close ack is received (HandleSessionClosed handler). } } // else if ... }
/// <summary> /// Handler for handling any informational message received /// from the server side. /// </summary> /// <param name="sender">sender of this event, unused</param> /// <param name="eventArgs">arguments describing this event</param> private void HandleInformationalMessageReceived(object sender, RemoteDataEventArgs<InformationalMessage> eventArgs) { using (s_tracer.TraceEventHandlers()) { InformationalMessage infoMessage = eventArgs.Data; switch (infoMessage.DataType) { case RemotingDataType.PowerShellDebug: { informationalBuffers.AddDebug((DebugRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellVerbose: { informationalBuffers.AddVerbose((VerboseRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellWarning: { informationalBuffers.AddWarning((WarningRecord)infoMessage.Message); } break; case RemotingDataType.PowerShellProgress: { ProgressRecord progress = (ProgressRecord)LanguagePrimitives.ConvertTo(infoMessage.Message, typeof(ProgressRecord), System.Globalization.CultureInfo.InvariantCulture); informationalBuffers.AddProgress(progress); } break; case RemotingDataType.PowerShellInformationStream: { informationalBuffers.AddInformation((InformationRecord)infoMessage.Message); } break; } } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> internal static void ExitHandler(object sender, RemoteDataEventArgs<RemoteHostCall> eventArgs) { RemoteHostCall hostcall = eventArgs.Data; if (hostcall.IsSetShouldExitOrPopRunspace) { return; } // use the method from the RemotePowerShell to indeed execute this call ClientRemotePowerShell remotePowerShell = (ClientRemotePowerShell)sender; remotePowerShell.ExecuteHostCall(hostcall); }
/// <summary> /// Handles a request for public key from the server /// </summary> /// <param name="sender">send of this event, unused</param> /// <param name="eventArgs">arguments describing this event, unused</param> private void HandlePublicKeyRequestReceived(object sender, RemoteDataEventArgs<string> eventArgs) { if (SessionDataStructureHandler.StateMachine.State == RemoteSessionState.Established) { RemoteSessionStateMachineEventArgs args = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.KeyRequested); SessionDataStructureHandler.StateMachine.RaiseEvent(args); StartKeyExchange(); } }
/// <summary> /// A session disconnect has been initiated by the WinRM robust connection layer. Set /// internal state to Disconnecting. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void HandleSessionRCDisconnecting(object sender, RemoteDataEventArgs<Exception> e) { Dbg.Assert(this.stateInfo.State == RunspacePoolState.Opened, "RC disconnect should only occur for runspace pools in the Opened state."); lock (this.syncObject) { SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Disconnecting, e.Data)); } RaiseStateChangeEvent(this.stateInfo); }
/// <summary> /// A host call has been proxied from the server which needs to /// be executed /// </summary> /// <param name="sender">sender of this event</param> /// <param name="eventArgs">arguments describing this event</param> internal void HandleRemoteHostCalls(object sender, RemoteDataEventArgs<RemoteHostCall> eventArgs) { if (HostCallReceived != null) { HostCallReceived.SafeInvoke(sender, eventArgs); } else { RemoteHostCall hostCall = eventArgs.Data; if (hostCall.IsVoidMethod) { hostCall.ExecuteVoidMethod(host); } else { RemoteHostResponse remoteHostResponse = hostCall.ExecuteNonVoidMethod(host); DataStructureHandler.SendHostResponseToServer(remoteHostResponse); } } }