コード例 #1
0
        /// <summary>
        /// authenticate the user against the enterprise active directory and list the servers available to the user
        /// </summary>
        private void CreateEnterpriseSessionFromLogin()
        {
            try
            {
                // authenticate the user against the enterprise active directory
                _enterpriseSession = _enterpriseClient.Authenticate(user.Value, password.Value);

                if (_enterpriseSession.AuthenticationErrorCode != EnterpriseAuthenticationErrorCode.NONE)
                {
                    if (_enterpriseSession.AuthenticationErrorCode == EnterpriseAuthenticationErrorCode.PASSWORD_EXPIRED)
                    {
                        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), Guid.NewGuid().ToString(), string.Format("openPopup('changePasswordPopup', 'EnterpriseChangePassword.aspx?userId={0}');", user.Value), true);
                    }
                    else
                    {
                        connectError.InnerText = EnterpriseAuthenticationErrorHelper
                                                 .GetErrorDescription(_enterpriseSession.AuthenticationErrorCode);
                    }
                    UpdateControls();
                    return;
                }

                _enterpriseSession.ClientRemoteIP = ClientIPHelper.ClientIPFromRequest(new HttpContextWrapper(HttpContext.Current).Request, true, new string[] { });

                // bind the enterprise session to the current http session
                HttpContext.Current.Session[HttpSessionStateVariables.EnterpriseSession.ToString()] = _enterpriseSession;

                // prevent session fixation attack by generating a new session ID upon login
                // also, using http get method to prevent the browser asking for http post data confirmation if the page is reloaded
                // https://www.owasp.org/index.php/Session_Fixation
                Response.Redirect(string.Format("?oldSID={0}", HttpContext.Current.Session.SessionID), true);
            }
            catch (ThreadAbortException)
            {
                // occurs because the response is ended after redirect
            }
            catch (Exception exc)
            {
                System.Diagnostics.Trace.TraceError("Failed to create enterprise session from login ({0})", exc);
            }
        }
コード例 #2
0
        /// <summary>
        /// enterprise mode from url: load the enterprise session (from querystring param) and proceed to connection; the user is non admin and the url is only usable once
        /// enterprise mode from login: authenticate the user against the enterprise active directory and list the servers available to the user; the user is admin if member of the "EnterpriseAdminGroup" defined into myrtille services config
        /// standard mode: connect the specified server; authentication is delegated to the remote server or connection broker (if applicable)
        /// if MFA is enabled and not already processed, authenticate the user against the configured MFA provider (OTP preferred)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ConnectButtonClick(
            object sender,
            EventArgs e)
        {
            if (!_authorizedRequest)
            {
                return;
            }

            // one time usage enterprise session url
            if (_enterpriseSession == null && Request["SI"] != null && Request["SD"] != null && Request["SK"] != null)
            {
                CreateEnterpriseSessionFromUrl();
            }

            // MFA (OTP passcode)
            if (_enterpriseSession == null && _mfaAuthClient.GetState())
            {
                var clientIP = ClientIPHelper.ClientIPFromRequest(new HttpContextWrapper(HttpContext.Current).Request, true, new string[] { });
                if (!_mfaAuthClient.Authenticate(user.Value, mfaPassword.Value, clientIP))
                {
                    connectError.InnerText = "MFA Authentication failed!";
                    UpdateControls();
                    return;
                }
            }

            // enterprise mode from login
            if (_enterpriseSession == null && _enterpriseClient.GetState())
            {
                CreateEnterpriseSessionFromLogin();
            }
            // connection from:
            // > standard mode
            // > enterprise mode: hosts list
            // > enterprise mode: one time session url
            else
            {
                // the display size is required to start a remote session
                // if missing, the client will provide it automatically
                if (string.IsNullOrEmpty(width.Value) || string.IsNullOrEmpty(height.Value))
                {
                    return;
                }

                // connect
                if (ConnectRemoteServer())
                {
                    // in enterprise mode from login, a new http session id was already generated (no need to do it each time an host is connected!)
                    // in standard mode or enterprise mode from url, a new http session id must be generated
                    if (_enterpriseSession == null || Request["SI"] != null)
                    {
                        // session fixation protection
                        if (_cookielessSession)
                        {
                            // generate a new http session id
                            RemoteSession.OwnerSessionID = HttpSessionHelper.RegenerateSessionId();
                        }
                    }
                    try
                    {
                        // standard mode: switch to http get (standard login) or remove the connection params from url (auto-connect / start program from url)
                        // enterprise mode: remove the host id from url
                        Response.Redirect("~/", true);
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after redirect
                    }
                }
                // connection failed from the hosts list or from a one time session url
                else if (_enterpriseSession != null && Request["SD"] != null)
                {
                    try
                    {
                        // remove the host id from url
                        Response.Redirect("~/", true);
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after redirect
                    }
                }
            }
        }
コード例 #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)
        {
            // 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();
        }
コード例 #4
0
ファイル: Default.aspx.cs プロジェクト: visnyin/myrtille
        /// <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 (_httpSessionUseUri)
            {
                if (Request.Cookies[HttpRequestCookies.ClientKey.ToString()] == null)
                {
                    if (Session[HttpSessionStateVariables.ClientKey.ToString()] == null || _allowShareSessionUrl)
                    {
                        var cookie = new HttpCookie(HttpRequestCookies.ClientKey.ToString());
                        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[HttpRequestCookies.ClientKey.ToString()].Value;
                    if (Session[HttpSessionStateVariables.ClientKey.ToString()] == null)
                    {
                        Session[HttpSessionStateVariables.ClientKey.ToString()] = clientKey;
                    }
                    else if (!((string)Session[HttpSessionStateVariables.ClientKey.ToString()]).Equals(clientKey) && !_allowShareSessionUrl)
                    {
                        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 using a connection service, send the connection state
                    if (Session.SessionID.Equals(RemoteSession.OwnerSessionID) && RemoteSession.ConnectionService)
                    {
                        _connectionClient.SetConnectionState(RemoteSession.Id, string.IsNullOrEmpty(RemoteSession.VMAddress) ? RemoteSession.ServerAddress : RemoteSession.VMAddress, GuidHelper.ConvertFromString(RemoteSession.VMGuid), RemoteSession.State);
                    }

                    if (RemoteSession.State == RemoteSessionState.Disconnected)
                    {
                        // if connecting from a login page or url, show any connection failure into a dialog box
                        // otherwise, this is delegated to the connection API used and its related UI
                        if (_loginEnabled)
                        {
                            // handle connection failure
                            var script = string.Format("handleRemoteSessionExit({0});", RemoteSession.ExitCode);

                            // redirect to login page
                            if (!string.IsNullOrEmpty(_loginUrl))
                            {
                                script += string.Format("window.location.href = '{0}';", _loginUrl);
                            }

                            ClientScript.RegisterClientScriptBlock(GetType(), Guid.NewGuid().ToString(), script, true);
                        }

                        // cleanup
                        Session[HttpSessionStateVariables.RemoteSession.ToString()] = null;
                        if (Session[HttpSessionStateVariables.GuestInfo.ToString()] != null)
                        {
                            Session[HttpSessionStateVariables.GuestInfo.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 (!string.IsNullOrEmpty(Request["gid"]))
            {
                var guestId = Guid.Empty;
                if (Guid.TryParse(Request["gid"], out guestId))
                {
                    var sharingInfo = GetSharingInfo(guestId);
                    if (sharingInfo != null)
                    {
                        Session[HttpSessionStateVariables.RemoteSession.ToString()] = sharingInfo.RemoteSession;
                        Session[HttpSessionStateVariables.GuestInfo.ToString()]     = sharingInfo.GuestInfo;

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

            if (_httpSessionUseUri)
            {
                // if running myrtille into an iframe, the iframe url is registered (into a cookie) after the remote session is connected
                // this is necessary to prevent a new http session from being generated for the iframe if the page is reloaded, due to the missing http session id into the iframe url (!)
                // multiple iframes (on the same page), like multiple connections/tabs, requires cookieless="UseUri" for sessionState into web.config

                // problem is, there can be many cases where the cookie is not removed after the remote session is disconnected (network issue, server down, etc?)
                // if the page is reloaded, the iframe will use it's previously registered http session... which may not exist anymore or have its active remote session disconnected
                // if that happens, unregister the iframe url (from the cookie) and reload the page; that will provide a new connection identifier to the iframe and reconnect it

                if (!string.IsNullOrEmpty(Request["fid"]) && RemoteSession == null)
                {
                    if (Request.Cookies[Request["fid"]] != null)
                    {
                        // remove the cookie for the given iframe
                        Response.Cookies[Request["fid"]].Expires = DateTime.Now.AddDays(-1);

                        // reload the page
                        ClientScript.RegisterClientScriptBlock(GetType(), Guid.NewGuid().ToString(), "parent.location.href = parent.location.href;", true);
                    }
                }
            }

            // local admin
            if (_enterpriseSession == null && RemoteSession == null && _enterpriseClient.GetMode() == EnterpriseMode.Local && !string.IsNullOrEmpty(Request["mode"]) && Request["mode"].Equals("admin"))
            {
                _localAdmin = true;
            }

            // 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();
        }
コード例 #5
0
        /// <summary>
        /// enterprise mode from url: load the enterprise session (from querystring param) and proceed to connection; the user is non admin and the url is only usable once
        /// enterprise mode from login: authenticate the user against the enterprise active directory and list the servers available to the user; the user is admin if member of the "EnterpriseAdminGroup" defined into myrtille services config
        /// standard mode: connect the specified server; the rdp authentication is delegated to the rdp server or connection broker (if applicable)
        /// if MFA is enabled and not already processed, authenticate the user against the configured MFA provider (OTP preferred)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ConnectButtonClick(
            object sender,
            EventArgs e)
        {
            // one time usage enterprise session url
            if (Request["SI"] != null && Request["SD"] != null && Request["SK"] != null)
            {
                CreateEnterpriseSessionFromUrl();
            }

            // MFA (OTP passcode)
            if (_enterpriseSession == null && _mfaAuthClient.GetState())
            {
                var clientIP = ClientIPHelper.ClientIPFromRequest(new HttpContextWrapper(HttpContext.Current).Request, true, new string[] { });
                if (!_mfaAuthClient.Authenticate(user.Value, mfaPassword.Value, clientIP))
                {
                    connectError.InnerText = "MFA Authentication failed!";
                    UpdateControls();

                    return;
                }
            }

            // enterprise mode from login
            if (_enterpriseSession == null && _enterpriseClient.GetState())
            {
                CreateEnterpriseSessionFromLogin();
            }
            // connection from:
            // > standard mode
            // > enterprise mode: hosts list
            // > enterprise mode: one time session url
            else
            {
                // the display size is required to start a remote session
                // if missing, the client will provide it automatically
                if (string.IsNullOrEmpty(width.Value) || string.IsNullOrEmpty(height.Value))
                {
                    return;
                }

                // connect
                if (ConnectRemoteServer())
                {
                    try
                    {
                        // in enterprise mode from login, a new http session was already generated (no need to do it each time an host is connected!)
                        // in standard mode or enterprise mode from url, a new http session must be generated
                        if (_enterpriseSession == null || Request["SI"] != null)
                        {
                            // cancel the current http session
                            HttpContext.Current.Session.Abandon();

                            // prevent session fixation attack by generating a new session ID upon login
                            // also, using http get method to prevent the browser asking for http post data confirmation if the page is reloaded
                            // https://www.owasp.org/index.php/Session_Fixation
                            Response.Redirect(string.Format("?oldSID={0}", HttpContext.Current.Session.SessionID), true);
                        }
                        // remove the host id from url
                        else
                        {
                            Response.Redirect("?", true);
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after redirect
                    }
                }
                // connection failed from the hosts list or from a one time session url
                else if (_enterpriseSession != null && Request["SD"] != null)
                {
                    try
                    {
                        // remove the host id from url
                        Response.Redirect("?", true);
                    }
                    catch (ThreadAbortException)
                    {
                        // occurs because the response is ended after redirect
                    }
                }
            }
        }
コード例 #6
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()];

                    var clientIP = ClientIPHelper.ClientIPFromRequest(new HttpContextWrapper(HttpContext.Current).Request, true, new string[] { });

                    if (!_enterpriseSession.ClientRemoteIP.Equals(clientIP))
                    {
                        HttpContext.Current.Session[HttpSessionStateVariables.EnterpriseSession.ToString()] = null;
                        _enterpriseSession = null;
                    }
                }
                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 remote session information from session url
            if (Request.QueryString["SSE"] != null)
            {
                RemoteSession = GetSharedRemoteSession(Request.QueryString["SSE"]);
                if (RemoteSession == null)
                {
                    Response.Redirect(string.Format("?oldSID={0}", HttpContext.Current.Session.SessionID), true);
                }
            }
            else
            // 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();
        }