예제 #1
0
 internal override void SendNegotiationAsync()
 {
     using (ServerRemoteSessionDSHandlerlImpl._trace.TraceMethod())
     {
         RemoteDataObject sessionCapability = RemotingEncoder.GenerateServerSessionCapability(this._session.Context.ServerCapability, Guid.Empty);
         this._stateMachine.RaiseEvent(new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationSendCompleted));
         this._transportManager.SendDataToClient <PSObject>(RemoteDataObject <PSObject> .CreateFrom(sessionCapability.Destination, sessionCapability.DataType, sessionCapability.RunspacePoolId, sessionCapability.PowerShellId, (PSObject)sessionCapability.Data), false);
     }
 }
        internal override void SendNegotiationAsync()
        {
            RemoteDataObject obj2 = RemotingEncoder.GenerateServerSessionCapability(this._session.Context.ServerCapability, Guid.Empty);
            RemoteSessionStateMachineEventArgs fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationSendCompleted);

            this._stateMachine.RaiseEvent(fsmEventArg);
            RemoteDataObject <PSObject> data = RemoteDataObject <PSObject> .CreateFrom(obj2.Destination, obj2.DataType, obj2.RunspacePoolId, obj2.PowerShellId, (PSObject)obj2.Data);

            this._transportManager.SendDataToClient <PSObject>(data, false, false);
        }
예제 #3
0
        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
                    });
                }
            }
        }
예제 #4
0
        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 });
        }
