internal WSManPluginCommandSession(
     WSManNativeApi.WSManPluginRequest creationRequestDetails,
     WSManPluginServerTransportManager transportMgr,
     ServerRemoteSession remoteSession)
     : base(creationRequestDetails, transportMgr)
 {
     _remoteSession = remoteSession;
     cmdSyncObject  = new System.Object();
 }
Beispiel #2
0
        protected WSManPluginServerSession(
            WSManNativeApi.WSManPluginRequest creationRequestDetails,
            WSManPluginServerTransportManager transportMgr)
        {
            _syncObject = new object();
            this.creationRequestDetails = creationRequestDetails;
            this.transportMgr           = transportMgr;

            transportMgr.PrepareCalled += this.HandlePrepareFromTransportManager;
            transportMgr.WSManTransportErrorOccured += this.HandleTransportError;
        }
        protected WSManPluginServerSession(
            WSManNativeApi.WSManPluginRequest creationRequestDetails,
            WSManPluginServerTransportManager transportMgr)
        {
            _syncObject = new Object();
            this.creationRequestDetails = creationRequestDetails;
            this.transportMgr = transportMgr;

            transportMgr.PrepareCalled +=
                new EventHandler<EventArgs>(this.HandlePrepareFromTransportManager);
            transportMgr.WSManTransportErrorOccured +=
                new EventHandler<TransportErrorOccuredEventArgs>(this.HandleTransportError);
        }
        internal WSManPluginShellSession(
            WSManNativeApi.WSManPluginRequest creationRequestDetails,
            WSManPluginServerTransportManager transportMgr,
            ServerRemoteSession remoteSession,
            WSManPluginOperationShutdownContext shutDownContext)
            : base(creationRequestDetails, transportMgr)
        {
            _remoteSession         = remoteSession;
            _remoteSession.Closed +=
                new EventHandler <RemoteSessionStateMachineEventArgs>(this.HandleServerRemoteSessionClosed);

            _activeCommandSessions = new Dictionary <IntPtr, WSManPluginCommandSession>();
            this.shellSyncObject   = new System.Object();
            this.shutDownContext   = shutDownContext;
        }
Beispiel #5
0
        // Used by command transport manager to manage cmd transport manager instances by session.
        internal void ReportTransportMgrForCmd(
            Guid cmdId,
            WSManPluginServerTransportManager transportManager)
        {
            lock (_syncObject)
            {
                if (_isClosed)
                {
                    return;
                }

                if (!_activeCmdTransportManagers.ContainsKey(cmdId))
                {
                    _activeCmdTransportManagers.Add(cmdId, transportManager);
                }
            }
        }
Beispiel #6
0
 // Create Cmd Transport Manager for this sessn transport manager
 internal WSManPluginCommandTransportManager(WSManPluginServerTransportManager srvrTransportMgr)
     : base(srvrTransportMgr.Fragmentor.FragmentSize, srvrTransportMgr.CryptoHelper)
 {
     _serverTransportMgr = srvrTransportMgr;
     this.TypeTable      = srvrTransportMgr.TypeTable;
 }
