From 7a2ab59346d7f7681812119e681cde67cd46b8d5 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 27 Jul 2017 21:50:50 -0500 Subject: [PATCH] connections now just reference credential ids --- .../XmlConnectionNodeSerializer27Tests.cs | 5 ++-- ...nnectionsSerializerMremotengFormatTests.cs | 30 ++++++++++++------- mRemoteV1/App/Export.cs | 2 +- .../App/Initialization/CredsAndConsSetup.cs | 2 +- .../Config/Connections/ConnectionsSaver.cs | 2 +- .../XmlConnectionNodeSerializer27.cs | 2 +- .../XmlConnectionsDeserializer.cs | 11 +------ ...CsvConnectionsSerializerMremotengFormat.cs | 27 ++++++++++++----- .../XmlCredentialManagerUpgrader.cs | 2 +- .../Connection/AbstractConnectionRecord.cs | 8 ++--- .../Connection/Protocol/ICA/IcaProtocol.cs | 19 ++++++++---- mRemoteV1/Connection/Protocol/PuttyBase.cs | 21 ++++++++----- .../Connection/Protocol/RDP/RdpProtocol.cs | 26 ++++++++++------ .../Protocol/VNC/Connection.Protocol.VNC.cs | 13 ++++++-- 14 files changed, 107 insertions(+), 63 deletions(-) diff --git a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27Tests.cs b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27Tests.cs index 4007a058..d8f8f235 100644 --- a/mRemoteNGTests/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27Tests.cs +++ b/mRemoteNGTests/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27Tests.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Xml.Linq; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; @@ -78,7 +79,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers Username = "myuser", Domain = "superdomain", Password = "pass", - CredentialRecord = Substitute.For(), + CredentialRecordId = Guid.Empty, Hostname = "somehost", ExtApp = "myextapp", PreExtApp = "preext1", diff --git a/mRemoteNGTests/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormatTests.cs b/mRemoteNGTests/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormatTests.cs index fdecccd7..550148f6 100644 --- a/mRemoteNGTests/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormatTests.cs +++ b/mRemoteNGTests/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormatTests.cs @@ -11,18 +11,30 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers { public class CsvConnectionsSerializerMremotengFormatTests { + private ICredentialRepositoryList _credentialRepositoryList; private const string ConnectionName = "myconnection"; private const string Username = "myuser"; private const string Domain = "mydomain"; private const string Password = "mypass123"; + [OneTimeSetUp] + public void OneTimeSetup() + { + var credRecord = Substitute.For(); + credRecord.Username.Returns(Username); + credRecord.Domain.Returns(Domain); + credRecord.Password.Returns(Password.ConvertToSecureString()); + _credentialRepositoryList = Substitute.For(); + _credentialRepositoryList.GetCredentialRecord(new Guid()).ReturnsForAnyArgs(credRecord); + } + [TestCase(Username)] [TestCase(Domain)] [TestCase(Password)] [TestCase("InheritColors")] public void CreatesCsv(string valueThatShouldExist) { - var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter()); + var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList); var connectionInfo = BuildConnectionInfo(); var csv = serializer.Serialize(connectionInfo); Assert.That(csv, Does.Match(valueThatShouldExist)); @@ -35,7 +47,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers public void SerializerRespectsSaveFilterSettings(string valueThatShouldntExist) { var saveFilter = new SaveFilter(true); - var serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter); + var serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, _credentialRepositoryList); var connectionInfo = BuildConnectionInfo(); var csv = serializer.Serialize(connectionInfo); Assert.That(csv, Does.Not.Match(valueThatShouldntExist)); @@ -44,7 +56,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers [Test] public void CanSerializeEmptyConnectionInfo() { - var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter()); + var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList); var connectionInfo = new ConnectionInfo(); var csv = serializer.Serialize(connectionInfo); Assert.That(csv, Is.Not.Empty); @@ -53,33 +65,29 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers [Test] public void CantPassNullToConstructor() { - Assert.Throws(() => new CsvConnectionsSerializerMremotengFormat(null)); + Assert.Throws(() => new CsvConnectionsSerializerMremotengFormat(null, _credentialRepositoryList)); } [Test] public void CantPassNullToSerializeConnectionInfo() { - var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter()); + var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList); Assert.Throws(() => serializer.Serialize((ConnectionInfo)null)); } [Test] public void CantPassNullToSerializeConnectionTreeModel() { - var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter()); + var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList); Assert.Throws(() => serializer.Serialize((ConnectionTreeModel)null)); } private ConnectionInfo BuildConnectionInfo() { - var credRecord = Substitute.For(); - credRecord.Username.Returns(Username); - credRecord.Domain.Returns(Domain); - credRecord.Password.Returns(Password.ConvertToSecureString()); return new ConnectionInfo { Name = ConnectionName, - CredentialRecord = credRecord, + CredentialRecordId = Guid.NewGuid(), Inheritance = {Colors = true} }; } diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index 83e37add..58b1a8fb 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -84,7 +84,7 @@ namespace mRemoteNG.App serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer); break; case ConnectionsSaver.Format.mRCSV: - serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter); + serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, Runtime.CredentialProviderCatalog); break; default: throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null); diff --git a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs index 1ffce6c6..c7b3deec 100644 --- a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs +++ b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs @@ -37,7 +37,7 @@ namespace mRemoteNG.App.Initialization { var defaultCredId = Settings.Default.ConDefaultCredentialRecord; var matchedCredentials = _credentialsService.GetCredentialRecords().Where(record => record.Id.Equals(defaultCredId)).ToArray(); - DefaultConnectionInfo.Instance.CredentialRecord = matchedCredentials.Any() ? matchedCredentials.First() : null; + DefaultConnectionInfo.Instance.CredentialRecordId = matchedCredentials.Any() ? matchedCredentials.First().Id : default(Guid?); } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/ConnectionsSaver.cs b/mRemoteV1/Config/Connections/ConnectionsSaver.cs index 4fa0d609..13522c65 100644 --- a/mRemoteV1/Config/Connections/ConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/ConnectionsSaver.cs @@ -188,7 +188,7 @@ namespace mRemoteNG.Config.Connections private void SaveToMremotengFormattedCsv() { - var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(SaveFilter); + var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(SaveFilter, Runtime.CredentialProviderCatalog); var dataProvider = new FileDataProvider(ConnectionFileName); var csvContent = csvConnectionsSerializer.Serialize(ConnectionTreeModel); dataProvider.Save(csvContent); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27.cs index 142cc96e..10cd048f 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionNodeSerializer27.cs @@ -42,7 +42,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("Id", connectionInfo.ConstantID)); element.Add(_saveFilter.SaveCredentialId - ? new XAttribute("CredentialId", connectionInfo.CredentialRecord?.Id.ToString() ?? "") + ? new XAttribute("CredentialId", connectionInfo.CredentialRecordId?.ToString() ?? "") : new XAttribute("CredentialId", "")); element.Add(new XAttribute("Hostname", connectionInfo.Hostname)); diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionsDeserializer.cs index a229ec0d..d6d95b31 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/XmlConnectionsDeserializer.cs @@ -508,16 +508,7 @@ namespace mRemoteNG.Config.Serializers if (_confVersion >= 2.7) { connectionInfo.Inheritance.CredentialRecord = bool.Parse(xmlnode.Attributes["InheritCredentialRecord"]?.Value ?? "False"); - - var requestedCredentialId = xmlnode.Attributes["CredentialId"]?.Value; - if (!string.IsNullOrEmpty(requestedCredentialId) && _credentialRecords.Any()) - { - var matchingCredential = _credentialRecords.Where(record => record.Id.ToString() == requestedCredentialId).ToArray(); - if (matchingCredential.Any()) - connectionInfo.CredentialRecord = matchingCredential.First(); - else - Runtime.MessageCollector?.AddMessage(MessageClass.InformationMsg, string.Format(Language.strFindMatchingCredentialFailed, requestedCredentialId, connectionInfo.Name)); - } + connectionInfo.CredentialRecordId = Guid.Parse(xmlnode.Attributes["CredentialId"]?.Value ?? ""); } } catch (Exception ex) diff --git a/mRemoteV1/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormat.cs b/mRemoteV1/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormat.cs index b9f070dd..9d1f3126 100644 --- a/mRemoteV1/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormat.cs +++ b/mRemoteV1/Config/Serializers/MiscSerializers/CsvConnectionsSerializerMremotengFormat.cs @@ -1,7 +1,9 @@ using System; using System.Linq; +using mRemoteNG.App; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -13,13 +15,18 @@ namespace mRemoteNG.Config.Serializers private string _csv = ""; private ConnectionInfo _serializationTarget; private readonly SaveFilter _saveFilter; + private readonly ICredentialRepositoryList _credentialRepositoryList; - public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter) + public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList) { if (saveFilter == null) throw new ArgumentNullException(nameof(saveFilter)); + if (credentialRepositoryList == null) + throw new ArgumentNullException(nameof(credentialRepositoryList)); + _saveFilter = saveFilter; + _credentialRepositoryList = credentialRepositoryList; } public string Serialize(ConnectionTreeModel connectionTreeModel) @@ -83,14 +90,20 @@ namespace mRemoteNG.Config.Serializers csvLine += con.Name + ";" + GetNodePath(con) + ";" + con.Description + ";" + con.Icon + ";" + con.Panel + ";"; - if (_saveFilter.SaveUsername) - csvLine += con.CredentialRecord?.Username + ";"; + if (con.CredentialRecordId.HasValue) + { + var credentialRecord = + _credentialRepositoryList.GetCredentialRecord(con.CredentialRecordId.Value); - if (_saveFilter.SavePassword) - csvLine += con.CredentialRecord?.Password.ConvertToUnsecureString() + ";"; + if (_saveFilter.SaveUsername) + csvLine += credentialRecord?.Username + ";"; - if (_saveFilter.SaveDomain) - csvLine += con.CredentialRecord?.Domain + ";"; + if (_saveFilter.SavePassword) + csvLine += credentialRecord?.Password.ConvertToUnsecureString() + ";"; + + if (_saveFilter.SaveDomain) + csvLine += credentialRecord?.Domain + ";"; + } csvLine += con.Hostname + ";" + con.Protocol + ";" + diff --git a/mRemoteV1/Config/Serializers/Versioning/XmlCredentialManagerUpgrader.cs b/mRemoteV1/Config/Serializers/Versioning/XmlCredentialManagerUpgrader.cs index f18e30ab..46ae4fa1 100644 --- a/mRemoteV1/Config/Serializers/Versioning/XmlCredentialManagerUpgrader.cs +++ b/mRemoteV1/Config/Serializers/Versioning/XmlCredentialManagerUpgrader.cs @@ -131,7 +131,7 @@ namespace mRemoteNG.Config.Serializers.Versioning Guid id; Guid.TryParse(connectionInfo.ConstantID, out id); if (map.ContainsKey(id)) - connectionInfo.CredentialRecord = map[id]; + connectionInfo.CredentialRecordId = map[id].Id; } } } diff --git a/mRemoteV1/Connection/AbstractConnectionRecord.cs b/mRemoteV1/Connection/AbstractConnectionRecord.cs index 4e7982f0..c4e47e2d 100644 --- a/mRemoteV1/Connection/AbstractConnectionRecord.cs +++ b/mRemoteV1/Connection/AbstractConnectionRecord.cs @@ -24,7 +24,7 @@ namespace mRemoteNG.Connection private string _panel = ""; private string _hostname = ""; - private ICredentialRecord _credentialRecord; + private Guid? _credentialRecordId; private ProtocolType _protocol; private string _extApp = ""; @@ -137,10 +137,10 @@ namespace mRemoteNG.Connection LocalizedAttributes.LocalizedDescription(nameof(Language.strPropertyDescriptionCredential))] [Editor(typeof(CredentialRecordListAdaptor), typeof(UITypeEditor))] [TypeConverter(typeof(ExpandableObjectConverter))] - public virtual ICredentialRecord CredentialRecord + public virtual Guid? CredentialRecordId { - get { return GetPropertyValue(nameof(CredentialRecord), _credentialRecord); } - set { SetField(ref _credentialRecord, value, nameof(CredentialRecord)); } + get { return GetPropertyValue(nameof(CredentialRecordId), _credentialRecordId); } + set { SetField(ref _credentialRecordId, value, nameof(CredentialRecordId)); } } [Obsolete("Use the CredentialRecord property")] diff --git a/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs b/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs index 4fdf7a06..7a0a022d 100644 --- a/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs +++ b/mRemoteV1/Connection/Protocol/ICA/IcaProtocol.cs @@ -1,4 +1,5 @@ using System; +using System.Security; using AxWFICALib; using System.Windows.Forms; using mRemoteNG.App; @@ -117,11 +118,19 @@ namespace mRemoteNG.Connection.Protocol.ICA { return; } - - var user = _info.CredentialRecord?.Username ?? ""; - var pass = _info.CredentialRecord?.Password ?? "".ConvertToSecureString(); - var dom = _info.CredentialRecord?.Domain ?? ""; - + + var user = ""; + var pass = new SecureString(); + var dom = ""; + + if (_info.CredentialRecordId.HasValue) + { + var credentialRecord = Runtime.CredentialProviderCatalog.GetCredentialRecord(_info.CredentialRecordId.Value); + user = credentialRecord?.Username ?? ""; + pass = credentialRecord?.Password ?? "".ConvertToSecureString(); + dom = credentialRecord?.Domain ?? ""; + } + if (string.IsNullOrEmpty(user)) { if (Settings.Default.EmptyCredentials == "windows") diff --git a/mRemoteV1/Connection/Protocol/PuttyBase.cs b/mRemoteV1/Connection/Protocol/PuttyBase.cs index 0d090f69..0b8c2fe3 100644 --- a/mRemoteV1/Connection/Protocol/PuttyBase.cs +++ b/mRemoteV1/Connection/Protocol/PuttyBase.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Drawing; using System.Threading; using System.Windows.Forms; +using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tools.Cmdline; @@ -72,10 +73,16 @@ namespace mRemoteNG.Connection.Protocol { var username = ""; var password = ""; - - if (!string.IsNullOrEmpty(InterfaceControl.Info.CredentialRecord?.Username)) + var credentialRecord = default(ICredentialRecord); + + if (InterfaceControl.Info.CredentialRecordId.HasValue) + { + credentialRecord = Runtime.CredentialProviderCatalog.GetCredentialRecord(InterfaceControl.Info.CredentialRecordId.Value); + } + + if (!string.IsNullOrEmpty(credentialRecord?.Username)) { - username = InterfaceControl.Info.CredentialRecord?.Username; + username = credentialRecord.Username; } else { @@ -90,10 +97,10 @@ namespace mRemoteNG.Connection.Protocol break; } } - - if (!string.IsNullOrEmpty(InterfaceControl.Info.CredentialRecord?.Password.ConvertToUnsecureString())) + + if (!string.IsNullOrEmpty(credentialRecord?.Password.ConvertToUnsecureString())) { - password = InterfaceControl.Info.CredentialRecord?.Password.ConvertToUnsecureString(); + password = credentialRecord.Password.ConvertToUnsecureString(); } else { @@ -103,7 +110,7 @@ namespace mRemoteNG.Connection.Protocol password = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey); } } - + arguments.Add("-" + (int)PuttySSHVersion); if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials) diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs index 1090cc8c..7dcc0ab7 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs @@ -346,12 +346,12 @@ namespace mRemoteNG.Connection.Protocol.RDP { if (_connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.Yes) { - if (_connectionInfo.CredentialRecord != null) - { - _rdpClient.TransportSettings2.GatewayUsername = _connectionInfo.CredentialRecord.Username; - _rdpClient.TransportSettings2.GatewayPassword = _connectionInfo.CredentialRecord.Password.ConvertToUnsecureString(); - _rdpClient.TransportSettings2.GatewayDomain = _connectionInfo.CredentialRecord.Domain; - } + if (!_connectionInfo.CredentialRecordId.HasValue) return; + var credentialRecord = + Runtime.CredentialProviderCatalog.GetCredentialRecord(_connectionInfo.CredentialRecordId.Value); + _rdpClient.TransportSettings2.GatewayUsername = credentialRecord?.Username; + _rdpClient.TransportSettings2.GatewayPassword = credentialRecord?.Password.ConvertToUnsecureString(); + _rdpClient.TransportSettings2.GatewayDomain = credentialRecord?.Domain; } else if (_connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard) { @@ -420,9 +420,17 @@ namespace mRemoteNG.Connection.Protocol.RDP return; } - var userName = _connectionInfo.CredentialRecord?.Username ?? ""; - var password = _connectionInfo.CredentialRecord?.Password ?? new SecureString(); - var domain = _connectionInfo.CredentialRecord?.Domain ?? ""; + var userName = ""; + var password = new SecureString(); + var domain = ""; + + if (_connectionInfo.CredentialRecordId.HasValue) + { + var credentialRecord = Runtime.CredentialProviderCatalog.GetCredentialRecord(_connectionInfo.CredentialRecordId.Value); + userName = credentialRecord?.Username ?? ""; + password = credentialRecord?.Password ?? new SecureString(); + domain = credentialRecord?.Domain ?? ""; + } if (string.IsNullOrEmpty(userName)) { diff --git a/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs b/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs index 153e6b44..d2c27076 100644 --- a/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs +++ b/mRemoteV1/Connection/Protocol/VNC/Connection.Protocol.VNC.cs @@ -165,7 +165,11 @@ namespace mRemoteNG.Connection.Protocol.VNC _VNC.ConnectComplete += VNCEvent_Connected; _VNC.ConnectionLost += VNCEvent_Disconnected; FrmMain.ClipboardChanged += VNCEvent_ClipboardChanged; - if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials && !string.IsNullOrEmpty(Info.CredentialRecord?.Password.ConvertToUnsecureString())) + if (!Info.CredentialRecordId.HasValue) + return; + var credentialRecord = Runtime.CredentialProviderCatalog.GetCredentialRecord(Info.CredentialRecordId.Value); + if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials + && credentialRecord?.Password?.Length > 0) { _VNC.GetPassword = VNCEvent_Authenticate; } @@ -198,9 +202,12 @@ namespace mRemoteNG.Connection.Protocol.VNC private string VNCEvent_Authenticate() { - return Info.CredentialRecord?.Password.ConvertToUnsecureString() ?? ""; + return Info.CredentialRecordId.HasValue + ? Runtime.CredentialProviderCatalog.GetCredentialRecord(Info.CredentialRecordId.Value).Password.ConvertToUnsecureString() + : ""; } - #endregion + + #endregion #region Enums public enum Defaults