예제 #5
0
        /// <summary>
        /// This processes the object received from transport which are
        /// not targeted for session
        /// </summary>
        /// <param name="rcvdData">
        /// received data.
        /// </param>
        internal void ProcessNonSessionMessages(RemoteDataObject <PSObject> rcvdData)
        {
            // TODO: Consider changing to Dbg.Assert()
            if (rcvdData == null)
            {
                throw PSTraceSource.NewArgumentNullException("rcvdData");
            }

            RemotingTargetInterface targetInterface = rcvdData.TargetInterface;

            Guid clientRunspacePoolId;
            RemoteRunspacePoolInternal runspacePool;

            switch (targetInterface)
            {
            case RemotingTargetInterface.Session:

                Dbg.Assert(false,
                           "The session remote data is handled my session data structure handler, not here");
                break;

            case RemotingTargetInterface.RunspacePool:
                clientRunspacePoolId = rcvdData.RunspacePoolId;
                runspacePool         = _session.GetRunspacePool(clientRunspacePoolId);

                if (runspacePool != null)
                {
                    // GETBACK
                    runspacePool.DataStructureHandler.ProcessReceivedData(rcvdData);
                }
                else
                {
                    // The runspace pool may have been removed on the client side,
                    // so, we should just ignore the message.
                    s_trace.WriteLine(@"Client received data for Runspace (id: {0}),
                            but the Runspace cannot be found", clientRunspacePoolId);
                }

                break;

            case RemotingTargetInterface.PowerShell:
                clientRunspacePoolId = rcvdData.RunspacePoolId;
                runspacePool         = _session.GetRunspacePool(clientRunspacePoolId);

                // GETBACK
                runspacePool.DataStructureHandler.DispatchMessageToPowerShell(rcvdData);
                break;

            default:

                break;
            }
        }
예제 #6
0
 internal void Fragment <T>(RemoteDataObject <T> obj, SerializedDataStream dataToBeSent)
 {
     dataToBeSent.Enter();
     try
     {
         obj.Serialize(dataToBeSent, this);
     }
     finally
     {
         dataToBeSent.Exit();
     }
 }
예제 #7
0
        internal void Execute(Action <ErrorRecord> writeErrorAction)
        {
            if (this._remoteHostCall.IsVoidMethod)
            {
                this.ExecuteVoid(writeErrorAction);
            }
            else
            {
                RemotingDataType            dataType = (this._clientPowerShellId == Guid.Empty) ? RemotingDataType.RemoteRunspaceHostResponseData : RemotingDataType.RemotePowerShellHostResponseData;
                RemoteDataObject <PSObject> data     = RemoteDataObject <PSObject> .CreateFrom(RemotingDestination.InvalidDestination | RemotingDestination.Server, dataType, this._clientRunspacePoolId, this._clientPowerShellId, this._remoteHostCall.ExecuteNonVoidMethod(this._clientHost).Encode());

                this._transportManager.DataToBeSentCollection.Add <PSObject>(data, DataPriorityType.PromptResponse);
            }
        }
예제 #8
0
        internal T ExecuteMethod <T>(RemoteHostMethodId methodId, object[] parameters)
        {
            long newCallId = this._serverDispatchTable.CreateNewCallId();

            this._transportManager.SendDataToClient <PSObject>(RemoteDataObject <PSObject> .CreateFrom(RemotingDestination.Client, this._remoteHostCallDataType, this._clientRunspacePoolId, this._clientPowerShellId, new RemoteHostCall(newCallId, methodId, parameters).Encode()), false);
            RemoteHostResponse response = this._serverDispatchTable.GetResponse(newCallId, (RemoteHostResponse)null);

            if (response == null)
            {
                throw RemoteHostExceptions.NewRemoteHostCallFailedException(methodId);
            }
            response.SimulateExecution();
            return((T)response.SimulateExecution());
        }
예제 #9
0
        /// <summary>
        /// Adds data to this collection. The data is fragmented in this method
        /// before being stored into the collection. So the calling thread
        /// will get affected, if it tries to add a huge object.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data">
        /// data to be added to the collection. Caller should make sure this is not
        /// null.
        /// </param>
        /// <param name="priority">
        /// Priority of the data.
        /// </param>
        internal void Add <T>(RemoteDataObject <T> data, DataPriorityType priority)
        {
            Dbg.Assert(data != null, "Cannot send null data object");
            Dbg.Assert(_fragmentor != null, "Fragmentor cannot be null while adding objects");
            Dbg.Assert(_dataToBeSent != null, "Serialized streams are not initialized");

            // make sure the only one object is fragmented and added to the collection
            // at any give time. This way the order of fragment is maintained
            // in the SendDataCollection(s).
            lock (_dataSyncObjects[(int)priority])
            {
                _fragmentor.Fragment <T>(data, _dataToBeSent[(int)priority]);
            }
        }
예제 #10
0
        /// <summary>
        /// Clubing negotiation packet + runspace creation and then doing transportManager.ConnectAsync().
        /// This will save us 2 network calls by doing all the work in one network call.
        /// </summary>
        private void HandleNegotiationSendingStateChange()
        {
            RemoteSessionCapability clientCapability = _session.Context.ClientCapability;

            Dbg.Assert(clientCapability.RemotingDestination == RemotingDestination.Server, "Expected clientCapability.RemotingDestination == RemotingDestination.Server");

            //Encode and send the negotiation reply
            RemoteDataObject data = RemotingEncoder.GenerateClientSessionCapability(
                clientCapability, _session.RemoteRunspacePoolInternal.InstanceId);
            RemoteDataObject <PSObject> dataAsPSObject = RemoteDataObject <PSObject> .CreateFrom(
                data.Destination, data.DataType, data.RunspacePoolId, data.PowerShellId, (PSObject)data.Data);

            _transportManager.DataToBeSentCollection.Add <PSObject>(dataAsPSObject);
        }
예제 #11
0
        /// <summary>
        /// The method performs the fragmentation operation.
        /// All fragments of the same object have the same ObjectId.
        /// All fragments of the same object have the same ObjectId.
        /// Each fragment has its own Fragment Id. Fragment Id always starts from zero (0),
        /// and increments sequentially with an increment of 1.
        /// The last fragment is indicated by an End of Fragment marker.
        /// </summary>
        /// <param name="obj">
        /// The object to be fragmented. Caller should make sure this is not null.
        /// </param>
        /// <param name="dataToBeSent">
        /// Caller specified dataToStore to which the fragments are added
        /// one-by-one
        /// </param>
        internal void Fragment <T>(RemoteDataObject <T> obj, SerializedDataStream dataToBeSent)
        {
            Dbg.Assert(obj != null, "Cannot fragment a null object");
            Dbg.Assert(dataToBeSent != null, "SendDataCollection cannot be null");

            dataToBeSent.Enter();
            try
            {
                obj.Serialize(dataToBeSent, this);
            }
            finally
            {
                dataToBeSent.Exit();
            }
        }
예제 #12
0
 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();
     }
 }
예제 #13
0
        /// <summary>
        /// This method sends the server side capability negotiation packet to the client.
        /// </summary>
        internal override void SendNegotiationAsync()
        {
            RemoteSessionCapability serverCapability = _session.Context.ServerCapability;
            RemoteDataObject        data             = RemotingEncoder.GenerateServerSessionCapability(serverCapability,
                                                                                                       Guid.Empty);

            RemoteSessionStateMachineEventArgs negotiationSendCompletedArg =
                new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.NegotiationSendCompleted);

            _stateMachine.RaiseEvent(negotiationSendCompletedArg);

            RemoteDataObject <PSObject> dataToBeSent = RemoteDataObject <PSObject> .CreateFrom(
                data.Destination, data.DataType, data.RunspacePoolId, data.PowerShellId, (PSObject)data.Data);

            // send data to client..flush is not true as we expect to send state changed
            // information (from runspace creation)
            _transportManager.SendDataToClient <PSObject>(dataToBeSent, false);
        }
예제 #14
0
        /// <summary>
        /// Execute.
        /// </summary>
        internal void Execute(Action <ErrorRecord> writeErrorAction)
        {
            if (_remoteHostCall.IsVoidMethod)
            {
                ExecuteVoid(writeErrorAction);
            }
            else
            {
                RemotingDataType remotingDataType =
                    _clientPowerShellId == Guid.Empty ? RemotingDataType.RemoteRunspaceHostResponseData : RemotingDataType.RemotePowerShellHostResponseData;

                RemoteHostResponse          remoteHostResponse = _remoteHostCall.ExecuteNonVoidMethod(_clientHost);
                RemoteDataObject <PSObject> dataToBeSent       = RemoteDataObject <PSObject> .CreateFrom(
                    RemotingDestination.Server, remotingDataType, _clientRunspacePoolId,
                    _clientPowerShellId, remoteHostResponse.Encode());

                _transportManager.DataToBeSentCollection.Add <PSObject>(dataToBeSent, DataPriorityType.PromptResponse);
            }
        }
        /// <summary>
        /// Execute void method.
        /// </summary>
        internal void ExecuteVoidMethod(RemoteHostMethodId methodId, object[] parameters)
        {
            Dbg.Assert(parameters != null, "Expected parameters != null");

            // Use void call ID so that the call is known to not have a return value.
            long callId = ServerDispatchTable.VoidCallId;
            RemoteHostCall remoteHostCall = new RemoteHostCall(callId, methodId, parameters);

            // Dispatch the call but don't wait for response since the return value is void.

            // TODO: remove redundant data from the RemoteHostCallPacket.
            RemoteDataObject<PSObject> dataToBeSent = RemoteDataObject<PSObject>.CreateFrom(RemotingDestination.Client,
                _remoteHostCallDataType, _clientRunspacePoolId, _clientPowerShellId,
                remoteHostCall.Encode());
            // flush is not used here..since this is a void method and server host
            // does not expect anything from client..so let the transport manager buffer
            // and send as much data as possible.
            _transportManager.SendDataToClient(dataToBeSent, false);
        }
예제 #16
0
        internal void OnDataAvailableCallback(RemoteDataObject <PSObject> remoteObject)
        {
            PSEtwLog.LogAnalyticInformational(PSEventId.TransportReceivedObject, PSOpcode.Open, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] {
                remoteObject.RunspacePoolId.ToString(),
                remoteObject.PowerShellId.ToString(),
                (int)remoteObject.Destination,
                (int)remoteObject.DataType,
                (int)remoteObject.TargetInterface
            });
            this.PowerShellGuidObserver.SafeInvoke(remoteObject.PowerShellId, EventArgs.Empty);
            RemoteDataEventArgs eventArgs = new RemoteDataEventArgs(remoteObject);

            if (remoteObject.DataType == RemotingDataType.RunspacePoolStateInfo)
            {
                System.Diagnostics.Debug.WriteLine("RunspacePool State Opened Received");
                Thread.Sleep(800);                  //HACK: Delay reception in local mode... TODO: Find why!!! cannot have a Wait somewhere
                _slowed = true;
            }
            this.DataReceived.SafeInvoke <RemoteDataEventArgs>(this, eventArgs);
        }
예제 #17
0
        internal void DispatchInputQueueData(object sender, RemoteDataEventArgs dataArg)
        {
            if (dataArg == null)
            {
                throw PSTraceSource.NewArgumentNullException("dataArg");
            }
            RemoteDataObject <PSObject> receivedData = dataArg.ReceivedData;

            if (receivedData == null)
            {
                throw PSTraceSource.NewArgumentException("dataArg");
            }
            RemotingDestination destination = receivedData.Destination;
            var d = receivedData.Data;

            if ((destination & (RemotingDestination.InvalidDestination | RemotingDestination.Client)) != (RemotingDestination.InvalidDestination | RemotingDestination.Client))
            {
                throw new PSRemotingDataStructureException(RemotingErrorIdStrings.RemotingDestinationNotForMe, new object[] { RemotingDestination.InvalidDestination | RemotingDestination.Client, destination });
            }
            switch (receivedData.TargetInterface)
            {
            case RemotingTargetInterface.Session:
                this.ProcessSessionMessages(dataArg);
                return;

            case RemotingTargetInterface.RunspacePool:
            case RemotingTargetInterface.PowerShell:
            {
                RemoteSessionStateMachineEventArgs arg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived, null);
                if (!this.StateMachine.CanByPassRaiseEvent(arg))
                {
                    this.StateMachine.RaiseEvent(arg, false);
                    return;
                }
                this.ProcessNonSessionMessages(dataArg.ReceivedData);
                return;
            }
            }
        }