Beispiel #7
0
        /// <summary>
        /// Create a new shell in the plugin context.
        /// </summary>
        /// <param name="pluginContext"></param>
        /// <param name="requestDetails"></param>
        /// <param name="flags"></param>
        /// <param name="extraInfo"></param>
        /// <param name="startupInfo"></param>
        /// <param name="inboundShellInformation"></param>
        internal void CreateShell(
            IntPtr pluginContext,
            WSManNativeApi.WSManPluginRequest requestDetails,
            int flags,
            string extraInfo,
            WSManNativeApi.WSManShellStartupInfo_UnToMan startupInfo,
            WSManNativeApi.WSManData_UnToMan inboundShellInformation)
        {
            if (null == requestDetails)
            {
                // Nothing can be done because requestDetails are required to report operation complete
                PSEtwLog.LogAnalyticInformational(PSEventId.ReportOperationComplete,
                    PSOpcode.Close, PSTask.None,
                    PSKeyword.ManagedPlugin | PSKeyword.UseAlwaysAnalytic,
                    "null",
                    Convert.ToString(WSManPluginErrorCodes.NullInvalidInput, CultureInfo.InvariantCulture),
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidInput,
                        "requestDetails",
                        "WSManPluginShell"),
                    String.Empty);
                return;
            }

            if ((null == requestDetails.senderDetails) ||
                (null == requestDetails.operationInfo))
            {
                ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.NullInvalidInput,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidInput,
                        "requestDetails",
                        "WSManPluginShell"));
                return;
            }

            if (null == startupInfo)
            {
                ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.NullInvalidInput,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidInput,
                        "startupInfo",
                        "WSManPluginShell"));
                return;
            }

            if ((0 == startupInfo.inputStreamSet.streamIDsCount) || (0 == startupInfo.outputStreamSet.streamIDsCount))
            {
                ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.NullInvalidStreamSets,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidStreamSet,
                        WSManPluginConstants.SupportedInputStream,
                        WSManPluginConstants.SupportedOutputStream));
                return;
            }

            if (String.IsNullOrEmpty(extraInfo))
            {
                ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.NullInvalidInput,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidInput,
                        "extraInfo",
                        "WSManPluginShell"));
                return;
            }

            WSManPluginInstance.SetThreadProperties(requestDetails);

            // check if protocolversion option is honored
            if (!EnsureOptionsComply(requestDetails))
            {
                return;
            }

            int result = WSManPluginConstants.ExitCodeSuccess;
            WSManPluginShellSession mgdShellSession;
            WSManPluginOperationShutdownContext context;
            System.Byte[] convertedBase64 = null;

            try
            {
                PSSenderInfo senderInfo = GetPSSenderInfo(requestDetails.senderDetails);

                // inbound shell information is already verified by pwrshplugin.dll.. so no need
                // to verify here.
                WSManPluginServerTransportManager serverTransportMgr;

                if (Platform.IsWindows)
                {
                    serverTransportMgr = new WSManPluginServerTransportManager(BaseTransportManager.DefaultFragmentSize, new PSRemotingCryptoHelperServer());
                }

                else
                {
                    serverTransportMgr = new WSManPluginServerTransportManager(BaseTransportManager.DefaultFragmentSize, null);
                }

                PSEtwLog.LogAnalyticInformational(PSEventId.ServerCreateRemoteSession,
                    PSOpcode.Connect, PSTask.None,
                    PSKeyword.ManagedPlugin | PSKeyword.UseAlwaysAnalytic,
                    requestDetails.ToString(), senderInfo.UserInfo.Identity.Name, requestDetails.resourceUri);
                ServerRemoteSession remoteShellSession = ServerRemoteSession.CreateServerRemoteSession(senderInfo,
                    requestDetails.resourceUri,
                    extraInfo,
                    serverTransportMgr);

                if (null == remoteShellSession)
                {
                    WSManPluginInstance.ReportWSManOperationComplete(
                        requestDetails,
                        WSManPluginErrorCodes.SessionCreationFailed);
                    return;
                }

                context = new WSManPluginOperationShutdownContext(pluginContext, requestDetails.unmanagedHandle, IntPtr.Zero, false);
                if (null == context)
                {
                    ReportOperationComplete(requestDetails, WSManPluginErrorCodes.OutOfMemory);
                    return;
                }

                // Create a shell session wrapper to track and service future interactions.
                mgdShellSession = new WSManPluginShellSession(requestDetails, serverTransportMgr, remoteShellSession, context);
                AddToActiveShellSessions(mgdShellSession);
                mgdShellSession.SessionClosed += new EventHandler<EventArgs>(HandleShellSessionClosed);

                if (null != inboundShellInformation)
                {
                    if ((uint)WSManNativeApi.WSManDataType.WSMAN_DATA_TYPE_TEXT != inboundShellInformation.Type)
                    {
                        // only text data is supported
                        ReportOperationComplete(
                            requestDetails,
                            WSManPluginErrorCodes.InvalidInputDatatype,
                            StringUtil.Format(
                                RemotingErrorIdStrings.WSManPluginInvalidInputDataType,
                                "WSMAN_DATA_TYPE_TEXT"));
                        DeleteFromActiveShellSessions(requestDetails.unmanagedHandle);
                        return;
                    }
                    else
                    {
                        convertedBase64 = ServerOperationHelpers.ExtractEncodedXmlElement(
                            inboundShellInformation.Text,
                            WSManNativeApi.PS_CREATION_XML_TAG);
                    }
                }

                // now report the shell context to WSMan.
                PSEtwLog.LogAnalyticInformational(PSEventId.ReportContext,
                    PSOpcode.Connect, PSTask.None,
                    PSKeyword.ManagedPlugin | PSKeyword.UseAlwaysAnalytic,
                    requestDetails.ToString(), requestDetails.ToString());
                result = wsmanPinvokeStatic.WSManPluginReportContext(requestDetails.unmanagedHandle, 0, requestDetails.unmanagedHandle);

                if (WSManPluginConstants.ExitCodeSuccess != result)
                {
                    ReportOperationComplete(
                        requestDetails,
                        WSManPluginErrorCodes.ReportContextFailed,
                        StringUtil.Format(
                                RemotingErrorIdStrings.WSManPluginReportContextFailed));
                    DeleteFromActiveShellSessions(requestDetails.unmanagedHandle);
                    return;
                }
            }
            catch (System.Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                PSEtwLog.LogOperationalError(PSEventId.TransportError,
                    PSOpcode.Connect, PSTask.None, PSKeyword.UseAlwaysOperational, "00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000",
                    Convert.ToString(WSManPluginErrorCodes.ManagedException, CultureInfo.InvariantCulture), e.Message, e.StackTrace);

                DeleteFromActiveShellSessions(requestDetails.unmanagedHandle);
                ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.ManagedException,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginManagedException,
                        e.Message));
                return;
            }

            bool isRegisterWaitForSingleObjectSucceeded = true;

            //always synchronize calls to OperationComplete once notification handle is registered.. else duplicate OperationComplete calls are bound to happen
            lock (mgdShellSession.shellSyncObject)
            {
                mgdShellSession.registeredShutdownNotification = 1;

                // Wrap the provided handle so it can be passed to the registration function
                EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

                if (Platform.IsWindows)
                {
                    SafeWaitHandle safeWaitHandle = new SafeWaitHandle(requestDetails.shutdownNotificationHandle, false); // Owned by WinRM
                    ClrFacade.SetSafeWaitHandle(eventWaitHandle, safeWaitHandle);
                }
                else
                {
                    //On non-windows platforms the shutdown notification is done through a callback instead of a windows event handle.
                    //Register the callback and this will then signal the event. Note, the gch object is deleted in the shell shutdown
                    //notification that will always come in to shut down the operation.

                    GCHandle gch = GCHandle.Alloc(eventWaitHandle);
                    IntPtr p = GCHandle.ToIntPtr(gch);

                    wsmanPinvokeStatic.WSManPluginRegisterShutdownCallback(
                                                           requestDetails.unmanagedHandle,
                                                           WSManPluginManagedEntryWrapper.workerPtrs.UnmanagedStruct.wsManPluginShutdownCallbackNative,
                                                           p);
                }


                mgdShellSession.registeredShutDownWaitHandle = ThreadPool.RegisterWaitForSingleObject(
                                 eventWaitHandle,
                                 new WaitOrTimerCallback(WSManPluginManagedEntryWrapper.PSPluginOperationShutdownCallback),
                                 context,
                                 -1, // INFINITE
                                 true); // TODO: Do I need to worry not being able to set missing WT_TRANSFER_IMPERSONATION?
                if (null == mgdShellSession.registeredShutDownWaitHandle)
                {
                    isRegisterWaitForSingleObjectSucceeded = false;
                }
            }

            if (!isRegisterWaitForSingleObjectSucceeded)
            {
                mgdShellSession.registeredShutdownNotification = 0;
                WSManPluginInstance.ReportWSManOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.ShutdownRegistrationFailed);
                DeleteFromActiveShellSessions(requestDetails.unmanagedHandle);
                return;
            }

            try
            {
                if (convertedBase64 != null)
                {
                    mgdShellSession.SendOneItemToSessionHelper(convertedBase64, WSManPluginConstants.SupportedInputStream);
                }
            }
            catch (System.Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                PSEtwLog.LogOperationalError(PSEventId.TransportError,
                    PSOpcode.Connect, PSTask.None, PSKeyword.UseAlwaysOperational, "00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000",
                    Convert.ToString(WSManPluginErrorCodes.ManagedException, CultureInfo.InvariantCulture), e.Message, e.StackTrace);

                if (Interlocked.Exchange(ref mgdShellSession.registeredShutdownNotification, 0) == 1)
                {
                    // unregister callback.. wait for any ongoing callbacks to complete.. nothing much we could do if this fails
                    bool ignore = mgdShellSession.registeredShutDownWaitHandle.Unregister(null);
                    mgdShellSession.registeredShutDownWaitHandle = null;

                    //this will called OperationComplete
                    PerformCloseOperation(context);
                }
                return;
            }

            return;
        }
 internal WSManPluginCommandSession(
     WSManNativeApi.WSManPluginRequest creationRequestDetails,
     WSManPluginServerTransportManager transportMgr,
     ServerRemoteSession remoteSession)
     : base(creationRequestDetails, transportMgr)
 {
     _remoteSession = remoteSession;
     cmdSyncObject = new System.Object();
 }
        internal WSManPluginShellSession(
            WSManNativeApi.WSManPluginRequest creationRequestDetails,
            WSManPluginServerTransportManager transportMgr,
            ServerRemoteSession remoteSession,
            WSManPluginOperationShutdownContext shutDownContext)
            : base(creationRequestDetails, transportMgr)
        {
            _remoteSession = remoteSession;
            _remoteSession.Closed +=
                new EventHandler<RemoteSessionStateMachineEventArgs>(this.HandleServerRemoteSessionClosed);

            _activeCommandSessions = new Dictionary<IntPtr, WSManPluginCommandSession>();
            this.shellSyncObject = new System.Object();
            this.shutDownContext = shutDownContext;
        }
 // Create Cmd Transport Manager for this sessn transport manager
 internal WSManPluginCommandTransportManager(WSManPluginServerTransportManager srvrTransportMgr)
     : base(srvrTransportMgr.Fragmentor.FragmentSize, srvrTransportMgr.CryptoHelper)
 {
     _serverTransportMgr = srvrTransportMgr;
     this.TypeTable = srvrTransportMgr.TypeTable;
 }
        // Used by command transport manager to manage cmd transport manager instances by session.
        internal void ReportTransportMgrForCmd(
            Guid cmdId,
            WSManPluginServerTransportManager transportManager)
        {
            lock (_syncObject)
            {
                if (_isClosed)
                {
                    return;
                }

                if (!_activeCmdTransportManagers.ContainsKey(cmdId))
                {
                    _activeCmdTransportManagers.Add(cmdId, transportManager);
                }
            }
        }