Beispiel #1
0
        public RemoteSessionSocketHandler(HttpContext context, bool binary, string clientId, WebSocketDirection direction)
            : base()
        {
            _session  = context.Session;
            Binary    = binary;
            Direction = direction;

            try
            {
                if (context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)context.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                if (!_remoteSession.Manager.Clients.ContainsKey(clientId))
                {
                    lock (_remoteSession.Manager.ClientsLock)
                    {
                        _remoteSession.Manager.Clients.Add(clientId, new RemoteSessionClient(clientId));
                    }
                }

                _client = _remoteSession.Manager.Clients[clientId];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize socket handler ({0})", exc);
            }
        }
        public RemoteSessionManager(RemoteSession remoteSession)
        {
            try
            {
                RemoteSession = remoteSession;

                // remote session process client and callback
                var callback        = new RemoteSessionProcessClientCallback(this);
                var callbackContext = new InstanceContext(callback);
                Client = new RemoteSessionProcessClient(this, callbackContext);

                // pipes
                Pipes = new RemoteSessionPipes(RemoteSession);
                Pipes.ProcessUpdatesPipeMessage = ProcessUpdatesPipeMessage;

                // sockets
                WebSockets = new List <RemoteSessionSocketHandler>();

                // messages
                _messageEventLock = new object();

                // images
                _imageEventLock = new object();

                // cache
                _imageCache = (Cache)HttpContext.Current.Application[HttpApplicationStateVariables.Cache.ToString()];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize remote session manager, remote session {0} ({1})", RemoteSession.Id, exc);
            }
        }
Beispiel #3
0
        public RemoteSessionSocketHandler(HttpSessionState session, bool binaryMode)
            : base()
        {
            _session   = session;
            BinaryMode = binaryMode;

            try
            {
                if (session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)session[HttpSessionStateVariables.RemoteSession.ToString()];

                bool websocketBuffering;
                if (!bool.TryParse(ConfigurationManager.AppSettings["WebsocketBuffering"], out websocketBuffering))
                {
                    websocketBuffering = true;
                }

                // RDP: display updates are buffered to fit the client latency; buffer data is also invalidated past the image cache duration (default 1 sec) to avoid lag
                // SSH: terminal messages are unbuffered
                if (websocketBuffering && _remoteSession.HostType == HostTypeEnum.RDP)
                {
                    Buffer = new DataBuffer <int>(_bufferSize, _bufferDelay);
                    Buffer.SendBufferData = SendBufferData;
                }
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", session.SessionID, exc);
            }
        }
Beispiel #4
0
        public RemoteSessionEventSourceHandler(HttpContext context, string clientId)
        {
            _context = context;

            try
            {
                if (context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)context.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                if (!_remoteSession.Manager.Clients.ContainsKey(clientId))
                {
                    lock (_remoteSession.Manager.ClientsLock)
                    {
                        _remoteSession.Manager.Clients.Add(clientId, new RemoteSessionClient(clientId));
                    }
                }

                _client = _remoteSession.Manager.Clients[clientId];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize event source handler ({0})", exc);
            }
        }
Beispiel #5
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)
        {
            // retrieve the active enterprise session, if any
            if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] != null)
            {
                try
                {
                    _remoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                    if (_remoteSession.DisableSessionSharing(HttpContext.Current.Session.SessionID))
                    {
                        Response.Redirect("~/", true);
                    }

                    _remoteSession.SessionKey = Guid.NewGuid().ToString();
                    HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] = _remoteSession;

                    sessionUrl.Value = Request.Url.Scheme + "://" + Request.Url.Host + (Request.Url.Port != 80 && Request.Url.Port != 443 ? ":" + Request.Url.Port : "") + Request.ApplicationPath + "/?SSE=" + RDPCryptoHelper.GetSessionKey(_remoteSession.Id, HttpContext.Current.Session.SessionID, _remoteSession.SessionKey);
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                }
            }
            else
            {
                Response.Redirect("~/", true);
            }
        }
Beispiel #6
0
        /// <summary>
        /// retrieve a shared remote session
        /// </summary>
        /// <param name="guestGuid">guest guid</param>
        /// <returns></returns>
        private RemoteSession GetSharedRemoteSession(
            string guestGuid)
        {
            RemoteSession remoteSession = null;

            try
            {
                Application.Lock();

                var sharedSessions = (IDictionary <string, RemoteSession>)Application[HttpApplicationStateVariables.SharedRemoteSessions.ToString()];
                if (sharedSessions.ContainsKey(guestGuid))
                {
                    remoteSession = sharedSessions[guestGuid];
                    sharedSessions.Remove(guestGuid);
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the shared remote session ({0})", exc);
            }
            finally
            {
                Application.UnLock();
            }

            return(remoteSession);
        }
Beispiel #7
0
        /// <summary>
        /// initialization
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Init(
            object sender,
            EventArgs e)
        {
            try
            {
                // retrieve the active remote session, if any
                if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] != null)
                {
                    try
                    {
                        if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                        {
                            throw new NullReferenceException();
                        }

                        _remoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];
                    }
                    catch (Exception exc)
                    {
                        System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session ({0})", exc);
                    }
                }

                // ensure there is an active remote session
                // if a domain is specified, the roaming user profile is loaded from the Active Directory
                // file storage is synchronized with the user "My documents" folder (will use folder redirection if defined)
                // user credentials will be checked prior to any file operation
                // if possible, use SSL to communicate with the service
                if (_remoteSession != null && (_remoteSession.State == RemoteSessionState.Connecting || _remoteSession.State == RemoteSessionState.Connected) &&
                    (_remoteSession.ServerAddress.ToLower() == "localhost" || _remoteSession.ServerAddress == "127.0.0.1" || _remoteSession.ServerAddress == HttpContext.Current.Request.Url.Host || !string.IsNullOrEmpty(_remoteSession.UserDomain)) &&
                    !string.IsNullOrEmpty(_remoteSession.UserName) && !string.IsNullOrEmpty(_remoteSession.UserPassword))
                {
                    _fileStorageClient = new FileStorageClient();

                    var files = _fileStorageClient.GetUserDocumentsFolderFiles(
                        _remoteSession.Id,
                        _remoteSession.UserDomain,
                        _remoteSession.UserName,
                        _remoteSession.UserPassword);

                    if (files.Count > 0)
                    {
                        fileToDownloadSelect.DataSource = files;
                        fileToDownloadSelect.DataBind();
                        downloadFileButton.Disabled = false;
                    }
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to init file storage ({0})", exc);
            }
        }
Beispiel #8
0
        public RemoteSessionAudioSocketHandler(HttpContext context, bool binary)
            : base()
        {
            _context = context;
            Binary   = binary;

            try
            {
                if (context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)context.Session[HttpSessionStateVariables.RemoteSession.ToString()];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", context.Session.SessionID, exc);
                return;
            }

            var clientId = context.Session.SessionID;

            if (context.Request.Cookies[HttpRequestCookies.ClientKey.ToString()] != null)
            {
                clientId = context.Request.Cookies[HttpRequestCookies.ClientKey.ToString()].Value;
            }

            if (!_remoteSession.Manager.Clients.ContainsKey(clientId))
            {
                lock (_remoteSession.Manager.ClientsLock)
                {
                    _remoteSession.Manager.Clients.Add(clientId, new RemoteSessionClient(clientId));
                }
            }

            _client = _remoteSession.Manager.Clients[clientId];

            bool audioBuffering;

            if (!bool.TryParse(ConfigurationManager.AppSettings["AudioBuffering"], out audioBuffering))
            {
                audioBuffering = true;
            }

            // RDP: audio blocks are buffered for a seamless playback; buffer data is also invalidated past the audio cache duration (default 1,5 sec) in case of lag
            // SSH: no audio
            if (audioBuffering && _remoteSession.HostType == HostType.RDP)
            {
                Buffer = new DataBuffer <int>(_bufferCount, _bufferDelay);
                Buffer.SendBufferData = SendBufferData;
            }
        }
        public RemoteSessionManager(RemoteSession remoteSession)
        {
            try
            {
                RemoteSession = remoteSession;

                // remote session process client and callback
                var callback        = new RemoteSessionProcessClientCallback(this);
                var callbackContext = new InstanceContext(callback);
                HostClient = new RemoteSessionProcessClient(this, callbackContext);

                // pipes
                Pipes = new RemoteSessionPipes(RemoteSession);
                Pipes.ProcessUpdatesPipeMessage = ProcessUpdatesPipeMessage;

                // audio (RDP only)
                if (RemoteSession.HostType == HostType.RDP)
                {
                    Pipes.ProcessAudioPipeMessage = ProcessAudioPipeMessage;
                }

                // sockets
                WebSockets      = new List <RemoteSessionSocketHandler>();
                AudioWebSockets = new List <RemoteSessionAudioSocketHandler>();

                // messages
                MessageQueues = new Hashtable();

                // images event
                _imageEventLock = new object();

                // cache
                _cache = (Cache)HttpContext.Current.Application[HttpApplicationStateVariables.Cache.ToString()];

                // owner idle timeout
                if (!int.TryParse(ConfigurationManager.AppSettings["ClientIdleTimeout"], out _clientIdleTimeoutDelay))
                {
                    _clientIdleTimeoutDelay = 0;
                }

                if (_clientIdleTimeoutDelay > 0)
                {
                    ClientIdleTimeout = new CancellationTokenSource();
                }

                // guests idle timeout
                _guestsIdleTimeout     = new Dictionary <string, CancellationTokenSource>();
                _guestsIdleTimeoutLock = new object();
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize remote session manager, remote session {0} ({1})", RemoteSession.Id, exc);
            }
        }
        public RemoteSessionManager(RemoteSession remoteSession)
        {
            try
            {
                RemoteSession = remoteSession;

                // remote session process client and callback
                var callback        = new RemoteSessionProcessClientCallback(this);
                var callbackContext = new InstanceContext(callback);
                HostClient = new RemoteSessionProcessClient(this, callbackContext);

                // pipes
                Pipes = new RemoteSessionPipes(RemoteSession);
                Pipes.ProcessUpdatesPipeMessage = ProcessUpdatesPipeMessage;

                // sockets
                WebSockets = new List <RemoteSessionSocketHandler>();

                // messages
                MessageQueues = new Hashtable();

                // images event
                _imageEventLock = new object();

                // images cache
                _imageCache = (Cache)HttpContext.Current.Application[HttpApplicationStateVariables.Cache.ToString()];

                // browser resize
                if (!bool.TryParse(ConfigurationManager.AppSettings["ScaleOnResize"], out _scaleOnResize))
                {
                    _scaleOnResize = true;
                }

                if (!_scaleOnResize)
                {
                    _reconnectTimeout = new CancellationTokenSource();
                }

                // browser timeout
                if (!int.TryParse(ConfigurationManager.AppSettings["ClientIdleTimeout"], out _clientIdleTimeoutDelay))
                {
                    _clientIdleTimeoutDelay = 0;
                }

                if (_clientIdleTimeoutDelay > 0)
                {
                    ClientIdleTimeout = new CancellationTokenSource();
                }
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize remote session manager, remote session {0} ({1})", RemoteSession.Id, exc);
            }
        }
        /// <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.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                _remoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];

                // retrieve the pdf file
                if (!string.IsNullOrEmpty(Request["name"]))
                {
                    try
                    {
                        var fileStream = _printerServiceClient.GetPdfFile(_remoteSession.Id, Request["name"]);

                        // CAUTION! IE/Edge appears to have issues with inline documents
                        // for instance, it loads twice "application/pdf" documents (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6734131/),
                        // which is a problem because the document is deleted on retrieval to enforce security (the second request will thus fail)
                        // the idea behind inline content was to open the pdf in a new tab; it works on every browser but IE/Edge :/
                        // using attachment instead

                        //FileHelper.DownloadFile(Response, fileStream, Request["name"], true, "application/pdf", "inline");
                        FileHelper.DownloadFile(Response, fileStream, Request["name"], true, "application/pdf");
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after sending the pdf
                    }
                    catch (Exception exc)
                    {
                        System.Diagnostics.Trace.TraceError("Failed to download pdf file ({0})", exc);
                    }
                    finally
                    {
                        // remove the pdf file
                        _printerServiceClient.DeletePdfFile(_remoteSession.Id, Request["name"]);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                // occurs because the response is ended after deleting the pdf
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
            }
        }
Beispiel #12
0
        /// <summary>
        /// retrieve an image update (region or fullscreen) from the rdp session and send it to the browser
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(
            object sender,
            EventArgs e)
        {
            // if cookies are enabled, the http session id is added to the http request headers; otherwise, it's added to the http request url
            // in both cases, the given http session is automatically bound to the current http context

            RemoteSession remoteSession = null;

            try
            {
                if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the current http session
                remoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                return;
            }

            try
            {
                // retrieve params
                var imgIdx = int.Parse(HttpContext.Current.Request.QueryString["imgIdx"]);

                // retrieve image data
                var img = remoteSession.Manager.GetCachedUpdate(imgIdx);

                // if the image isn't available (removed from cache?), request a fullscreen update (resync display)
                if (img == null)
                {
                    remoteSession.Manager.SendCommand(RemoteSessionCommand.RequestFullscreenUpdate);
                }

                var imgData = img != null ? img.Data : null;
                if (imgData != null && imgData.Length > 0)
                {
                    // write the output
                    HttpContext.Current.Response.OutputStream.Write(imgData, 0, imgData.Length);
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to get display update, remote session {0} ({1})", remoteSession.Id, exc);
            }
        }
Beispiel #13
0
        public RemoteSessionEventSourceHandler(HttpContext context)
        {
            _context = context;
            Session  = context.Session;

            try
            {
                if (_context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)_context.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                // register the handler against the remote session manager
                lock (((ICollection)_remoteSession.Manager.EventSources).SyncRoot)
                {
                    // search for a previously registered handler
                    RemoteSessionEventSourceHandler oldEventSource = null;

                    foreach (var eventSource in _remoteSession.Manager.EventSources)
                    {
                        if (eventSource.Session.SessionID == _context.Session.SessionID)
                        {
                            oldEventSource = eventSource;
                            break;
                        }
                    }

                    // unregister the previous handler, if any
                    if (oldEventSource != null)
                    {
                        _remoteSession.Manager.EventSources.Remove(oldEventSource);
                    }

                    // register this handler
                    _remoteSession.Manager.EventSources.Add(this);
                }

                // mime type for event source
                _context.Response.ContentType = "text/event-stream";
                _context.Response.Headers.Add("Content-Type", "text/event-stream\n\n");
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", _context.Session.SessionID, exc);
            }
        }
        public RemoteSessionLongPollingHandler(HttpContext context)
        {
            _context = context;
            Session  = context.Session;

            try
            {
                if (_context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)_context.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                // register the handler against the remote session manager
                lock (((ICollection)_remoteSession.Manager.LongPollings).SyncRoot)
                {
                    // search for a previously registered handler
                    RemoteSessionLongPollingHandler oldLongPolling = null;

                    foreach (var longPolling in _remoteSession.Manager.LongPollings)
                    {
                        if (longPolling.Session.SessionID == _context.Session.SessionID)
                        {
                            oldLongPolling = longPolling;
                            break;
                        }
                    }

                    // unregister the previous handler, if any
                    if (oldLongPolling != null)
                    {
                        _remoteSession.Manager.LongPollings.Remove(oldLongPolling);
                    }

                    // register this handler
                    _remoteSession.Manager.LongPollings.Add(this);
                }

                // the handler is ready to push data
                Send("<script>parent.lpInitConnection();</script>");
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", _context.Session.SessionID, exc);
            }
        }
Beispiel #15
0
        public RemoteSessionManager(RemoteSession remoteSession)
        {
            try
            {
                RemoteSession = remoteSession;

                // remote session process client and callback
                var callback        = new RemoteSessionProcessClientCallback(this, HttpContext.Current.Application);
                var callbackContext = new InstanceContext(callback);
                HostClient = new RemoteSessionProcessClient(this, callbackContext);

                // clients
                Clients     = new Dictionary <string, RemoteSessionClient>();
                ClientsLock = new object();

                // pipes
                Pipes = new RemoteSessionPipes(RemoteSession);

                // images event
                _imageEventLock = new object();

                // cache
                _cache = (Cache)HttpContext.Current.Application[HttpApplicationStateVariables.Cache.ToString()];

                // owner idle timeout
                if (!int.TryParse(ConfigurationManager.AppSettings["OwnerIdleTimeout"], out _ownerIdleTimeoutDelay))
                {
                    _ownerIdleTimeoutDelay = 0;
                }

                if (_ownerIdleTimeoutDelay > 0)
                {
                    OwnerIdleTimeout = new CancellationTokenSource();
                }

                // guests idle timeout
                _guestsIdleTimeout     = new Dictionary <string, CancellationTokenSource>();
                _guestsIdleTimeoutLock = new object();

                // clients idle timeout
                _clientsIdleTimeout     = new Dictionary <string, CancellationTokenSource>();
                _clientsIdleTimeoutLock = new object();
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to initialize remote session manager, remote session {0} ({1})", RemoteSession?.Id, exc);
            }
        }
        /// <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 (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                _remoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];

                try
                {
                    Application.Lock();

                    // if remote session sharing is enabled, only the remote session owner can share it
                    if (!_remoteSession.AllowSessionSharing || !HttpContext.Current.Session.SessionID.Equals(_remoteSession.OwnerSessionID))
                    {
                        Response.Redirect("~/", true);
                    }

                    // create a new guest for the remote session
                    var sharedSessions = (IDictionary <string, RemoteSession>)Application[HttpApplicationStateVariables.SharedRemoteSessions.ToString()];
                    var guestGuid      = Guid.NewGuid().ToString();
                    sharedSessions.Add(guestGuid, _remoteSession);
                    sessionUrl.Value = Request.Url.Scheme + "://" + Request.Url.Host + (Request.Url.Port != 80 && Request.Url.Port != 443 ? ":" + Request.Url.Port : "") + Request.ApplicationPath + "/?SSE=" + guestGuid;
                }
                catch (ThreadAbortException)
                {
                    // occurs because the response is ended after redirect
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to generate a session sharing url ({0})", exc);
                }
                finally
                {
                    Application.UnLock();
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
            }
        }
Beispiel #17
0
        /// <summary>
        /// disconnect the remote server
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DisconnectButtonClick(
            object sender,
            EventArgs e)
        {
            if (!_authorizedRequest)
            {
                return;
            }

            // disconnect the active remote session, if any and connecting/connected
            if (RemoteSession != null && (RemoteSession.State == RemoteSessionState.Connecting || RemoteSession.State == RemoteSessionState.Connected))
            {
                try
                {
                    // prevent the remote session from being disconnected by a guest
                    if (Session.SessionID.Equals(RemoteSession.OwnerSessionID))
                    {
                        RemoteSession.State = RemoteSessionState.Disconnecting;
                        RemoteSession.Manager.SendCommand(RemoteSessionCommand.CloseClient);
                    }
                    else
                    {
                        Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                        RemoteSession = null;
                    }

                    // logout the enterprise session if single use only
                    if (_enterpriseSession != null && _enterpriseSession.SingleUseConnection)
                    {
                        LogoutButtonClick(this, EventArgs.Empty);
                    }

                    // enterprise mode: redirect to the hosts list
                    // standard mode: redirect to the login screen
                    Response.Redirect("~/", true);
                }
                catch (ThreadAbortException)
                {
                    // occurs because the response is ended after redirect
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to disconnect the remote session {0} ({1})", RemoteSession.Id, exc);
                }
            }
        }
Beispiel #18
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.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                _remoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];

                // retrieve the pdf file
                if (!string.IsNullOrEmpty(Request["name"]))
                {
                    try
                    {
                        var fileStream = _printerClient.GetPdfFile(_remoteSession.Id, Request["name"]);
                        FileHelper.DownloadFile(Response, fileStream, Request["name"], true, "application/pdf", Request["disposition"]);
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after sending the pdf
                    }
                    catch (Exception exc)
                    {
                        System.Diagnostics.Trace.TraceError("Failed to download pdf file ({0})", exc);
                    }
                    finally
                    {
                        // remove the pdf file
                        _printerClient.DeletePdfFile(_remoteSession.Id, Request["name"]);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                // occurs because the response is ended after deleting the pdf
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
            }
        }
Beispiel #19
0
        /// <summary>
        /// retrieve an image update (region or fullscreen) from the remote session and send it to the browser
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(
            object sender,
            EventArgs e)
        {
            // if cookies are enabled, the http session id is added to the http request headers; otherwise, it's added to the http request url
            // in both cases, the given http session is automatically bound to the current http context

            RemoteSession remoteSession = null;

            try
            {
                if (Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the current http session
                remoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];

                try
                {
                    // retrieve params
                    var imgIdx = int.Parse(Request.QueryString["imgIdx"]);

                    // retrieve image data
                    var img     = remoteSession.Manager.GetCachedUpdate(imgIdx);
                    var imgData = img != null ? img.Data : null;
                    if (imgData != null && imgData.Length > 0)
                    {
                        // write the output
                        Response.OutputStream.Write(imgData, 0, imgData.Length);
                    }
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve display update, remote session {0} ({1})", remoteSession.Id, exc);
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
            }
        }
Beispiel #20
0
        /// <summary>
        /// retrieve the mouse cursor from the rdp session and send it to the browser
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(
            object sender,
            EventArgs e)
        {
            // if cookies are enabled, the http session id is added to the http request headers; otherwise, it's added to the http request url
            // in both cases, the given http session is automatically bound to the current http context

            RemoteSession remoteSession = null;

            try
            {
                if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the current http session
                remoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                return;
            }

            try
            {
                // retrieve params
                var imgIdx = int.Parse(HttpContext.Current.Request.QueryString["imgIdx"]);

                // retrieve image data
                var img     = remoteSession.Manager.GetCachedUpdate(imgIdx);
                var imgData = img != null ? img.Data : null;
                if (imgData != null && imgData.Length > 0)
                {
                    CreateCursorFromImage(img.Width, img.Height, img.PosX, img.PosY, imgData, Response.OutputStream);
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to get mouse cursor, remote session {0} ({1})", remoteSession.Id, exc);
            }
        }
Beispiel #21
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)
        {
            // prevent session fixation or stealing
            SessionFixationHandler();

            // retrieve the active enterprise session, if any
            if (HttpContext.Current.Session[HttpSessionStateVariables.EnterpriseSession.ToString()] != null)
            {
                try
                {
                    _enterpriseSession = (EnterpriseSession)HttpContext.Current.Session[HttpSessionStateVariables.EnterpriseSession.ToString()];
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve the enterprise session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                }
            }

            // retrieve the active remote session, if any
            if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] != null)
            {
                try
                {
                    RemoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                }
            }

            // postback events may redirect after execution; UI is updated from there
            if (!IsPostBack)
            {
                UpdateControls();
            }

            // disable the browser cache; in addition to a "noCache" dummy param, with current time, on long-polling and xhr requests
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.Cache.SetNoStore();
        }
Beispiel #22
0
        public RemoteSessionSocketHandler(HttpSessionState session, bool binaryMode)
            : base()
        {
            BinaryMode = binaryMode;

            try
            {
                if (session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)session[HttpSessionStateVariables.RemoteSession.ToString()];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", session.SessionID, exc);
            }
        }
        public RemoteSessionAudioSocketHandler(HttpSessionState session, bool binaryMode)
            : base()
        {
            _session   = session;
            BinaryMode = binaryMode;

            try
            {
                if (session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                if (!BinaryMode)
                {
                    throw new Exception("Audio requires a binary websocket (HTML5 standard)");
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)session[HttpSessionStateVariables.RemoteSession.ToString()];

                bool audioBuffering;
                if (!bool.TryParse(ConfigurationManager.AppSettings["AudioBuffering"], out audioBuffering))
                {
                    audioBuffering = true;
                }

                // RDP: audio blocks are buffered for a seamless playback; buffer data is also invalidated past the audio cache duration (default 1,5 sec) in case of lag
                // SSH: no audio
                if (audioBuffering && _remoteSession.HostType == HostType.RDP)
                {
                    Buffer = new DataBuffer <int>(_bufferCount, _bufferDelay);
                    Buffer.SendBufferData = SendBufferData;
                }
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", session.SessionID, exc);
            }
        }
Beispiel #24
0
        public RemoteSessionSocketHandler(HttpContext context, bool binary, WebSocketDirection direction)
            : base()
        {
            _session  = context.Session;
            Binary    = binary;
            Direction = direction;

            try
            {
                if (context.Session[HttpSessionStateVariables.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                // retrieve the remote session for the given http session
                _remoteSession = (RemoteSession)context.Session[HttpSessionStateVariables.RemoteSession.ToString()];
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", context.Session.SessionID, exc);
                return;
            }

            var clientId = context.Session.SessionID;

            if (context.Request.Cookies[HttpRequestCookies.ClientKey.ToString()] != null)
            {
                clientId = context.Request.Cookies[HttpRequestCookies.ClientKey.ToString()].Value;
            }

            if (!_remoteSession.Manager.Clients.ContainsKey(clientId))
            {
                lock (_remoteSession.Manager.ClientsLock)
                {
                    _remoteSession.Manager.Clients.Add(clientId, new RemoteSessionClient(clientId));
                }
            }

            _client = _remoteSession.Manager.Clients[clientId];
        }
Beispiel #25
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.RemoteSession.ToString()] == null)
                {
                    throw new NullReferenceException();
                }

                _remoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];

                // if remote session sharing is enabled, only the remote session owner can share it
                if (!_remoteSession.AllowSessionSharing || !Session.SessionID.Equals(_remoteSession.OwnerSessionID))
                {
                    Response.Redirect("~/", true);
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
            }
        }
Beispiel #26
0
        /// <summary>
        /// initialization
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(
            object sender,
            EventArgs e)
        {
            #region session fixation attack

            // prevent session fixation attack by generating a new session ID upon login
            // https://www.owasp.org/index.php/Session_Fixation
            if (!string.IsNullOrEmpty(HttpContext.Current.Request["oldSID"]))
            {
                try
                {
                    HttpContext.Current.Application.Lock();

                    // retrieve the given (old) http session
                    var httpSessions = (IDictionary <string, HttpSessionState>)HttpContext.Current.Application[HttpApplicationStateVariables.HttpSessions.ToString()];
                    var httpSession  = httpSessions[HttpContext.Current.Request["oldSID"]];

                    // retrieve the remote session bound to it
                    var remoteSession = httpSession[HttpSessionStateVariables.RemoteSession.ToString()];

                    // unbind it from the old http session
                    httpSession[HttpSessionStateVariables.RemoteSession.ToString()] = null;

                    // bind it to the new http session
                    HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] = remoteSession;

                    // cancel the old http session
                    httpSession.Abandon();

                    // unregister it at application level
                    httpSessions.Remove(httpSession.SessionID);
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to generate a new http session upon login ({0})", exc);
                }
                finally
                {
                    HttpContext.Current.Application.UnLock();
                }
            }

            #endregion

            try
            {
                // retrieve the active remote session, if any
                if (HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] != null)
                {
                    try
                    {
                        RemoteSession = (RemoteSession)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()];
                    }
                    catch (Exception exc)
                    {
                        System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc);
                    }
                }

                // update controls
                UpdateControls();

                // disable the browser cache; in addition to a "noCache" dummy param, with current time, on long-polling and xhr requests
                Response.Cache.SetCacheability(HttpCacheability.NoCache);
                Response.Cache.SetNoStore();
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to load myrtille ({0})", exc);
            }
        }
Beispiel #27
0
        /// <summary>
        /// start the rdp session
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ConnectButtonClick(
            object sender,
            EventArgs e)
        {
            // remove the active remote session, if any (disconnected?)
            if (RemoteSession != null)
            {
                try
                {
                    // unset the remote session for the current http session
                    HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to remove remote session ({0})", exc);
                }
                finally
                {
                    RemoteSession = null;
                }
            }

            // create a new remote session
            try
            {
                HttpContext.Current.Application.Lock();

                // auto-increment the remote sessions counter
                // note that it doesn't really count the active remote sessions... it's just an auto-increment for the remote session id, ensuring it's unique...
                var remoteSessionsCounter = (int)HttpContext.Current.Application[HttpApplicationStateVariables.RemoteSessionsCounter.ToString()];
                remoteSessionsCounter++;

                // create the remote session
                RemoteSession = new RemoteSession
                {
                    Id            = remoteSessionsCounter,
                    State         = RemoteSessionState.NotConnected,
                    ServerAddress = string.IsNullOrEmpty(server.Value) ? "localhost" : server.Value,
                    UserDomain    = domain.Value,
                    UserName      = user.Value,
                    UserPassword  = string.IsNullOrEmpty(passwordHash.Value) ? password.Value : RDPCryptoHelper.DecryptPassword(passwordHash.Value),
                    ClientWidth   = int.Parse(width.Value),
                    ClientHeight  = int.Parse(height.Value),
                    Program       = program.Value
                };

                // set the remote session for the current http session
                HttpContext.Current.Session[HttpSessionStateVariables.RemoteSession.ToString()] = RemoteSession;

                // register the http session at application level
                var httpSessions = (IDictionary <string, HttpSessionState>)HttpContext.Current.Application[HttpApplicationStateVariables.HttpSessions.ToString()];
                httpSessions[HttpContext.Current.Session.SessionID] = HttpContext.Current.Session;

                // update the remote sessions auto-increment counter
                HttpContext.Current.Application[HttpApplicationStateVariables.RemoteSessionsCounter.ToString()] = remoteSessionsCounter;
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to create remote session ({0})", exc);
                RemoteSession = null;
            }
            finally
            {
                HttpContext.Current.Application.UnLock();
            }

            // connect it
            if (RemoteSession != null)
            {
                try
                {
                    // update the remote session state
                    RemoteSession.State = RemoteSessionState.Connecting;

                    // create pipes for the web gateway and the rdp client to talk
                    RemoteSession.Manager.Pipes.CreatePipes();

                    // the rdp client does connect the pipes when it starts; when it stops (either because it was closed, crashed or because the rdp session had ended), pipes are released
                    // 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
                    // use http://technet.microsoft.com/en-us/sysinternals/dd581625 to track the existing pipes
                    RemoteSession.Manager.Client.StartProcess(
                        RemoteSession.Id,
                        RemoteSession.ClientWidth,
                        RemoteSession.ClientHeight);

                    // update controls
                    UpdateControls();
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to connect the remote session {0} ({1})", RemoteSession.Id, exc);
                }
            }
        }
Beispiel #28
0
        /// <summary>
        /// connect the remote server
        /// </summary>
        /// <remarks>
        /// authentication is delegated to the remote server or connection broker (if applicable)
        /// </remarks>
        private bool ConnectRemoteServer()
        {
            // connection parameters
            string loginHostName       = null;
            var    loginHostType       = (HostType)Convert.ToInt32(hostType.Value);
            var    loginProtocol       = (SecurityProtocol)securityProtocol.SelectedIndex;
            var    loginServer         = string.IsNullOrEmpty(server.Value) ? "localhost" : server.Value;
            var    loginVMGuid         = vmGuid.Value;
            var    loginVMAddress      = string.Empty;
            var    loginVMEnhancedMode = vmEnhancedMode.Checked;
            var    loginDomain         = domain.Value;
            var    loginUser           = user.Value;
            var    loginPassword       = string.IsNullOrEmpty(passwordHash.Value) ? password.Value : CryptoHelper.RDP_Decrypt(passwordHash.Value);
            var    startProgram        = program.Value;

            // allowed features
            var allowRemoteClipboard = _allowRemoteClipboard;
            var allowFileTransfer    = _allowFileTransfer;
            var allowPrintDownload   = _allowPrintDownload;
            var allowSessionSharing  = _allowSessionSharing;
            var allowAudioPlayback   = _allowAudioPlayback;

            // sharing parameters
            int maxActiveGuests = int.MaxValue;

            var connectionId = Guid.NewGuid();

            // connect an host from the hosts list or from a one time session url
            if (_enterpriseSession != null && (!string.IsNullOrEmpty(Request["SD"])))
            {
                long hostId;
                if (!long.TryParse(Request["SD"], out hostId))
                {
                    hostId = 0;
                }

                try
                {
                    // retrieve the host connection details
                    var connection = _enterpriseClient.GetSessionConnectionDetails(_enterpriseSession.SessionID, hostId, _enterpriseSession.SessionKey);
                    if (connection == null)
                    {
                        System.Diagnostics.Trace.TraceInformation("Unable to retrieve host {0} connection details (invalid host or one time session url already used?)", hostId);
                        return(false);
                    }

                    loginHostName       = connection.HostName;
                    loginHostType       = connection.HostType;
                    loginProtocol       = connection.Protocol;
                    loginServer         = !string.IsNullOrEmpty(connection.HostAddress) ? connection.HostAddress : connection.HostName;
                    loginVMGuid         = connection.VMGuid;
                    loginVMEnhancedMode = connection.VMEnhancedMode;
                    loginDomain         = connection.Domain;
                    loginUser           = connection.Username;
                    loginPassword       = CryptoHelper.RDP_Decrypt(connection.Password);
                    startProgram        = connection.StartRemoteProgram;
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve host {0} connection details ({1})", hostId, exc);
                    return(false);
                }
            }
            // by using a connection service on a backend (connection API), the connection details can be hidden from querystring and mapped to a connection identifier
            else if (!string.IsNullOrEmpty(Request["cid"]))
            {
                if (!Guid.TryParse(Request["cid"], out connectionId))
                {
                    System.Diagnostics.Trace.TraceInformation("Invalid connection id {0}", Request["cid"]);
                    return(false);
                }

                try
                {
                    // retrieve the connection details
                    var connection = _connectionClient.GetConnectionInfo(connectionId);
                    if (connection == null)
                    {
                        System.Diagnostics.Trace.TraceInformation("Unable to retrieve connection info {0}", connectionId);
                        return(false);
                    }

                    // ensure the user is allowed to connect the host
                    if (!_connectionClient.IsUserAllowedToConnectHost(connection.User.Domain, connection.User.UserName, connection.Host.IPAddress, connection.VM != null ? connection.VM.Guid : Guid.Empty))
                    {
                        System.Diagnostics.Trace.TraceInformation("User: domain={0}, name={1} is not allowed to connect host {2}", connection.User.Domain, connection.User.UserName, connection.Host.IPAddress);
                        return(false);
                    }

                    loginHostType = connection.Host.HostType;
                    loginProtocol = connection.Host.SecurityProtocol;
                    loginServer   = connection.Host.IPAddress;
                    loginVMGuid   = connection.VM != null?connection.VM.Guid.ToString() : string.Empty;

                    loginVMAddress      = connection.VM != null ? connection.VM.IPAddress : string.Empty;
                    loginVMEnhancedMode = connection.VM != null ? connection.VM.EnhancedMode : false;
                    loginDomain         = connection.User.Domain;
                    loginUser           = connection.User.UserName;
                    loginPassword       = connection.User.Password;
                    startProgram        = connection.StartProgram;

                    allowRemoteClipboard = allowRemoteClipboard && connection.AllowRemoteClipboard;
                    allowFileTransfer    = allowFileTransfer && connection.AllowFileTransfer;
                    allowPrintDownload   = allowPrintDownload && connection.AllowPrintDownload;
                    allowSessionSharing  = allowSessionSharing && connection.MaxActiveGuests > 0;
                    allowAudioPlayback   = allowAudioPlayback && connection.AllowAudioPlayback;

                    maxActiveGuests = connection.MaxActiveGuests;
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve connection info {0} ({1})", connectionId, exc);
                    return(false);
                }
            }
            // if the connection from login screen or url is disabled, the connection must be done either by using a connection API or from the enterprise mode
            else if (!_loginEnabled)
            {
                return(false);
            }

            // remove any active remote session (disconnected?)
            if (RemoteSession != null)
            {
                // unset the remote session for the current http session
                Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                RemoteSession = null;
            }

            // create a new remote session
            try
            {
                Application.Lock();

                // create the remote session
                RemoteSession = new RemoteSession(
                    connectionId,
                    loginHostName,
                    loginHostType,
                    loginProtocol,
                    loginServer,
                    loginVMGuid,
                    loginVMAddress,
                    loginVMEnhancedMode,
                    !string.IsNullOrEmpty(loginDomain) ? loginDomain : AccountHelper.GetDomain(loginUser, loginPassword),
                    AccountHelper.GetUserName(loginUser),
                    loginPassword,
                    int.Parse(width.Value),
                    int.Parse(height.Value),
                    startProgram,
                    allowRemoteClipboard,
                    allowFileTransfer,
                    allowPrintDownload,
                    allowSessionSharing,
                    allowAudioPlayback,
                    maxActiveGuests,
                    Session.SessionID,
                    (string)Session[HttpSessionStateVariables.ClientKey.ToString()],
                    Request["cid"] != null
                    );

                // bind the remote session to the current http session
                Session[HttpSessionStateVariables.RemoteSession.ToString()] = RemoteSession;

                // register the remote session at the application level
                var remoteSessions = (IDictionary <Guid, RemoteSession>)Application[HttpApplicationStateVariables.RemoteSessions.ToString()];
                remoteSessions.Add(RemoteSession.Id, RemoteSession);
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to create remote session ({0})", exc);
                RemoteSession = null;
            }
            finally
            {
                Application.UnLock();
            }

            // connect it
            if (RemoteSession != null)
            {
                RemoteSession.State = RemoteSessionState.Connecting;
            }
            else
            {
                connectError.InnerText = "Failed to create remote session!";
                return(false);
            }

            return(true);
        }
Beispiel #29
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)
        {
            // client ip protection
            if (_clientIPTracking)
            {
                var clientIP = ClientIPHelper.ClientIPFromRequest(new HttpContextWrapper(HttpContext.Current).Request, true, new string[] { });
                if (Session[HttpSessionStateVariables.ClientIP.ToString()] == null)
                {
                    Session[HttpSessionStateVariables.ClientIP.ToString()] = clientIP;
                }
                else if (!((string)Session[HttpSessionStateVariables.ClientIP.ToString()]).Equals(clientIP))
                {
                    System.Diagnostics.Trace.TraceWarning("Failed to validate the client ip");
                    _authorizedRequest = false;
                    UpdateControls();
                    return;
                }
            }

            // session spoofing protection
            if (_cookielessSession)
            {
                if (Request.Cookies["clientKey"] == null)
                {
                    if (Session[HttpSessionStateVariables.ClientKey.ToString()] == null)
                    {
                        var cookie = new HttpCookie("clientKey");
                        cookie.Value = Guid.NewGuid().ToString();
                        cookie.Path  = "/";
                        Response.Cookies.Add(cookie);
                    }
                    else
                    {
                        System.Diagnostics.Trace.TraceWarning("Failed to validate the client key: missing key");
                        _authorizedRequest = false;
                        UpdateControls();
                        return;
                    }
                }
                else
                {
                    var clientKey = Request.Cookies["clientKey"].Value;
                    if (Session[HttpSessionStateVariables.ClientKey.ToString()] == null)
                    {
                        Session[HttpSessionStateVariables.ClientKey.ToString()] = clientKey;
                    }
                    else if (!((string)Session[HttpSessionStateVariables.ClientKey.ToString()]).Equals(clientKey))
                    {
                        System.Diagnostics.Trace.TraceWarning("Failed to validate the client key: key mismatch");
                        _authorizedRequest = false;
                        UpdateControls();
                        return;
                    }
                }
            }

            // retrieve the active enterprise session, if any
            if (Session[HttpSessionStateVariables.EnterpriseSession.ToString()] != null)
            {
                try
                {
                    _enterpriseSession = (EnterpriseSession)Session[HttpSessionStateVariables.EnterpriseSession.ToString()];
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve the active enterprise session ({0})", exc);
                }
            }

            // retrieve the active remote session, if any
            if (Session[HttpSessionStateVariables.RemoteSession.ToString()] != null)
            {
                try
                {
                    RemoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];

                    if (RemoteSession.State == RemoteSessionState.Disconnected)
                    {
                        // handle connection failure
                        ClientScript.RegisterClientScriptBlock(GetType(), Guid.NewGuid().ToString(), string.Format("handleRemoteSessionExit({0});", RemoteSession.ExitCode), true);

                        // cleanup
                        Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                        RemoteSession = null;
                    }
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve the active remote session ({0})", exc);
                }
            }
            // retrieve a shared remote session from url, if any
            else if (Request["SSE"] != null)
            {
                Session[HttpSessionStateVariables.RemoteSession.ToString()] = GetSharedRemoteSession(Request["SSE"]);

                try
                {
                    // remove the shared session guid from url
                    Response.Redirect("~/", true);
                }
                catch (ThreadAbortException)
                {
                    // occurs because the response is ended after redirect
                }
            }

            // postback events may redirect after execution; UI is updated from there
            if (!IsPostBack)
            {
                UpdateControls();
            }

            // disable the browser cache; in addition to a "noCache" dummy param, with current time, on long-polling and xhr requests
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.Cache.SetNoStore();
        }
Beispiel #30
0
        /// <summary>
        /// connect the remote server
        /// </summary>
        /// <remarks>
        /// authentication is delegated to the remote server or connection broker (if applicable)
        /// </remarks>
        private bool ConnectRemoteServer()
        {
            // connection parameters
            string loginHostName       = null;
            var    loginHostType       = (HostTypeEnum)Convert.ToInt32(hostType.Value);
            var    loginProtocol       = (SecurityProtocolEnum)securityProtocol.SelectedIndex;
            var    loginServer         = string.IsNullOrEmpty(server.Value) ? "localhost" : server.Value;
            var    loginVMGuid         = vmGuid.Value;
            var    loginVMEnhancedMode = vmEnhancedMode.Checked;
            var    loginDomain         = domain.Value;
            var    loginUser           = user.Value;
            var    loginPassword       = string.IsNullOrEmpty(passwordHash.Value) ? password.Value : RDPCryptoHelper.DecryptPassword(passwordHash.Value);
            var    startProgram        = program.Value;

            // connect an host from the hosts list or from a one time session url
            if (_enterpriseSession != null && Request["SD"] != null)
            {
                long hostId;
                if (!long.TryParse(Request["SD"], out hostId))
                {
                    hostId = 0;
                }

                try
                {
                    // retrieve the host connection details
                    var connection = _enterpriseClient.GetSessionConnectionDetails(_enterpriseSession.SessionID, hostId, _enterpriseSession.SessionKey);
                    if (connection == null)
                    {
                        System.Diagnostics.Trace.TraceInformation("Unable to retrieve host {0} connection details (invalid host or one time session url already used?)", hostId);
                        return(false);
                    }
                    loginHostName       = connection.HostName;
                    loginHostType       = connection.HostType;
                    loginProtocol       = connection.Protocol;
                    loginServer         = !string.IsNullOrEmpty(connection.HostAddress) ? connection.HostAddress : connection.HostName;
                    loginVMGuid         = connection.VMGuid;
                    loginVMEnhancedMode = connection.VMEnhancedMode;
                    loginDomain         = connection.Domain;
                    loginUser           = connection.Username;
                    loginPassword       = RDPCryptoHelper.DecryptPassword(connection.Password);
                    startProgram        = connection.StartRemoteProgram;
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to retrieve host {0} connection details ({1})", hostId, exc);
                    return(false);
                }
            }

            // remove any active remote session (disconnected?)
            if (RemoteSession != null)
            {
                // unset the remote session for the current http session
                Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                RemoteSession = null;
            }

            // create a new remote session
            try
            {
                // create the remote session
                RemoteSession = new RemoteSession(
                    Guid.NewGuid(),
                    RemoteSessionState.NotConnected,
                    loginHostName,
                    loginHostType,
                    loginProtocol,
                    loginServer,
                    loginVMGuid,
                    loginVMEnhancedMode,
                    loginDomain,
                    loginUser,
                    loginPassword,
                    int.Parse(width.Value),
                    int.Parse(height.Value),
                    startProgram,
                    _allowRemoteClipboard,
                    _allowFileTransfer,
                    _allowPrintDownload,
                    _allowSessionSharing,
                    Session.SessionID
                    );

                // bind the remote session to the current http session
                Session[HttpSessionStateVariables.RemoteSession.ToString()] = RemoteSession;
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to create remote session ({0})", exc);
                RemoteSession = null;
            }

            // connect it
            if (RemoteSession != null)
            {
                try
                {
                    // update the remote session state
                    RemoteSession.State = RemoteSessionState.Connecting;

                    // create pipes for the web gateway and the host client to talk
                    RemoteSession.Manager.Pipes.CreatePipes();

                    // the host client does connect the pipes when it starts; when it stops (either because it was closed, crashed or because the remote session had ended), pipes are released
                    // 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 host client through the inputs pipe
                    // use http://technet.microsoft.com/en-us/sysinternals/dd581625 to track the existing pipes
                    RemoteSession.Manager.HostClient.StartProcess(
                        RemoteSession.Id,
                        RemoteSession.HostType,
                        RemoteSession.SecurityProtocol,
                        RemoteSession.ServerAddress,
                        RemoteSession.VMGuid,
                        RemoteSession.UserDomain,
                        RemoteSession.UserName,
                        RemoteSession.StartProgram,
                        RemoteSession.ClientWidth,
                        RemoteSession.ClientHeight,
                        RemoteSession.AllowRemoteClipboard,
                        RemoteSession.AllowPrintDownload);
                }
                catch (Exception exc)
                {
                    System.Diagnostics.Trace.TraceError("Failed to connect the remote session {0} ({1})", RemoteSession.Id, exc);
                    connectError.InnerText = "Failed to connect! ensure myrtille services are running";
                    return(false);
                }
            }
            else
            {
                connectError.InnerText = "Failed to create remote session!";
                return(false);
            }

            return(true);
        }