예제 #18
0
        internal static RemoteDataObject <T> CreateFrom(Stream serializedDataStream, Fragmentor defragmentor)
        {
            if ((serializedDataStream.Length - serializedDataStream.Position) < 40L)
            {
                PSRemotingTransportException exception = new PSRemotingTransportException(PSRemotingErrorId.NotEnoughHeaderForRemoteDataObject, RemotingErrorIdStrings.NotEnoughHeaderForRemoteDataObject, new object[] { 0x3d });
                throw exception;
            }
            RemotingDestination destination = (RemotingDestination)RemoteDataObject <T> .DeserializeUInt(serializedDataStream);

            RemotingDataType dataType = (RemotingDataType)RemoteDataObject <T> .DeserializeUInt(serializedDataStream);

            Guid runspacePoolId = RemoteDataObject <T> .DeserializeGuid(serializedDataStream);

            Guid powerShellId = RemoteDataObject <T> .DeserializeGuid(serializedDataStream);

            object valueToConvert = null;

            if ((serializedDataStream.Length - 40L) > 0L)
            {
                valueToConvert = defragmentor.DeserializeToPSObject(serializedDataStream);
            }
            return(new RemoteDataObject <T>(destination, dataType, runspacePoolId, powerShellId, (T)LanguagePrimitives.ConvertTo(valueToConvert, typeof(T), CultureInfo.CurrentCulture)));
        }
예제 #19
0
        internal void ProcessRawData(byte[] data, OnDataAvailableCallback callback)
        {
            lock (this.syncObject)
            {
                if (this.isDisposed)
                {
                    return;
                }
                this.numberOfThreadsProcessing++;
                int maxNumberOfThreadsToAllowForProcessing = this.maxNumberOfThreadsToAllowForProcessing;
                int numberOfThreadsProcessing = this.numberOfThreadsProcessing;
            }
            try
            {
                this.pendingDataStream.Write(data, 0, data.Length);
Label_005A:
                if (this.pendingDataStream.Length <= 0x15L)
                {
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Not enough data to process. Data is less than header length. Data length is {0}. Header Length {1}.", new object[] { this.pendingDataStream.Length, 0x15 }), new object[0]);
                }
                else
                {
                    byte[] fragmentBytes = this.pendingDataStream.GetBuffer();
                    long   objectId      = FragmentedRemoteObject.GetObjectId(fragmentBytes, 0);
                    if (objectId <= 0L)
                    {
                        throw new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdCannotBeLessThanZero);
                    }
                    long fragmentId      = FragmentedRemoteObject.GetFragmentId(fragmentBytes, 0);
                    bool isStartFragment = FragmentedRemoteObject.GetIsStartFragment(fragmentBytes, 0);
                    bool isEndFragment   = FragmentedRemoteObject.GetIsEndFragment(fragmentBytes, 0);
                    int  blobLength      = FragmentedRemoteObject.GetBlobLength(fragmentBytes, 0);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Object Id: {0}", new object[] { objectId }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Fragment Id: {0}", new object[] { fragmentId }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Start Flag: {0}", new object[] { isStartFragment }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "End Flag: {0}", new object[] { isEndFragment }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Blob Length: {0}", new object[] { blobLength }), new object[0]);
                    int count = 0;
                    try
                    {
                        count = 0x15 + blobLength;
                    }
                    catch (OverflowException)
                    {
                        baseTracer.WriteLine("Fragement too big.", new object[0]);
                        this.ResetRecieveData();
                        PSRemotingTransportException exception = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIsTooBig);
                        throw exception;
                    }
                    if (this.pendingDataStream.Length < count)
                    {
                        baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Not enough data to process packet. Data is less than expected blob length. Data length {0}. Expected Length {1}.", new object[] { this.pendingDataStream.Length, count }), new object[0]);
                    }
                    else
                    {
                        if (this.maxReceivedObjectSize.HasValue)
                        {
                            this.totalReceivedObjectSizeSoFar += count;
                            if ((this.totalReceivedObjectSizeSoFar < 0) || (this.totalReceivedObjectSizeSoFar > this.maxReceivedObjectSize.Value))
                            {
                                baseTracer.WriteLine("ObjectSize > MaxReceivedObjectSize. ObjectSize is {0}. MaxReceivedObjectSize is {1}", new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                PSRemotingTransportException exception2 = null;
                                if (this.isCreateByClientTM)
                                {
                                    exception2 = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumClient, RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumClient, new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                }
                                else
                                {
                                    exception2 = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumServer, RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumServer, new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                }
                                this.ResetRecieveData();
                                throw exception2;
                            }
                        }
                        this.pendingDataStream.Seek(0L, SeekOrigin.Begin);
                        byte[] buffer = new byte[count];
                        this.pendingDataStream.Read(buffer, 0, count);
                        PSEtwLog.LogAnalyticVerbose(PSEventId.ReceivedRemotingFragment, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, objectId, fragmentId, isStartFragment ? 1 : 0, isEndFragment ? 1 : 0, (int)blobLength, new PSETWBinaryBlob(buffer, 0x15, blobLength));
                        byte[] buffer3 = null;
                        if (count < this.pendingDataStream.Length)
                        {
                            buffer3 = new byte[this.pendingDataStream.Length - count];
                            this.pendingDataStream.Read(buffer3, 0, ((int)this.pendingDataStream.Length) - count);
                        }
                        this.pendingDataStream.Close();
                        this.pendingDataStream = new MemoryStream();
                        if (buffer3 != null)
                        {
                            this.pendingDataStream.Write(buffer3, 0, buffer3.Length);
                        }
                        if (isStartFragment)
                        {
                            this.canIgnoreOffSyncFragments = false;
                            this.currentObjectId           = objectId;
                            this.dataToProcessStream       = new MemoryStream();
                        }
                        else
                        {
                            if (objectId != this.currentObjectId)
                            {
                                baseTracer.WriteLine("ObjectId != CurrentObjectId", new object[0]);
                                this.ResetRecieveData();
                                if (!this.canIgnoreOffSyncFragments)
                                {
                                    PSRemotingTransportException exception3 = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdsNotMatching);
                                    throw exception3;
                                }
                                baseTracer.WriteLine("Ignoring ObjectId != CurrentObjectId", new object[0]);
                                goto Label_005A;
                            }
                            if (fragmentId != (this.currentFrgId + 1L))
                            {
                                baseTracer.WriteLine("Fragment Id is not in sequence.", new object[0]);
                                this.ResetRecieveData();
                                if (!this.canIgnoreOffSyncFragments)
                                {
                                    PSRemotingTransportException exception4 = new PSRemotingTransportException(RemotingErrorIdStrings.FragmetIdsNotInSequence);
                                    throw exception4;
                                }
                                baseTracer.WriteLine("Ignoring Fragment Id is not in sequence.", new object[0]);
                                goto Label_005A;
                            }
                        }
                        this.currentFrgId = fragmentId;
                        this.dataToProcessStream.Write(buffer, 0x15, blobLength);
                        if (!isEndFragment)
                        {
                            goto Label_005A;
                        }
                        try
                        {
                            this.dataToProcessStream.Seek(0L, SeekOrigin.Begin);
                            RemoteDataObject <PSObject> obj2 = RemoteDataObject <PSObject> .CreateFrom(this.dataToProcessStream, this.defragmentor);

                            baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Runspace Id: {0}", new object[] { obj2.RunspacePoolId }), new object[0]);
                            baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "PowerShell Id: {0}", new object[] { obj2.PowerShellId }), new object[0]);
                            callback(obj2);
                        }
                        finally
                        {
                            this.ResetRecieveData();
                        }
                        if (!this.isDisposed && this.pendingDataStream.Length > 0x15L)
                        {
                            goto Label_005A;
                        }
                    }
                }
            }
            finally
            {
                lock (this.syncObject)
                {
                    if (this.isDisposed && (this.numberOfThreadsProcessing == 1))
                    {
                        this.ReleaseResources();
                    }
                    this.numberOfThreadsProcessing--;
                }
            }
        }
예제 #20
0
 /// <summary>
 /// Adds data to this collection. The data is fragmented in this method
 /// before being stored into the collection. So the calling thread
 /// will get affected, if it tries to add a huge object.
 ///
 /// The data is added with Default priority.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="data">
 /// data to be added to the collection. Caller should make sure this is not
 /// null.
 /// </param>
 internal void Add <T>(RemoteDataObject <T> data)
 {
     Add <T>(data, DataPriorityType.Default);
 }
