Ejemplo n.º 1
0
        public void StartProcess(
            Guid remoteSessionId,
            HostTypeEnum hostType,
            SecurityProtocolEnum securityProtocol,
            string serverAddress,
            string vmGuid,
            string userDomain,
            string userName,
            string startProgram,
            int clientWidth,
            int clientHeight,
            bool allowRemoteClipboard,
            bool allowPrintDownload)
        {
            Trace.TraceInformation("Calling service start process, remote session {0}, server {1}, domain {2}, user {3}, program {4}", remoteSessionId, serverAddress, string.IsNullOrEmpty(userDomain) ? "(none)" : userDomain, userName, string.IsNullOrEmpty(startProgram) ? "(none)" : startProgram);

            lock (_processStartLock)
            {
                try
                {
                    Channel.StartProcess(
                        remoteSessionId,
                        hostType,
                        securityProtocol,
                        serverAddress,
                        vmGuid,
                        userDomain,
                        userName,
                        startProgram,
                        clientWidth,
                        clientHeight,
                        allowRemoteClipboard,
                        allowPrintDownload);

                    _processStarted = true;
                }
                catch (Exception exc)
                {
                    Trace.TraceError("Failed to call service start process, remote session {0} ({1})", _remoteSessionManager.RemoteSession.Id, exc);
                    throw;
                }
            }
        }
