From 6139b499a96165ac5c4ccb4900fd36c76622ea1f Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 25 Feb 2015 01:39:59 -0800 Subject: [PATCH] RDS Help desk computer group added --- .../RemoteDesktopServicesProxy.cs | 78 ++++++++++ .../RemoteDesktopServicesController.cs | 72 ++++++++- .../esRemoteDesktopServices.asmx.cs | 6 + .../IRemoteDesktopServices.cs | 1 + .../RdsCollectionSettings.cs | 5 +- .../RemoteApplication.cs | 1 + .../Windows2012.cs | 147 ++++++++++++++++-- .../RemoteDesktopServicesProxy.cs | 55 +++++++ .../RemoteDesktopServices.asmx.cs | 16 ++ .../WebsitePanel_SharedResources.ascx.resx | 3 + .../RDSEditCollectionSettings.ascx.resx | 9 ++ .../RDS/RDSCreateCollection.ascx.cs | 17 +- .../RDS/RDSEditCollectionSettings.ascx | 37 +++++ .../RDS/RDSEditCollectionSettings.ascx.cs | 11 +- ...RDSEditCollectionSettings.ascx.designer.cs | 63 ++++++++ .../RDS/UserControls/RDSCollectionApps.ascx | 9 +- 16 files changed, 505 insertions(+), 25 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs index 6ba412b9..3214d80d 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs @@ -118,6 +118,8 @@ namespace WebsitePanel.EnterpriseServer { private System.Threading.SendOrPostCallback SaveRdsCollectionLocalAdminsOperationCompleted; + private System.Threading.SendOrPostCallback InstallSessionHostsCertificateOperationCompleted; + /// public esRemoteDesktopServices() { this.Url = "http://localhost:9002/esRemoteDesktopServices.asmx"; @@ -255,6 +257,9 @@ namespace WebsitePanel.EnterpriseServer { /// public event SaveRdsCollectionLocalAdminsCompletedEventHandler SaveRdsCollectionLocalAdminsCompleted; + /// + public event InstallSessionHostsCertificateCompletedEventHandler InstallSessionHostsCertificateCompleted; + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetRdsCollection", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public RdsCollection GetRdsCollection(int collectionId) { @@ -2238,6 +2243,53 @@ namespace WebsitePanel.EnterpriseServer { } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/InstallSessionHostsCertificate", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public ResultObject InstallSessionHostsCertificate(int collectionId, [System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] byte[] certificate, string password) { + object[] results = this.Invoke("InstallSessionHostsCertificate", new object[] { + collectionId, + certificate, + password}); + return ((ResultObject)(results[0])); + } + + /// + public System.IAsyncResult BeginInstallSessionHostsCertificate(int collectionId, byte[] certificate, string password, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("InstallSessionHostsCertificate", new object[] { + collectionId, + certificate, + password}, callback, asyncState); + } + + /// + public ResultObject EndInstallSessionHostsCertificate(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((ResultObject)(results[0])); + } + + /// + public void InstallSessionHostsCertificateAsync(int collectionId, byte[] certificate, string password) { + this.InstallSessionHostsCertificateAsync(collectionId, certificate, password, null); + } + + /// + public void InstallSessionHostsCertificateAsync(int collectionId, byte[] certificate, string password, object userState) { + if ((this.InstallSessionHostsCertificateOperationCompleted == null)) { + this.InstallSessionHostsCertificateOperationCompleted = new System.Threading.SendOrPostCallback(this.OnInstallSessionHostsCertificateOperationCompleted); + } + this.InvokeAsync("InstallSessionHostsCertificate", new object[] { + collectionId, + certificate, + password}, this.InstallSessionHostsCertificateOperationCompleted, userState); + } + + private void OnInstallSessionHostsCertificateOperationCompleted(object arg) { + if ((this.InstallSessionHostsCertificateCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.InstallSessionHostsCertificateCompleted(this, new InstallSessionHostsCertificateCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { base.CancelAsync(userState); @@ -3387,4 +3439,30 @@ namespace WebsitePanel.EnterpriseServer { } } } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void InstallSessionHostsCertificateCompletedEventHandler(object sender, InstallSessionHostsCertificateCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class InstallSessionHostsCertificateCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal InstallSessionHostsCertificateCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public ResultObject Result { + get { + this.RaiseExceptionIfNecessary(); + return ((ResultObject)(this.results[0])); + } + } + } } diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs index e1561f26..91f589c3 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs @@ -278,6 +278,51 @@ namespace WebsitePanel.EnterpriseServer return SaveRdsCollectionLocalAdminsInternal(users, collectionId); } + public static ResultObject InstallSessionHostsCertificate(int collectionId, byte[] certificate, string password) + { + return InstallSessionHostsCertificateInternal(collectionId, certificate, password); + } + + private static ResultObject InstallSessionHostsCertificateInternal(int collectionId, byte[] certificate, string password) + { + var result = TaskManager.StartResultTask("REMOTE_DESKTOP_SERVICES", "INSTALL_CERTIFICATE"); + + try + { + var collection = ObjectUtils.FillObjectFromDataReader(DataProvider.GetRDSCollectionById(collectionId)); + Organization org = OrganizationController.GetOrganization(collection.ItemId); + + if (org == null) + { + result.IsSuccess = false; + result.AddError("", new NullReferenceException("Organization not found")); + return result; + } + + var rds = GetRemoteDesktopServices(GetRemoteDesktopServiceID(org.PackageId)); + var servers = ObjectUtils.CreateListFromDataReader(DataProvider.GetRDSServersByCollectionId(collection.Id)).ToList(); + + rds.InstallCertificate(certificate, password, servers.Select(s => s.FqdName).ToArray()); + } + catch (Exception ex) + { + throw TaskManager.WriteError(ex); + } + finally + { + if (!result.IsSuccess) + { + TaskManager.CompleteResultTask(result); + } + else + { + TaskManager.CompleteResultTask(); + } + } + + return result; + } + private static RdsCollection GetRdsCollectionInternal(int collectionId) { var collection = ObjectUtils.FillObjectFromDataReader(DataProvider.GetRDSCollectionById(collectionId)); @@ -372,9 +417,25 @@ namespace WebsitePanel.EnterpriseServer private static RdsCollectionSettings GetRdsCollectionSettingsInternal(int collectionId) { - var collection = ObjectUtils.FillObjectFromDataReader(DataProvider.GetRDSCollectionById(collectionId)); - - return ObjectUtils.FillObjectFromDataReader(DataProvider.GetRdsCollectionSettingsByCollectionId(collectionId)); + var collection = ObjectUtils.FillObjectFromDataReader(DataProvider.GetRDSCollectionById(collectionId)); + var settings = ObjectUtils.FillObjectFromDataReader(DataProvider.GetRdsCollectionSettingsByCollectionId(collectionId)); + + if (settings.SecurityLayer == null) + { + settings.SecurityLayer = SecurityLayerValues.Negotiate.ToString(); + } + + if (settings.EncryptionLevel == null) + { + settings.EncryptionLevel = EncryptionLevel.ClientCompatible.ToString(); + } + + if (settings.AuthenticateUsingNLA == null) + { + settings.AuthenticateUsingNLA = true; + } + + return settings; } private static List GetOrganizationRdsCollectionsInternal(int itemId) @@ -426,7 +487,10 @@ namespace WebsitePanel.EnterpriseServer ClientPrinterRedirected = true, ClientPrinterAsDefault = true, RDEasyPrintDriverEnabled = true, - MaxRedirectedMonitors = 16 + MaxRedirectedMonitors = 16, + EncryptionLevel = EncryptionLevel.ClientCompatible.ToString(), + SecurityLayer = SecurityLayerValues.Negotiate.ToString(), + AuthenticateUsingNLA = true }; rds.CreateCollection(org.OrganizationId, collection); diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs index e6391df1..8cd3ecdb 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs @@ -325,5 +325,11 @@ namespace WebsitePanel.EnterpriseServer { return RemoteDesktopServicesController.SaveRdsCollectionLocalAdmins(users, collectionId); } + + [WebMethod] + public ResultObject InstallSessionHostsCertificate(int collectionId, byte[] certificate, string password) + { + return RemoteDesktopServicesController.InstallSessionHostsCertificate(collectionId, certificate, password); + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs index 9ecc03eb..133eb575 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs @@ -78,5 +78,6 @@ namespace WebsitePanel.Providers.RemoteDesktopServices List GetRdsCollectionLocalAdmins(string hostName); void MoveRdsServerToTenantOU(string hostName, string organizationId); void RemoveRdsServerFromTenantOU(string hostName, string organizationId); + void InstallCertificate(byte[] certificate, string password, List hostNames); } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RdsCollectionSettings.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RdsCollectionSettings.cs index 5827ecc6..2ccae36a 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RdsCollectionSettings.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RdsCollectionSettings.cs @@ -21,6 +21,9 @@ namespace WebsitePanel.Providers.RemoteDesktopServices public bool ClientPrinterRedirected { get; set; } public bool ClientPrinterAsDefault { get; set; } public bool RDEasyPrintDriverEnabled { get; set; } - public int MaxRedirectedMonitors { get; set; } + public int MaxRedirectedMonitors { get; set; } + public string SecurityLayer { get; set; } + public string EncryptionLevel { get; set; } + public bool AuthenticateUsingNLA { get; set; } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RemoteApplication.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RemoteApplication.cs index 300f8b47..b0bda452 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RemoteApplication.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/RemoteApplication.cs @@ -36,5 +36,6 @@ namespace WebsitePanel.Providers.RemoteDesktopServices public string FileVirtualPath { get; set; } public bool ShowInWebAccess { get; set; } public string RequiredCommandLine { get; set; } + public string[] Users { get; set; } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index 515250c5..af65e3c0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -70,8 +70,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices private const string WspAdministratorsGroupName = "WSP-Administrators"; private const string WspAdministratorsGroupDescription = "WSP Administrators"; private const string RdsServersOU = "RDSServers"; - private const uint ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008; - private const uint ADS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000; + private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer"; #endregion @@ -309,6 +308,11 @@ namespace WebsitePanel.Providers.RemoteDesktopServices //ActiveDirectoryUtils.AddObjectToGroup(GetComputerPath(ConnectionBroker), GetComputerGroupPath(organizationId, collection.Name)); } + if (!ActiveDirectoryUtils.AdObjectExists(GetHelpDeskComputerGroupPath())) + { + ActiveDirectoryUtils.CreateGroup(GetRootOUPath(), RDSHelpDeskComputerGroup); + } + if (!ActiveDirectoryUtils.AdObjectExists(GetUsersGroupPath(organizationId, collection.Name))) { //Create user group @@ -561,6 +565,11 @@ namespace WebsitePanel.Providers.RemoteDesktopServices ExecuteShellCommand(runSpace, cmd, false); + if (!ActiveDirectoryUtils.AdObjectExists(GetHelpDeskComputerGroupPath())) + { + ActiveDirectoryUtils.CreateGroup(GetRootOUPath(), RDSHelpDeskComputerGroup); + } + AddComputerToCollectionAdComputerGroup(organizationId, collectionName, server); } catch (Exception e) @@ -1134,32 +1143,103 @@ namespace WebsitePanel.Providers.RemoteDesktopServices #region SSL - public void InstallCertificate(byte[] certificate, string password, string hostName) + public void InstallCertificate(byte[] certificate, string password, List hostNames) { Runspace runspace = null; try - { + { + var guid = Guid.NewGuid(); var x509Cert = new X509Certificate2(certificate, password, X509KeyStorageFlags.Exportable); + //var content = x509Cert.Export(X509ContentType.Pfx); + var filePath = SaveCertificate(certificate, guid); runspace = OpenRunspace(); - CopyCertificateFile(certificate, hostName, runspace); + + foreach (var hostName in hostNames) + { + var destinationPath = string.Format("\\\\{0}\\c$\\{1}.pfx", hostName, guid); + var errors = CopyCertificateFile(runspace, filePath, destinationPath); + + if (!errors.Any()) + { + errors = ImportCertificate(runspace, hostName, password, string.Format("c:\\{0}.pfx", guid), x509Cert.Thumbprint); + } + + DeleteCertificateFile(destinationPath, runspace); + + if (errors.Any()) + { + Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray())); + throw new Exception(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray())); + } + } + + if (File.Exists(filePath)) + { + File.Delete(filePath); + } } finally { CloseRunspace(runspace); } } - - private string CopyCertificateFile(byte[] certificate, string hostName, Runspace runspace) - { - var destinationPath = string.Format("\\{0}\\c$\\remoteCert.pfx", hostName); - return destinationPath; + private object[] ImportCertificate(Runspace runspace, string hostName, string password, string certificatePath, string thumbprint) + { + var scripts = new List + { + string.Format("$mypwd = ConvertTo-SecureString -String {0} -Force –AsPlainText", password), + string.Format("Import-PfxCertificate –FilePath \"{0}\" cert:\\localMachine\\my -Password $mypwd", certificatePath), + string.Format("$cert = Get-Item cert:\\LocalMachine\\My\\{0}", thumbprint), + string.Format("$path = (Get-WmiObject -class \"Win32_TSGeneralSetting\" -Namespace root\\cimv2\\terminalservices -Filter \"TerminalName='RDP-tcp'\").__path"), + string.Format("Set-WmiInstance -Path $path -argument @{0}", string.Format("{{SSLCertificateSHA1Hash=\"{0}\"}}", thumbprint)) + }; + + object[] errors = null; + ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors); + + return errors; } - private void DeleteCertificate(string path, Runspace runspace) + private string SaveCertificate(byte[] certificate, Guid guid) { + var filePath = string.Format("{0}{1}.pfx", Path.GetTempPath(), guid); + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + + File.WriteAllBytes(filePath, certificate); + + return filePath; + } + + private object[] CopyCertificateFile(Runspace runspace, string filePath, string destinationPath) + { + var scripts = new List + { + string.Format("Copy-Item \"{0}\" -Destination \"{1}\" -Force", filePath, destinationPath) + }; + + object[] errors = null; + ExecuteShellCommand(runspace, scripts, out errors); + + return errors; + } + + private object[] DeleteCertificateFile(string destinationPath, Runspace runspace) + { + var scripts = new List + { + string.Format("Remove-Item -Path \"{0}\" -Force", destinationPath) + }; + + object[] errors = null; + ExecuteShellCommand(runspace, scripts, out errors); + + return errors; } #endregion @@ -1242,7 +1322,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } return users; - } + } private void AddUserGroupsToCollection(Runspace runSpace, string collectionName, List groups) { @@ -1257,7 +1337,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices private void AddComputerToCollectionAdComputerGroup(string organizationId, string collectionName, RdsServer server) { var computerPath = GetComputerPath(server.Name, false); - var computerGroupName = GetComputersGroupName( collectionName); + var computerGroupName = GetComputersGroupName( collectionName); if (!ActiveDirectoryUtils.AdObjectExists(computerPath)) { @@ -1273,6 +1353,11 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetComputerGroupPath(organizationId, collectionName)); } + + if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup)) + { + ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetHelpDeskComputerGroupPath()); + } } SetRDServerNewConnectionAllowed(false, server); @@ -1297,6 +1382,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetComputerGroupPath(organizationId, collectionName)); } + + if (ActiveDirectoryUtils.AdObjectExists(GetHelpDeskComputerGroupPath())) + { + if (ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup)) + { + ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetHelpDeskComputerGroupPath()); + } + } } } @@ -1487,11 +1580,18 @@ namespace WebsitePanel.Providers.RemoteDesktopServices DisplayName = Convert.ToString(GetPSObjectProperty(psObject, "DisplayName")), FilePath = Convert.ToString(GetPSObjectProperty(psObject, "FilePath")), Alias = Convert.ToString(GetPSObjectProperty(psObject, "Alias")), - ShowInWebAccess = Convert.ToBoolean(GetPSObjectProperty(psObject, "ShowInWebAccess")) + ShowInWebAccess = Convert.ToBoolean(GetPSObjectProperty(psObject, "ShowInWebAccess")), + Users = null }; var requiredCommandLine = GetPSObjectProperty(psObject, "RequiredCommandLine"); remoteApp.RequiredCommandLine = requiredCommandLine == null ? null : requiredCommandLine.ToString(); + var users = (string[])(GetPSObjectProperty(psObject, "UserGroups")); + + if (users != null && users.Any()) + { + remoteApp.Users = users; + } return remoteApp; } @@ -1564,7 +1664,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices internal string GetComputerGroupPath(string organizationId, string collection) { StringBuilder sb = new StringBuilder(); - // append provider + AppendProtocol(sb); AppendDomainController(sb); AppendCNPath(sb, GetComputersGroupName(collection)); @@ -1573,12 +1673,25 @@ namespace WebsitePanel.Providers.RemoteDesktopServices AppendDomainPath(sb, RootDomain); return sb.ToString(); - } + } + + internal string GetHelpDeskComputerGroupPath() + { + StringBuilder sb = new StringBuilder(); + + AppendProtocol(sb); + AppendDomainController(sb); + AppendCNPath(sb, RDSHelpDeskComputerGroup); + AppendOUPath(sb, RootOU); + AppendDomainPath(sb, RootDomain); + + return sb.ToString(); + } internal string GetUsersGroupPath(string organizationId, string collection) { StringBuilder sb = new StringBuilder(); - // append provider + AppendProtocol(sb); AppendDomainController(sb); AppendCNPath(sb, GetUsersGroupName(collection)); diff --git a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs index b3bd520c..863d17ea 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs @@ -98,6 +98,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { private System.Threading.SendOrPostCallback RemoveRdsServerFromTenantOUOperationCompleted; + private System.Threading.SendOrPostCallback InstallCertificateOperationCompleted; + /// public RemoteDesktopServices() { this.Url = "http://localhost:9003/RemoteDesktopServices.asmx"; @@ -205,6 +207,9 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { /// public event RemoveRdsServerFromTenantOUCompletedEventHandler RemoveRdsServerFromTenantOUCompleted; + /// + public event InstallCertificateCompletedEventHandler InstallCertificateCompleted; + /// [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/CreateCollection", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] @@ -1675,6 +1680,52 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { } } + /// + [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/InstallCertificate", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public void InstallCertificate([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] byte[] certificate, string password, string[] hostNames) { + this.Invoke("InstallCertificate", new object[] { + certificate, + password, + hostNames}); + } + + /// + public System.IAsyncResult BeginInstallCertificate(byte[] certificate, string password, string[] hostNames, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("InstallCertificate", new object[] { + certificate, + password, + hostNames}, callback, asyncState); + } + + /// + public void EndInstallCertificate(System.IAsyncResult asyncResult) { + this.EndInvoke(asyncResult); + } + + /// + public void InstallCertificateAsync(byte[] certificate, string password, string[] hostNames) { + this.InstallCertificateAsync(certificate, password, hostNames, null); + } + + /// + public void InstallCertificateAsync(byte[] certificate, string password, string[] hostNames, object userState) { + if ((this.InstallCertificateOperationCompleted == null)) { + this.InstallCertificateOperationCompleted = new System.Threading.SendOrPostCallback(this.OnInstallCertificateOperationCompleted); + } + this.InvokeAsync("InstallCertificate", new object[] { + certificate, + password, + hostNames}, this.InstallCertificateOperationCompleted, userState); + } + + private void OnInstallCertificateOperationCompleted(object arg) { + if ((this.InstallCertificateCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.InstallCertificateCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { base.CancelAsync(userState); @@ -2300,4 +2351,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void RemoveRdsServerFromTenantOUCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void InstallCertificateCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); } diff --git a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs index decdada6..03fec8aa 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs @@ -630,5 +630,21 @@ namespace WebsitePanel.Server throw; } } + + [WebMethod, SoapHeader("settings")] + public void InstallCertificate(byte[] certificate, string password, List hostNames) + { + try + { + Log.WriteStart("'{0}' InstallCertificate", ProviderSettings.ProviderName); + RDSProvider.InstallCertificate(certificate, password, hostNames); + Log.WriteEnd("'{0}' InstallCertificate", ProviderSettings.ProviderName); + } + catch (Exception ex) + { + Log.WriteError(String.Format("'{0}' InstallCertificate", ProviderSettings.ProviderName), ex); + throw; + } + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx index 03fcb7be..35afc963 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx @@ -5638,6 +5638,9 @@ Collection not created + + Session host certificate not installed + RDS Collection settings not updated diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/App_LocalResources/RDSEditCollectionSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/App_LocalResources/RDSEditCollectionSettings.ascx.resx index 98985552..f20c77f4 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/App_LocalResources/RDSEditCollectionSettings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/App_LocalResources/RDSEditCollectionSettings.ascx.resx @@ -129,6 +129,9 @@ Enable redirection for the following: + + Encryption Level + Idle session limit: @@ -141,6 +144,9 @@ Printers + + Security Layer + Set RD Session Host server timeout and reconnection settings for the session collection. @@ -153,6 +159,9 @@ Client Settings + + Security Settings + Session Settings diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs index 5d16a9ba..21ef3c4d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs @@ -63,7 +63,22 @@ namespace WebsitePanel.Portal.RDS } RdsCollection collection = new RdsCollection{ Name = txtCollectionName.Text, DisplayName = txtCollectionName.Text, Servers = servers.GetServers(), Description = "" }; - int collectionId = ES.Services.RDS.AddRdsCollection(PanelRequest.ItemID, collection); + int collectionId = ES.Services.RDS.AddRdsCollection(PanelRequest.ItemID, collection); + + try + { + if (upPFX.HasFile.Equals(true)) + { + byte[] pfx = upPFX.FileBytes; + string certPassword = txtPFXInstallPassword.Text; + //ES.Services.RDS.InstallSessionHostsCertificate(collectionId, pfx, certPassword); + } + } + catch(Exception ex) + { + messageBox.ShowErrorMessage("RDSSESSIONHOST_CERTIFICATE_NOT_INSTALLED", ex); + } + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "rds_edit_collection", "CollectionId=" + collectionId, "ItemID=" + PanelRequest.ItemID)); } catch (Exception ex) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx index a2bd0546..56646324 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx @@ -175,6 +175,43 @@ + + + + +
+ + + + + + + + + + + + +
+ + + + + +
+ + + + + + +
+ +
+
+
+
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.cs index b64a0df6..541ff80e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.cs @@ -43,7 +43,10 @@ namespace WebsitePanel.Portal.RDS ClientPrinterRedirected = true, ClientPrinterAsDefault = true, RDEasyPrintDriverEnabled = true, - MaxRedirectedMonitors = 16 + MaxRedirectedMonitors = 16, + EncryptionLevel = EncryptionLevel.ClientCompatible.ToString(), + SecurityLayer = SecurityLayerValues.Negotiate.ToString(), + AuthenticateUsingNLA = true }; } @@ -89,6 +92,9 @@ namespace WebsitePanel.Portal.RDS chEasyPrint.Checked = collection.Settings.RDEasyPrintDriverEnabled; chEasyPrint.Enabled = collection.Settings.ClientPrinterRedirected; tbMonitorsNumber.Text = collection.Settings.MaxRedirectedMonitors.ToString(); + cbAuthentication.Checked = collection.Settings.AuthenticateUsingNLA; + ddSecurityLayer.SelectedValue = collection.Settings.SecurityLayer; + ddEncryptionLevel.SelectedValue = collection.Settings.EncryptionLevel; } private bool EditCollectionSettings() @@ -165,6 +171,9 @@ namespace WebsitePanel.Portal.RDS } settings.ClientDeviceRedirectionOptions = string.Join(",", redirectionOptions.ToArray()); + settings.AuthenticateUsingNLA = cbAuthentication.Checked; + settings.SecurityLayer = ddSecurityLayer.SelectedItem.Value; + settings.EncryptionLevel = ddEncryptionLevel.SelectedItem.Value; return settings; } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.designer.cs index 0bb4e3f3..1d2b5bc2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionSettings.ascx.designer.cs @@ -354,6 +354,69 @@ namespace WebsitePanel.Portal.RDS { /// protected global::System.Web.UI.WebControls.TextBox tbMonitorsNumber; + /// + /// secRdsSecuritySettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.CollapsiblePanel secRdsSecuritySettings; + + /// + /// panelRdsSecuritySettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel panelRdsSecuritySettings; + + /// + /// locSecurityLayer control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locSecurityLayer; + + /// + /// ddSecurityLayer control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddSecurityLayer; + + /// + /// locEncryptionLevel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locEncryptionLevel; + + /// + /// ddEncryptionLevel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddEncryptionLevel; + + /// + /// cbAuthentication control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.CheckBox cbAuthentication; + /// /// buttonPanel control. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx index 782d0213..94109cb6 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx @@ -1,4 +1,5 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RDSCollectionApps.ascx.cs" Inherits="WebsitePanel.Portal.RDS.UserControls.RDSCollectionApps" %> +<%@ Import Namespace="WebsitePanel.Portal" %> <%@ Register Src="../../UserControls/PopupHeader.ascx" TagName="PopupHeader" TagPrefix="wsp" %> @@ -28,7 +29,13 @@ - + + + + + + +