예제 #21
0
        /// <summary>
        /// Process data coming from the transport. This method analyses the data
        /// and if an object can be created, it creates one and calls the
        /// <paramref name="callback"/> with the deserialized object. This method
        /// does not assume all fragments to be available. So if not enough fragments are
        /// available it will simply return..
        /// </summary>
        /// <param name="data">
        /// Data to process.
        /// </param>
        /// <param name="callback">
        /// Callback to call once a complete deserialized object is available.
        /// </param>
        /// <returns>
        /// Defragmented Object if any, otherwise null.
        /// </returns>
        /// <exception cref="PSRemotingTransportException">
        /// 1. Fragment Ids not in sequence
        /// 2. Object Ids does not match
        /// 3. The current deserialized object size of the received data exceeded
        /// allowed maximum object size. The current deserialized object size is {0}.
        /// Allowed maximum object size is {1}.
        /// </exception>
        /// <remarks>
        /// Might throw other exceptions as the deserialized object is handled here.
        /// </remarks>
        internal void ProcessRawData(byte[] data, OnDataAvailableCallback callback)
        {
            Dbg.Assert(data != null, "Cannot process null data");
            Dbg.Assert(callback != null, "Callback cannot be null");

            lock (_syncObject)
            {
                if (_isDisposed)
                {
                    return;
                }

                _numberOfThreadsProcessing++;
                if (_numberOfThreadsProcessing > _maxNumberOfThreadsToAllowForProcessing)
                {
                    Dbg.Assert(false, "Multiple threads are not allowed in ProcessRawData.");
                }
            }

            try
            {
                _pendingDataStream.Write(data, 0, data.Length);

                // this do loop will process one deserialized object.
                // using a loop allows to process multiple objects within
                // the same packet
                while (true)
                {
                    if (_pendingDataStream.Length <= FragmentedRemoteObject.HeaderLength)
                    {
                        // there is not enough data to be processed.
                        s_baseTracer.WriteLine("Not enough data to process. Data is less than header length. Data length is {0}. Header Length {1}.",
                                               _pendingDataStream.Length, FragmentedRemoteObject.HeaderLength);
                        return;
                    }

                    byte[] dataRead = _pendingDataStream.ToArray();

                    // there is enough data to process here. get the fragment header
                    long objectId = FragmentedRemoteObject.GetObjectId(dataRead, 0);
                    if (objectId <= 0)
                    {
                        throw new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdCannotBeLessThanZero);
                    }

                    long fragmentId = FragmentedRemoteObject.GetFragmentId(dataRead, 0);
                    bool sFlag      = FragmentedRemoteObject.GetIsStartFragment(dataRead, 0);
                    bool eFlag      = FragmentedRemoteObject.GetIsEndFragment(dataRead, 0);
                    int  blobLength = FragmentedRemoteObject.GetBlobLength(dataRead, 0);

                    if ((s_baseTracer.Options & PSTraceSourceOptions.WriteLine) != PSTraceSourceOptions.None)
                    {
                        s_baseTracer.WriteLine("Object Id: {0}", objectId);
                        s_baseTracer.WriteLine("Fragment Id: {0}", fragmentId);
                        s_baseTracer.WriteLine("Start Flag: {0}", sFlag);
                        s_baseTracer.WriteLine("End Flag: {0}", eFlag);
                        s_baseTracer.WriteLine("Blob Length: {0}", blobLength);
                    }

                    int totalLengthOfFragment = 0;

                    try
                    {
                        totalLengthOfFragment = checked (FragmentedRemoteObject.HeaderLength + blobLength);
                    }
                    catch (System.OverflowException)
                    {
                        s_baseTracer.WriteLine("Fragment too big.");
                        ResetReceiveData();
                        PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIsTooBig);
                        throw e;
                    }

                    if (_pendingDataStream.Length < totalLengthOfFragment)
                    {
                        s_baseTracer.WriteLine("Not enough data to process packet. Data is less than expected blob length. Data length {0}. Expected Length {1}.",
                                               _pendingDataStream.Length, totalLengthOfFragment);
                        return;
                    }

                    // ensure object size limit is not reached
                    if (_maxReceivedObjectSize.HasValue)
                    {
                        _totalReceivedObjectSizeSoFar = unchecked (_totalReceivedObjectSizeSoFar + totalLengthOfFragment);
                        if ((_totalReceivedObjectSizeSoFar < 0) || (_totalReceivedObjectSizeSoFar > _maxReceivedObjectSize.Value))
                        {
                            s_baseTracer.WriteLine("ObjectSize > MaxReceivedObjectSize. ObjectSize is {0}. MaxReceivedObjectSize is {1}",
                                                   _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            PSRemotingTransportException e = null;

                            if (_isCreateByClientTM)
                            {
                                e = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumClient,
                                                                     RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumClient,
                                                                     _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            }
                            else
                            {
                                e = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumServer,
                                                                     RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumServer,
                                                                     _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            }

                            ResetReceiveData();
                            throw e;
                        }
                    }

                    // appears like stream doesn't have individual position marker for read and write
                    // since we are going to read from now...
                    _pendingDataStream.Seek(0, SeekOrigin.Begin);

                    // we have enough data to process..so read the data from the stream and process.
                    byte[] oneFragment = new byte[totalLengthOfFragment];
                    // this will change position back to totalLengthOfFragment
                    int dataCount = _pendingDataStream.Read(oneFragment, 0, totalLengthOfFragment);
                    Dbg.Assert(dataCount == totalLengthOfFragment, "Unable to read enough data from the stream. Read failed");

                    PSEtwLog.LogAnalyticVerbose(
                        PSEventId.ReceivedRemotingFragment, PSOpcode.Receive, PSTask.None,
                        PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                        (Int64)objectId,
                        (Int64)fragmentId,
                        sFlag ? 1 : 0,
                        eFlag ? 1 : 0,
                        (UInt32)blobLength,
                        new PSETWBinaryBlob(oneFragment, FragmentedRemoteObject.HeaderLength, blobLength));

                    byte[] extraData = null;
                    if (totalLengthOfFragment < _pendingDataStream.Length)
                    {
                        // there is more data in the stream than fragment size..so save that data
                        extraData = new byte[_pendingDataStream.Length - totalLengthOfFragment];
                        _pendingDataStream.Read(extraData, 0, (int)(_pendingDataStream.Length - totalLengthOfFragment));
                    }

                    // reset incoming stream.
                    _pendingDataStream.Dispose();
                    _pendingDataStream = new MemoryStream();
                    if (extraData != null)
                    {
                        _pendingDataStream.Write(extraData, 0, extraData.Length);
                    }

                    if (sFlag)
                    {
                        _canIgnoreOffSyncFragments = false; // reset this upon receiving a start fragment of a fresh object
                        _currentObjectId           = objectId;
                        // Memory streams created with an unsigned byte array provide a non-resizable stream view
                        // of the data, and can only be written to. When using a byte array, you can neither append
                        // to nor shrink the stream, although you might be able to modify the existing contents
                        // depending on the parameters passed into the constructor. Empty memory streams are
                        // resizable, and can be written to and read from.
                        _dataToProcessStream = new MemoryStream();
                    }
                    else
                    {
                        // check if the data belongs to the same object as the start fragment
                        if (objectId != _currentObjectId)
                        {
                            s_baseTracer.WriteLine("ObjectId != CurrentObjectId");
                            // TODO - drop an ETW event
                            ResetReceiveData();
                            if (!_canIgnoreOffSyncFragments)
                            {
                                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdsNotMatching);
                                throw e;
                            }
                            else
                            {
                                s_baseTracer.WriteLine("Ignoring ObjectId != CurrentObjectId");
                                continue;
                            }
                        }

                        if (fragmentId != (_currentFrgId + 1))
                        {
                            s_baseTracer.WriteLine("Fragment Id is not in sequence.");
                            // TODO - drop an ETW event
                            ResetReceiveData();
                            if (!_canIgnoreOffSyncFragments)
                            {
                                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.FragmentIdsNotInSequence);
                                throw e;
                            }
                            else
                            {
                                s_baseTracer.WriteLine("Ignoring Fragment Id is not in sequence.");
                                continue;
                            }
                        }
                    }

                    // make fragment id from this packet as the current fragment id
                    _currentFrgId = fragmentId;
                    // store the blob in a separate stream
                    _dataToProcessStream.Write(oneFragment, FragmentedRemoteObject.HeaderLength, blobLength);

                    if (eFlag)
                    {
                        try
                        {
                            // appears like stream doesn't individual position marker for read and write
                            // since we are going to read from now..i am resetting position to 0.
                            _dataToProcessStream.Seek(0, SeekOrigin.Begin);
                            RemoteDataObject <PSObject> remoteObject = RemoteDataObject <PSObject> .CreateFrom(_dataToProcessStream, _defragmentor);

                            s_baseTracer.WriteLine("Runspace Id: {0}", remoteObject.RunspacePoolId);
                            s_baseTracer.WriteLine("PowerShell Id: {0}", remoteObject.PowerShellId);
                            // notify the caller that a deserialized object is available.
                            callback(remoteObject);
                        }
                        finally
                        {
                            // Reset the receive data buffers and start the process again.
                            ResetReceiveData();
                        }

                        if (_isDisposed)
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                lock (_syncObject)
                {
                    if (_isDisposed && (_numberOfThreadsProcessing == 1))
                    {
                        ReleaseResources();
                    }

                    _numberOfThreadsProcessing--;
                }
            }
        }
예제 #22
0
 internal abstract void RaiseKeyExchangeMessageReceived(RemoteDataObject <PSObject> receivedData);
예제 #23
0
 internal void ExecuteVoidMethod(RemoteHostMethodId methodId, object[] parameters) => this._transportManager.SendDataToClient <PSObject>(RemoteDataObject <PSObject> .CreateFrom(RemotingDestination.Client, this._remoteHostCallDataType, this._clientRunspacePoolId, this._clientPowerShellId, new RemoteHostCall(-100L, methodId, parameters).Encode()), false);
예제 #24
0
        internal void DispatchInputQueueData(object sender, RemoteDataEventArgs dataEventArg)
        {
            using (ServerRemoteSession._trace.TraceMethod())
            {
                RemoteDataObject <PSObject> remoteDataObject    = dataEventArg != null ? dataEventArg.ReceivedData : throw ServerRemoteSession._trace.NewArgumentNullException(nameof(dataEventArg));
                RemotingDestination         remotingDestination = remoteDataObject != null ? remoteDataObject.Destination : throw ServerRemoteSession._trace.NewArgumentException(nameof(dataEventArg));
                if ((remotingDestination & this.MySelf) != this.MySelf)
                {
                    throw new PSRemotingDataStructureException(PSRemotingErrorId.RemotingDestinationNotForMe, new object[2]
                    {
                        (object)this.MySelf,
                        (object)remotingDestination
                    });
                }
                RemotingTargetInterface targetInterface = remoteDataObject.TargetInterface;
                RemotingDataType        dataType        = remoteDataObject.DataType;
                switch (targetInterface)
                {
                case RemotingTargetInterface.Session:
                    switch (dataType)
                    {
                    case RemotingDataType.SessionCapability:
                        this._sessionDSHandler.RaiseDataReceivedEvent(dataEventArg);
                        return;

                    case RemotingDataType.CloseSession:
                        this._sessionDSHandler.RaiseDataReceivedEvent(dataEventArg);
                        return;

                    case RemotingDataType.CreateRunspacePool:
                        RemoteSessionStateMachineEventArgs fsmEventArg1 = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived);
                        if (this.SessionDataStructureHandler.StateMachine.CanByPassRaiseEvent(fsmEventArg1))
                        {
                            fsmEventArg1.RemoteData = remoteDataObject;
                            this.SessionDataStructureHandler.StateMachine.DoMessageReceived((object)this, fsmEventArg1);
                            return;
                        }
                        this.SessionDataStructureHandler.StateMachine.RaiseEvent(fsmEventArg1);
                        return;

                    case RemotingDataType.PublicKey:
                        this._sessionDSHandler.RaiseDataReceivedEvent(dataEventArg);
                        return;

                    default:
                        return;
                    }

                case RemotingTargetInterface.RunspacePool:
                case RemotingTargetInterface.PowerShell:
                    RemoteSessionStateMachineEventArgs fsmEventArg2 = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.MessageReceived);
                    if (this.SessionDataStructureHandler.StateMachine.CanByPassRaiseEvent(fsmEventArg2))
                    {
                        fsmEventArg2.RemoteData = remoteDataObject;
                        this.SessionDataStructureHandler.StateMachine.DoMessageReceived((object)this, fsmEventArg2);
                        break;
                    }
                    this.SessionDataStructureHandler.StateMachine.RaiseEvent(fsmEventArg2);
                    break;
                }
            }
        }