Ejemplo n.º 2
0
        public RemoteSession(
            Guid id,
            RemoteSessionState state,
            string hostName,
            HostTypeEnum hostType,
            SecurityProtocolEnum securityProtocol,
            string serverAddress,
            string vmGuid,
            bool vmEnhancedMode,
            string userDomain,
            string userName,
            string userPassword,
            int clientWidth,
            int clientHeight,
            string startProgram,
            bool allowRemoteClipboard,
            bool allowFileTransfer,
            bool allowPrintDownload,
            bool allowSessionSharing,
            string ownerSessionID)
        {
            Id                   = id;
            State                = state;
            HostName             = hostName;
            HostType             = hostType;
            SecurityProtocol     = securityProtocol;
            ServerAddress        = serverAddress;
            VMGuid               = vmGuid;
            VMEnhancedMode       = vmEnhancedMode;
            UserDomain           = userDomain;
            UserName             = userName;
            UserPassword         = userPassword;
            ClientWidth          = clientWidth;
            ClientHeight         = clientHeight;
            StartProgram         = startProgram;
            AllowRemoteClipboard = allowRemoteClipboard;
            AllowFileTransfer    = allowFileTransfer;
            AllowPrintDownload   = allowPrintDownload;
            AllowSessionSharing  = allowSessionSharing;
            OwnerSessionID       = ownerSessionID;

            Manager = new RemoteSessionManager(this);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// page load (postback data is now available)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(
            object sender,
            EventArgs e)
        {
            try
            {
                if (Session[HttpSessionStateVariables.EnterpriseSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                _enterpriseSession = (EnterpriseSession)Session[HttpSessionStateVariables.EnterpriseSession.ToString()];

                try
                {
                    if (!_enterpriseSession.IsAdmin)
                    {
                        Response.Redirect("~/", true);
                    }

                    if (Request["hostType"] == null || !Enum.TryParse(Request["hostType"], out _hostType))
                    {
                        _hostType = HostTypeEnum.RDP;
                    }

                    // retrieve the host, if any (create if empty)
                    if (Request["hostId"] != null)
                    {
                        long hostId;
                        if (!long.TryParse(Request["hostId"], out hostId))
                        {
                            hostId = 0;
                        }

                        if (hostId != 0)
                        {
                            _hostId = hostId;

                            if (!IsPostBack && Request["edit"] == null)
                            {
                                try
                                {
                                    var host = _enterpriseClient.GetHost(_hostId.Value, _enterpriseSession.SessionID);
                                    if (host != null)
                                    {
                                        _hostType                      = host.HostType;
                                        hostType.Value                 = _hostType.ToString();
                                        hostName.Value                 = host.HostName;
                                        hostAddress.Value              = host.HostAddress;
                                        vmGuid.Value                   = host.VMGuid;
                                        vmEnhancedMode.Checked         = host.VMEnhancedMode;
                                        groupsAccess.Value             = host.DirectoryGroups;
                                        securityProtocol.SelectedIndex = (int)host.Protocol;
                                        promptCredentials.Checked      = host.PromptForCredentials;
                                        startProgram.Value             = host.StartRemoteProgram;
                                    }
                                }
                                catch (Exception exc)
                                {
                                    System.Diagnostics.Trace.TraceError("Failed to retrieve host {0}, ({1})", _hostId, exc);
                                }
                            }

                            createSessionUrl.Attributes["onclick"] = string.Format("parent.openPopup('editHostSessionPopup', 'EditHostSession.aspx?hostId={0}');", _hostId);
                        }
                    }
                    else
                    {
                        createSessionUrl.Disabled = true;
                        deleteHost.Disabled       = true;
                    }

                    vmGuidInput.Visible         = _hostType == HostTypeEnum.RDP;
                    vmEnhancedModeInput.Visible = _hostType == HostTypeEnum.RDP;
                    rdpSecurityInput.Visible    = _hostType == HostTypeEnum.RDP;
                    startProgramInput.Visible   = _hostType == HostTypeEnum.RDP;
                }
                catch (ThreadAbortException)
                {
                    // occurs because the response is ended after redirect
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active enterprise session ({0})", exc);
            }
        }
Ejemplo n.º 4
0
        public void StartProcess(
            int remoteSessionId,
            HostTypeEnum hostType,
            SecurityProtocolEnum securityProtocol,
            string serverAddress,
            string userDomain,
            string userName,
            string startProgram,
            int clientWidth,
            int clientHeight,
            bool allowRemoteClipboard,
            bool allowPrintDownload)
        {
            Trace.TraceInformation("Connecting remote session {0}, type {1}, security {2}, server {3}, domain {4}, user {5}, program {6}",
                                   remoteSessionId,
                                   hostType,
                                   hostType == HostTypeEnum.RDP ? securityProtocol.ToString().ToUpper() : "N/A",
                                   serverAddress,
                                   hostType == HostTypeEnum.RDP ? (string.IsNullOrEmpty(userDomain) ? "(none)" : userDomain) : "N/A",
                                   userName,
                                   hostType == HostTypeEnum.RDP ? (string.IsNullOrEmpty(startProgram) ? "(none)" : startProgram) : "N/A");

            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                _process = new Process();

                // select the host client executable based on the host type
                var clientFilePath = string.Empty;
                var clientFileName = string.Empty;
                switch (hostType)
                {
                // see https://github.com/cedrozor/myrtille/blob/master/DOCUMENTATION.md#build for information and steps to build FreeRDP along with myrtille
                case HostTypeEnum.RDP:
                    clientFilePath = @"Myrtille.RDP\FreeRDP";
                    clientFileName = "wfreerdp.exe";
                    break;

                case HostTypeEnum.SSH:
                    clientFilePath = @"Myrtille.SSH\bin";
                    clientFileName = "Myrtille.SSH.exe";
                    break;
                }

                if (Environment.UserInteractive)
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.Replace(@"Myrtille.Services\bin", clientFilePath), clientFileName);
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, clientFileName);
                }

                // ensure the host client executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = string.Format("The host client executable ({0}) is missing. Please read documentation for steps to build it", _process.StartInfo.FileName);
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                // log remote session events into a file (located into <Myrtille folder>\log)
                bool remoteSessionLog;
                if (!bool.TryParse(ConfigurationManager.AppSettings["RemoteSessionLog"], out remoteSessionLog))
                {
                    remoteSessionLog = false;
                }

                #region RDP

                if (hostType == HostTypeEnum.RDP)
                {
                    // color depth
                    int bpp;
                    if (!int.TryParse(ConfigurationManager.AppSettings["FreeRDPBpp"], out bpp))
                    {
                        bpp = 16;
                    }

                    // gdi mode (sw: software, hw: hardware). default software because there is a palette issue with windows server 2008; also, the performance gain is small and even null on most virtual machines, when hardware isn't available
                    var gdi = "sw";
                    if (ConfigurationManager.AppSettings["FreeRDPGdi"] != null)
                    {
                        gdi = ConfigurationManager.AppSettings["FreeRDPGdi"];
                    }

                    // wallpaper
                    bool wallpaper;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWallpaper"], out wallpaper))
                    {
                        wallpaper = false;
                    }

                    // desktop composition
                    bool aero;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPAero"], out aero))
                    {
                        aero = false;
                    }

                    // window drag
                    bool windowDrag;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWindowDrag"], out windowDrag))
                    {
                        windowDrag = false;
                    }

                    // menu animations
                    bool menuAnims;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPMenuAnims"], out menuAnims))
                    {
                        menuAnims = false;
                    }

                    // themes
                    bool themes;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPThemes"], out themes))
                    {
                        themes = false;
                    }

                    // smooth fonts (requires ClearType enabled on the remote server)
                    bool smoothFonts;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPSmoothFonts"], out smoothFonts))
                    {
                        smoothFonts = true;
                    }

                    // ignore certificate warning (when using NLA); may happen, for example, with a self-signed certificate (not trusted) or if the server joined a domain after the certificate was issued (name mismatch). more details here: http://www.vkernel.ro/blog/configuring-certificates-in-2012r2-remote-desktop-services-rds
                    bool certIgnore;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPCertIgnore"], out certIgnore))
                    {
                        certIgnore = true;
                    }

                    // pdf virtual printer redirection

                    // TOCHECK: for some reason, using the exact pdf virtual printer driver name ("PDF Scribe Virtual Printer") doesn't work (the printer doesn't show into the remote session) with wfreerdp, while it works with mstsc (!)
                    // it may have something to do with the driver not being installed on the remote server, but as the underlying driver is the standard "Microsoft Postscript Printer Driver (v3)" (pscript5.dll), it should have worked...
                    // as a workaround for now, the same way freerdp does in CUPS mode (printer redirection under Linux), it's possible to use the "MS Publisher Imagesetter" driver; it's also based on pscript5.dll and support basic print features (portrait/landscape orientation, custom fonts, color mode, etc.)

                    // as the rdp server uses the client numlock state, ensure it's off
                    // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                    SetNumLock(false);

                    // https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface
                    // Syntax: /flag enables flag, +toggle or -toggle enables or disables toggle. /toggle and +toggle are the same. Options with values work like this: /option:<value>
                    // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the rdp client through the inputs pipe
                    _process.StartInfo.Arguments =
                        "/myrtille-sid:" + _remoteSessionId +                                                                       // session id
                        (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                                       // session window
                        (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                                     // session log
                        " /w:" + clientWidth +                                                                                      // display width
                        " /h:" + clientHeight +                                                                                     // display height
                        " /bpp:" + bpp +                                                                                            // color depth
                        " /gdi:" + gdi +                                                                                            // gdi mode (sw: software, hw: hardware)
                        (wallpaper ? " +" : " -") + "wallpaper" +                                                                   // wallpaper
                        (aero ? " +" : " -") + "aero" +                                                                             // desktop composition
                        (windowDrag ? " +" : " -") + "window-drag" +                                                                // window drag
                        (menuAnims ? " +" : " -") + "menu-anims" +                                                                  // menu animations
                        (themes ? " +" : " -") + "themes" +                                                                         // themes
                        (smoothFonts ? " +" : " -") + "fonts" +                                                                     // smooth fonts (requires ClearType enabled on the remote server)
                        " +compression" +                                                                                           // bulk compression (level is autodetected from the rdp version)
                        (certIgnore ? " /cert-ignore" : string.Empty) +                                                             // ignore certificate warning (when using NLA)
                        (allowPrintDownload ? " /printer:\"Myrtille PDF\",\"MS Publisher Imagesetter\"" : string.Empty) +           // pdf virtual printer
                        " -mouse-motion" +                                                                                          // mouse motion
                        " +bitmap-cache" +                                                                                          // bitmap cache
                        " -offscreen-cache" +                                                                                       // offscreen cache
                        " +glyph-cache" +                                                                                           // glyph cache
                        " -async-input" +                                                                                           // async input
                        " -async-update" +                                                                                          // async update
                        " -async-channels" +                                                                                        // async channels
                        " -async-transport" +                                                                                       // async transport
                        (allowRemoteClipboard ? " +" : " -") + "clipboard" +                                                        // clipboard support
                        (securityProtocol != SecurityProtocolEnum.auto ? " /sec:" + securityProtocol.ToString() : string.Empty) +   // security protocol
                        " /audio-mode:2";                                                                                           // audio mode (not supported for now, 2: do not play)
                }

                #endregion

                #region SSH

                else
                {
                    _process.StartInfo.Arguments =
                        "/myrtille-sid:" + _remoteSessionId +                                                                       // session id
                        (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                                       // session window
                        (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                                     // session log
                        " /w:" + clientWidth +                                                                                      // display width
                        " /h:" + clientHeight;                                                                                      // display height
                }

                #endregion

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start the host client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }