diff --git a/Myrtille.Web/Default.aspx.cs b/Myrtille.Web/Default.aspx.cs index 0a6d809..d846343 100644 --- a/Myrtille.Web/Default.aspx.cs +++ b/Myrtille.Web/Default.aspx.cs @@ -34,6 +34,7 @@ limitations under the License. using Myrtille.Helpers; using Myrtille.Services.Contracts; using Myrtille.Web.Properties; +using Myrtille.Web.src.Utils; using Newtonsoft.Json.Linq; namespace Myrtille.Web @@ -521,94 +522,6 @@ protected void ConnectButtonClick( } } - private static bool TrustCertificate(object sender, X509Certificate x509Certificate, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - - private static JObject SecurdenWebRequest(string serverUrl, string requestUrl, string requestMethod, JObject requestParams) - { - requestUrl = serverUrl + requestUrl; - JObject result = null; - try - { - if (requestMethod == "GET" && requestParams != null) - { - requestUrl += '?'; - requestUrl += "LAUNCHER_INPUT=" + requestParams.ToString(); - } - - ServicePointManager.ServerCertificateValidationCallback = TrustCertificate; - ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; - var uri = new Uri(requestUrl); - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); - request.Method = requestMethod; - request.UserAgent = "-SECURDEN-LAUNCHER-"; - if (requestMethod == "POST" && requestParams != null) - { - var postData = "LAUNCHER_INPUT=" + requestParams.ToString(); - var data = Encoding.UTF8.GetBytes(postData); - request.ContentType = "application/x-www-form-urlencoded"; - request.ContentLength = data.Length; - using (var stream = request.GetRequestStream()) - { - stream.Write(data, 0, data.Length); - } - } - var response = (HttpWebResponse)request.GetResponse(); - var responseString = string.Empty; - using (var stream = new StreamReader(response.GetResponseStream())) - { - responseString = stream.ReadToEnd(); - } - result = JObject.Parse(responseString); - response.Close(); - } - catch (Exception) - { } - return result; - } - - private JObject ProcessLaunchRequest(string serverUrl, string authKey) - { - JObject returnObj = null; - JObject paramObj = new JObject(new JProperty("AUTH_KEY", authKey)); - JObject response = null; - if (Request["access_url"] != null && Request["access_url"].Trim() != "") - { - string accessUrl = Request["access_url"].Trim(); - if (accessUrl.EndsWith("/")) - { - accessUrl = accessUrl.Substring(0, accessUrl.Length - 1); - } - response = SecurdenWebRequest(accessUrl, "/launcher/verify_launch_info", "POST", paramObj); - } - if (response == null) - { - response = SecurdenWebRequest(serverUrl, "/launcher/verify_launch_info", "POST", paramObj); - } - if (response == null) - { - Response.Write(""); - } - else if (response.ContainsKey("type")) - { - if ((string)response["type"] == "WEB_RDP") - { - returnObj = response; - } - else - { - Response.Write(""); - } - } - else - { - Response.Write(""); - } - return returnObj; - } - /// /// connect the remote server /// @@ -617,6 +530,8 @@ private JObject ProcessLaunchRequest(string serverUrl, string authKey) /// private bool ConnectRemoteServer() { + var connectionId = Guid.NewGuid(); + // connection parameters string loginHostName = null; var loginHostType = (HostType)Convert.ToInt32(hostType.Value); @@ -637,20 +552,96 @@ private bool ConnectRemoteServer() } long userProfileId = 0; long userSessionId = 0; + string accessUrl = null; + if (RemoteSession == null) { - JObject connectionDetails = ProcessLaunchRequest(Request["referrer"], Request["auth_key"]); + JObject connectionDetails = SecurdenWeb.ProcessLaunchRequest(Request, Response, Request["referrer"], Request["auth_key"], connectionId.ToString()); if (connectionDetails == null) { return false; } else { - if (connectionDetails["user_profile_id"] != null && connectionDetails["user_session_id"] != null) + userProfileId = (long)connectionDetails["user_profile_id"]; + userSessionId = (long)connectionDetails["user_session_id"]; + if ((string)connectionDetails["type"] == "SHADOW_SESSION") + { + connectionDetails = (JObject)connectionDetails["details"]; + string guestShareId = ""; + try + { + Application.Lock(); + + // create a new guest for the remote session + var sharedSessions = (IDictionary)Application[HttpApplicationStateVariables.SharedRemoteSessions.ToString()]; + Guid OldConnectionId = new Guid((string)connectionDetails["connection_id"]); + var sharingInfo = new SharingInfo + { + RemoteSession = ((IDictionary) Application[HttpApplicationStateVariables.RemoteSessions.ToString()])[OldConnectionId], + GuestInfo = new GuestInfo + { + Id = Guid.NewGuid(), + ConnectionId = OldConnectionId, + Control = false, + } + }; + + sharedSessions.Add(sharingInfo.GuestInfo.Id, sharingInfo); + guestShareId = sharingInfo.GuestInfo.Id.ToString(); + } + 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(); + } + if (guestShareId != "") + { + Response.Redirect("~/?gid=" + guestShareId, true); + } + else + { + Response.Write(""); + } + return false; + } + else if ((string) connectionDetails["type"] == "TERMINATE_SESSION") { - userProfileId = (long)connectionDetails["user_profile_id"]; - userSessionId = (long)connectionDetails["user_session_id"]; + connectionDetails = (JObject)connectionDetails["details"]; + bool isTerminated = false; + try + { + Guid OldConnectionId = new Guid((string)connectionDetails["connection_id"]); + RemoteSession = ((IDictionary)Application[HttpApplicationStateVariables.RemoteSessions.ToString()])[OldConnectionId]; + RemoteSession.Manager.SendCommand(RemoteSessionCommand.CloseClient); + isTerminated = true; + } + catch (ThreadAbortException) + { + // occurs because the response is ended after redirect + } + catch (Exception exc) + { + System.Diagnostics.Trace.TraceError("Failed to terminate the session ({0})", exc); + } + if (isTerminated) + { + Response.Write(""); + } + else + { + Response.Write(""); + } + return false; } + accessUrl = (string)connectionDetails["ACCESS_URL"]; connectionDetails = (JObject)connectionDetails["details"]; loginServer = (string)connectionDetails["address"]; loginDomain = ""; @@ -673,8 +664,6 @@ private bool ConnectRemoteServer() // 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"]))) { @@ -809,6 +798,7 @@ private bool ConnectRemoteServer() RemoteSession.UserProfileId = userProfileId; RemoteSession.UserSessionId = userSessionId; + RemoteSession.accessUrl = accessUrl; // bind the remote session to the current http session Session[HttpSessionStateVariables.RemoteSession.ToString()] = RemoteSession; diff --git a/Myrtille.Web/Myrtille.Web.csproj b/Myrtille.Web/Myrtille.Web.csproj index 1de5402..0fdb5ec 100644 --- a/Myrtille.Web/Myrtille.Web.csproj +++ b/Myrtille.Web/Myrtille.Web.csproj @@ -214,6 +214,7 @@ + Component diff --git a/Myrtille.Web/Web.config b/Myrtille.Web/Web.config index fb29592..729a12f 100644 --- a/Myrtille.Web/Web.config +++ b/Myrtille.Web/Web.config @@ -8,20 +8,22 @@
- -
+ +
- - + + - - + + @@ -98,7 +100,7 @@ - + @@ -122,25 +124,31 @@ - - - + + + - + - + - + @@ -167,7 +175,7 @@ - + diff --git a/Myrtille.Web/src/Clients/RemoteSessionProcessClient.cs b/Myrtille.Web/src/Clients/RemoteSessionProcessClient.cs index dac423e..e8cd86e 100644 --- a/Myrtille.Web/src/Clients/RemoteSessionProcessClient.cs +++ b/Myrtille.Web/src/Clients/RemoteSessionProcessClient.cs @@ -20,12 +20,19 @@ limitations under the License. using System.Collections.Generic; using System.Configuration; using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using System.ServiceModel; +using System.Text; using System.Threading; using System.Web; using Myrtille.Helpers; using Myrtille.Services.Contracts; using Myrtille.Web.Properties; +using Myrtille.Web.src.Utils; +using Newtonsoft.Json.Linq; namespace Myrtille.Web { @@ -236,6 +243,7 @@ private void CleanupDisconnectedSession(RemoteSessionExitCode exitCode) var remoteSessions = (IDictionary)_application[HttpApplicationStateVariables.RemoteSessions.ToString()]; if (remoteSessions.ContainsKey(_remoteSessionManager.RemoteSession.Id)) { + SecurdenWeb.ManageSessionRequest(_remoteSessionManager.RemoteSession.accessUrl, _remoteSessionManager.RemoteSession.Id.ToString(), false); remoteSessions.Remove(_remoteSessionManager.RemoteSession.Id); } diff --git a/Myrtille.Web/src/RemoteSession.cs b/Myrtille.Web/src/RemoteSession.cs index 364248c..fe9a033 100644 --- a/Myrtille.Web/src/RemoteSession.cs +++ b/Myrtille.Web/src/RemoteSession.cs @@ -34,6 +34,7 @@ public class RemoteSession public long UserProfileId; public long UserSessionId; + public string accessUrl; public Guid Id; public RemoteSessionState State; diff --git a/Myrtille.Web/src/RemoteSessionManager.cs b/Myrtille.Web/src/RemoteSessionManager.cs index a85678b..ce4f137 100644 --- a/Myrtille.Web/src/RemoteSessionManager.cs +++ b/Myrtille.Web/src/RemoteSessionManager.cs @@ -30,6 +30,7 @@ limitations under the License. using System.Web.SessionState; using Myrtille.Helpers; using Myrtille.Services.Contracts; +using Myrtille.Web.src.Utils; namespace Myrtille.Web { @@ -161,6 +162,7 @@ public void ProcessUpdatesPipeData(byte[] data) if (RemoteSession.State == RemoteSessionState.Connecting) { RemoteSession.State = RemoteSessionState.Connected; + SecurdenWeb.ManageSessionRequest(RemoteSession.accessUrl, RemoteSession.Id.ToString(), true); SendMessage(new RemoteSessionMessage { Type = MessageType.Connected, Prefix = "connected" }); // in case the remote session was reconnected, send the capture API config diff --git a/Myrtille.Web/src/Utils/WebRequest.cs b/Myrtille.Web/src/Utils/WebRequest.cs new file mode 100644 index 0000000..6670373 --- /dev/null +++ b/Myrtille.Web/src/Utils/WebRequest.cs @@ -0,0 +1,121 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Web; + +namespace Myrtille.Web.src.Utils +{ + public static class SecurdenWeb + { + private static bool TrustCertificate(object sender, X509Certificate x509Certificate, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors) + { + return true; + } + + private static JObject SecurdenWebRequest(string serverUrl, string requestUrl, string requestMethod, JObject requestParams) + { + requestUrl = serverUrl + requestUrl; + JObject result = null; + try + { + if (requestMethod == "GET" && requestParams != null) + { + requestUrl += '?'; + requestUrl += "LAUNCHER_INPUT=" + requestParams.ToString(); + } + + ServicePointManager.ServerCertificateValidationCallback = TrustCertificate; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; + var uri = new Uri(requestUrl); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); + request.Method = requestMethod; + request.UserAgent = "-SECURDEN-LAUNCHER-"; + if (requestMethod == "POST" && requestParams != null) + { + var postData = "LAUNCHER_INPUT=" + requestParams.ToString(); + var data = Encoding.UTF8.GetBytes(postData); + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = data.Length; + using (var stream = request.GetRequestStream()) + { + stream.Write(data, 0, data.Length); + } + } + var response = (HttpWebResponse)request.GetResponse(); + var responseString = string.Empty; + using (var stream = new StreamReader(response.GetResponseStream())) + { + responseString = stream.ReadToEnd(); + } + result = JObject.Parse(responseString); + response.Close(); + } + catch (Exception) + { } + return result; + } + + public static void ManageSessionRequest(string serverUrl, string connectionId, bool status) + { + if (serverUrl != null) + { + JObject paramObj = new JObject(new JProperty("CONNECTION_ID", connectionId), new JProperty("STATUS", status)); + SecurdenWebRequest(serverUrl, "/launcher/manage_web_session", "POST", paramObj); + } + } + + public static JObject ProcessLaunchRequest(HttpRequest Request, HttpResponse Response, string serverUrl, string authKey, string connectionId) + { + JObject returnObj = null; + JObject paramObj = new JObject(new JProperty("AUTH_KEY", authKey), new JProperty("CONNECTION_ID", connectionId)); + JObject response = null; + if (Request["access_url"] != null && Request["access_url"].Trim() != "") + { + string accessUrl = Request["access_url"].Trim(); + if (accessUrl.EndsWith("/")) + { + accessUrl = accessUrl.Substring(0, accessUrl.Length - 1); + } + response = SecurdenWebRequest(accessUrl, "/launcher/verify_launch_info", "POST", paramObj); + if (response != null && ((JObject)response["details"]).ContainsKey("is_remote_session_managed") && (bool)response["details"]["is_remote_session_managed"]) + { + response["ACCESS_URL"] = accessUrl; + } + else if (response == null) + { + response = SecurdenWebRequest(serverUrl, "/launcher/verify_launch_info", "POST", paramObj); + if (response != null && ((JObject)response["details"]).ContainsKey("is_remote_session_managed") && (bool)response["details"]["is_remote_session_managed"]) + { + response["ACCESS_URL"] = serverUrl; + } + } + } + if (response == null) + { + Response.Write(""); + } + else if (response.ContainsKey("type")) + { + if ((string)response["type"] == "WEB_RDP" || (string)response["type"] == "SHADOW_SESSION" || (string)response["type"] == "TERMINATE_SESSION") + { + returnObj = response; + } + else + { + Response.Write(""); + } + } + else + { + Response.Write(""); + } + return returnObj; + } + } +} \ No newline at end of file