예제 #25
0
 /// <summary>
 /// Raise the public key received event
 /// </summary>
 /// <param name="receivedData">received data</param>
 /// <remarks>This method is a hook to be called
 /// from the transport manager</remarks>
 internal override void RaiseKeyExchangeMessageReceived(RemoteDataObject <PSObject> receivedData)
 {
     ProcessSessionMessages(new RemoteDataEventArgs(receivedData));
 }
예제 #26
0
        // 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.GitCommitId, 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);
            }
            }
        }
예제 #27
0
        private void HandleNegotiationSendingStateChange()
        {
            RemoteDataObject sessionCapability = RemotingEncoder.GenerateClientSessionCapability(this._session.Context.ClientCapability, this._session.RemoteRunspacePoolInternal.InstanceId);

            this._transportManager.DataToBeSentCollection.Add <PSObject>(RemoteDataObject <PSObject> .CreateFrom(sessionCapability.Destination, sessionCapability.DataType, sessionCapability.RunspacePoolId, sessionCapability.PowerShellId, (PSObject)sessionCapability.Data));
        }
예제 #28
0
 /// <summary>
 /// Raise the public key received event
 /// </summary>
 /// <param name="receivedData">received data</param>
 /// <remarks>This method is a hook to be called
 /// from the transport manager</remarks>
 internal override void RaiseKeyExchangeMessageReceived(RemoteDataObject <PSObject> receivedData)
 {
     RaiseDataReceivedEvent(new RemoteDataEventArgs(receivedData));
 }
예제 #29
0
        /// <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 is null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(dataArg));
            }

            RemoteDataObject <PSObject> rcvdData = dataArg.ReceivedData;

            if (rcvdData is null)
            {
                throw PSTraceSource.NewArgumentException(nameof(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;
            }
        }
예제 #30
0
        /// <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.GitCommitId, 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);
            }
        }