Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/mRemoteNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortecxx <tecxx@rrs.at>2022-09-07 15:08:29 +0300
committertecxx <tecxx@rrs.at>2022-09-07 15:08:29 +0300
commitd9c01148b7330cdb016d308f8c3c3cfd7e3211bb (patch)
treed728a38b0df7b21031f77f0497470cbb16a81728
parent2b3cfd992fcb4c0dd1628cc5eb0baa2e06a2a305 (diff)
support extraction of SSH private keys from external credential provider (DSS)
supported formats: rsa, rsa with passphrase, putty private key
-rw-r--r--ExternalConnectors/DSS/SecretServerInterface.cs114
-rw-r--r--ExternalConnectors/DSS/SecretServerRestClient.cs11
-rw-r--r--ExternalConnectors/ExternalConnectors.csproj1
-rw-r--r--ExternalConnectors/PuttyKeyFileGenerator.cs109
-rw-r--r--mRemoteNG/Connection/Protocol/PuttyBase.cs53
-rw-r--r--mRemoteNG/Connection/Protocol/RDP/RdpProtocol6.cs10
-rw-r--r--mRemoteNG/Language/Language.resx4
-rw-r--r--mRemoteNG/Properties/OptionsCredentialsPage.Designer.cs25
-rw-r--r--mRemoteNG/UI/Forms/OptionsPages/CredentialsPage.cs4
9 files changed, 296 insertions, 35 deletions
diff --git a/ExternalConnectors/DSS/SecretServerInterface.cs b/ExternalConnectors/DSS/SecretServerInterface.cs
index 767ec4de..1a6f3e37 100644
--- a/ExternalConnectors/DSS/SecretServerInterface.cs
+++ b/ExternalConnectors/DSS/SecretServerInterface.cs
@@ -1,6 +1,11 @@
using Microsoft.Win32;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.OpenSsl;
+using Org.BouncyCastle.Security;
using SecretServerAuthentication.DSS;
using SecretServerRestClient.DSS;
+using System.Security.Cryptography;
namespace ExternalConnectors.DSS
{
@@ -114,25 +119,22 @@ namespace ExternalConnectors.DSS
}
}
- private static void FetchSecret(int secretID, out string secretUsername, out string secretPassword, out string secretDomain)
+ private static SecretsServiceClient ConstructSecretsServiceClient()
{
string baseURL = SSConnectionData.ssUrl;
-
- SecretModel secret;
if (SSConnectionData.ssSSO)
{
// REQUIRES IIS CONFIG! https://docs.thycotic.com/ss/11.0.0/api-scripting/webservice-iwa-powershell
var handler = new HttpClientHandler() { UseDefaultCredentials = true };
- using (var httpClient = new HttpClient(handler))
+ var httpClient = new HttpClient(handler);
{
// Call REST API:
- var client = new SecretsServiceClient($"{baseURL}/winauthwebservices/api", httpClient);
- secret = client.GetSecretAsync(false, true, secretID, null).Result;
+ return new SecretsServiceClient($"{baseURL}/winauthwebservices/api", httpClient);
}
}
else
{
- using (var httpClient = new HttpClient())
+ var httpClient = new HttpClient();
{
var token = GetToken();
@@ -140,15 +142,22 @@ namespace ExternalConnectors.DSS
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
// Call REST API:
- var client = new SecretsServiceClient($"{baseURL}/api", httpClient);
- secret = client.GetSecretAsync(false, true, secretID, null).Result;
+ return new SecretsServiceClient($"{baseURL}/api", httpClient);
}
}
+ }
+ private static void FetchSecret(int secretID, out string secretUsername, out string secretPassword, out string secretDomain, out string privatekey)
+ {
+ var client = ConstructSecretsServiceClient();
+ SecretModel secret = client.GetSecretAsync(false, true, secretID, null).Result;
+
// clear return variables
secretDomain = "";
secretUsername = "";
secretPassword = "";
+ privatekey = "";
+ string privatekeypassphrase = "";
// parse data and extract what we need
foreach (var item in secret.Items)
@@ -159,10 +168,91 @@ namespace ExternalConnectors.DSS
secretUsername = item.ItemValue;
else if (item.FieldName.ToLower().Equals("password"))
secretPassword = item.ItemValue;
+ else if (item.FieldName.ToLower().Equals("private key"))
+ {
+ client.ReadResponseNoJSONConvert = true;
+ privatekey = client.GetFieldAsync(false, false, secretID, "private-key").Result;
+ client.ReadResponseNoJSONConvert = false;
+ }
+ else if (item.FieldName.ToLower().Equals("private key passphrase"))
+ privatekeypassphrase = item.ItemValue;
}
+ // need to decode the private key?
+ if (!string.IsNullOrEmpty(privatekeypassphrase))
+ {
+ try
+ {
+ var key = DecodePrivateKey(privatekey, privatekeypassphrase);
+ privatekey = key;
+ }
+ catch(Exception)
+ {
+
+ }
+ }
+
+ // conversion to putty format necessary?
+ if (!string.IsNullOrEmpty(privatekey) && !privatekey.StartsWith("PuTTY-User-Key-File-2"))
+ {
+ try
+ {
+ RSACryptoServiceProvider key = ImportPrivateKey(privatekey);
+ privatekey = PuttyKeyFileGenerator.ToPuttyPrivateKey(key);
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ #region PUTTY KEY HANDLING
+ // decode rsa private key with encryption password
+ private static string DecodePrivateKey(string encryptedPrivateKey, string password)
+ {
+ TextReader textReader = new StringReader(encryptedPrivateKey);
+ PemReader pemReader = new PemReader(textReader, new PasswordFinder(password));
+
+ AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
+
+ TextWriter textWriter = new StringWriter();
+ var pemWriter = new PemWriter(textWriter);
+ pemWriter.WriteObject(keyPair.Private);
+ pemWriter.Writer.Flush();
+
+ return ""+textWriter.ToString();
+ }
+ private class PasswordFinder : IPasswordFinder
+ {
+ private string password;
+
+ public PasswordFinder(string password)
+ {
+ this.password = password;
+ }
+
+
+ public char[] GetPassword()
+ {
+ return password.ToCharArray();
+ }
}
+ // read private key pem string to rsacryptoserviceprovider
+ public static RSACryptoServiceProvider ImportPrivateKey(string pem)
+ {
+ PemReader pr = new PemReader(new StringReader(pem));
+ AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
+ RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
+ RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
+ rsa.ImportParameters(rsaParams);
+ return rsa;
+ }
+ #endregion
+
+
+ #region TOKEN
private static string GetToken()
{
// if there is no token, fetch a fresh one
@@ -233,11 +323,11 @@ namespace ExternalConnectors.DSS
return tokenResult;
}
}
-
+ #endregion
// input must be the secret id to fetch
- public static void FetchSecretFromServer(string input, out string username, out string password, out string domain)
+ public static void FetchSecretFromServer(string input, out string username, out string password, out string domain, out string privatekey)
{
// get secret id
int secretID = Int32.Parse(input);
@@ -246,7 +336,7 @@ namespace ExternalConnectors.DSS
SSConnectionData.Init();
// get the secret
- FetchSecret(secretID, out username, out password, out domain);
+ FetchSecret(secretID, out username, out password, out domain, out privatekey);
}
}
}
diff --git a/ExternalConnectors/DSS/SecretServerRestClient.cs b/ExternalConnectors/DSS/SecretServerRestClient.cs
index 614088df..20da6367 100644
--- a/ExternalConnectors/DSS/SecretServerRestClient.cs
+++ b/ExternalConnectors/DSS/SecretServerRestClient.cs
@@ -72886,6 +72886,9 @@ namespace SecretServerRestClient.DSS
}
public bool ReadResponseAsString { get; set; }
+ // RR 2022-09-97
+ public bool ReadResponseNoJSONConvert { get; set; }
+ // RR END
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Threading.CancellationToken cancellationToken)
{
@@ -72894,6 +72897,14 @@ namespace SecretServerRestClient.DSS
return new ObjectResponseResult<T>(default(T), string.Empty);
}
+ // RR 2022-09-97
+ if (ReadResponseNoJSONConvert)
+ {
+ var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return new ObjectResponseResult<T>((T)(object)responseText, responseText); // not sure if this is best practice, but it works.
+ }
+ // RR END
+
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
diff --git a/ExternalConnectors/ExternalConnectors.csproj b/ExternalConnectors/ExternalConnectors.csproj
index 4e341403..35422251 100644
--- a/ExternalConnectors/ExternalConnectors.csproj
+++ b/ExternalConnectors/ExternalConnectors.csproj
@@ -14,6 +14,7 @@
<PackageReference Include="AWSSDK.Core" Version="3.7.12.15" />
<PackageReference Include="AWSSDK.EC2" Version="3.7.79.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+ <PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
</ItemGroup>
<ItemGroup>
diff --git a/ExternalConnectors/PuttyKeyFileGenerator.cs b/ExternalConnectors/PuttyKeyFileGenerator.cs
new file mode 100644
index 00000000..6c62bca7
--- /dev/null
+++ b/ExternalConnectors/PuttyKeyFileGenerator.cs
@@ -0,0 +1,109 @@
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace ExternalConnectors;
+
+public class PuttyKeyFileGenerator
+{
+ private const int prefixSize = 4;
+ private const int paddedPrefixSize = prefixSize + 1;
+ private const int lineLength = 64;
+ private const string keyType = "ssh-rsa";
+ private const string encryptionType = "none";
+
+ // source from
+ // https://gist.github.com/canton7/5670788?permalink_comment_id=3240331
+ // https://gist.github.com/bosima/ee6630d30b533c7d7b2743a849e9b9d0
+
+ public static string ToPuttyPrivateKey(RSACryptoServiceProvider cryptoServiceProvider, string Comment = "imported-openssh-key")
+ {
+ var publicParameters = cryptoServiceProvider.ExportParameters(false);
+ byte[] publicBuffer = new byte[3 + keyType.Length + GetPrefixSize(publicParameters.Exponent) + publicParameters.Exponent.Length +
+ GetPrefixSize(publicParameters.Modulus) + publicParameters.Modulus.Length + 1];
+
+ using (var bw = new BinaryWriter(new MemoryStream(publicBuffer)))
+ {
+ bw.Write(new byte[] { 0x00, 0x00, 0x00 });
+ bw.Write(keyType);
+ PutPrefixed(bw, publicParameters.Exponent, CheckIsNeddPadding(publicParameters.Exponent));
+ PutPrefixed(bw, publicParameters.Modulus, CheckIsNeddPadding(publicParameters.Modulus));
+ }
+ var publicBlob = System.Convert.ToBase64String(publicBuffer);
+
+ var privateParameters = cryptoServiceProvider.ExportParameters(true);
+ byte[] privateBuffer = new byte[paddedPrefixSize + privateParameters.D.Length + paddedPrefixSize + privateParameters.P.Length + paddedPrefixSize + privateParameters.Q.Length + paddedPrefixSize + privateParameters.InverseQ.Length];
+
+ using (var bw = new BinaryWriter(new MemoryStream(privateBuffer)))
+ {
+ PutPrefixed(bw, privateParameters.D, true);
+ PutPrefixed(bw, privateParameters.P, true);
+ PutPrefixed(bw, privateParameters.Q, true);
+ PutPrefixed(bw, privateParameters.InverseQ, true);
+ }
+ var privateBlob = System.Convert.ToBase64String(privateBuffer);
+
+ HMACSHA1 hmacsha1 = new HMACSHA1(new SHA1CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes("putty-private-key-file-mac-key")));
+ //byte[] bytesToHash = new byte[4 + 7 + 4 + 4 + 4 + Comment.Length + 4 + publicBuffer.Length + 4 + privateBuffer.Length];
+ byte[] bytesToHash = new byte[prefixSize + keyType.Length + prefixSize + encryptionType.Length + prefixSize + Comment.Length +
+ prefixSize + publicBuffer.Length + prefixSize + privateBuffer.Length];
+
+ using (var bw = new BinaryWriter(new MemoryStream(bytesToHash)))
+ {
+ PutPrefixed(bw, Encoding.ASCII.GetBytes("ssh-rsa"));
+ PutPrefixed(bw, Encoding.ASCII.GetBytes("none"));
+ PutPrefixed(bw, Encoding.ASCII.GetBytes(Comment));
+ PutPrefixed(bw, publicBuffer);
+ PutPrefixed(bw, privateBuffer);
+ }
+
+ var hash = string.Join("", hmacsha1.ComputeHash(bytesToHash).Select(x => string.Format("{0:x2}", x)));
+
+ var sb = new StringBuilder();
+ sb.AppendLine("PuTTY-User-Key-File-2: " + keyType);
+ sb.AppendLine("Encryption: " + encryptionType);
+ sb.AppendLine("Comment: " + Comment);
+
+ var publicLines = SpliceText(publicBlob, lineLength);
+ sb.AppendLine("Public-Lines: " + publicLines.Length);
+ foreach (var line in publicLines)
+ {
+ sb.AppendLine(line);
+ }
+
+ var privateLines = SpliceText(privateBlob, lineLength);
+ sb.AppendLine("Private-Lines: " + privateLines.Length);
+ foreach (var line in privateLines)
+ {
+ sb.AppendLine(line);
+ }
+
+ sb.AppendLine("Private-MAC: " + hash);
+
+ return sb.ToString();
+ }
+ private static void PutPrefixed(BinaryWriter bw, byte[] bytes, bool addLeadingNull = false)
+ {
+ bw.Write(BitConverter.GetBytes(bytes.Length + (addLeadingNull ? 1 : 0)).Reverse().ToArray());
+ if (addLeadingNull)
+ bw.Write(new byte[] { 0x00 });
+ bw.Write(bytes);
+ }
+
+ private static string[] SpliceText(string text, int lineLength)
+ {
+ return Regex.Matches(text, ".{1," + lineLength + "}").Cast<Match>().Select(m => m.Value).ToArray();
+ }
+ private static int GetPrefixSize(byte[] bytes)
+ {
+ return CheckIsNeddPadding(bytes) ? paddedPrefixSize : prefixSize;
+ }
+ private static bool CheckIsNeddPadding(byte[] bytes)
+ {
+ // 128 == 10000000
+ // This means that the number of bits can be divided by 8.
+ // According to the algorithm in putty, you need to add a padding.
+ return bytes[0] >= 128;
+ }
+
+} \ No newline at end of file
diff --git a/mRemoteNG/Connection/Protocol/PuttyBase.cs b/mRemoteNG/Connection/Protocol/PuttyBase.cs
index 5dc16473..5b956d56 100644
--- a/mRemoteNG/Connection/Protocol/PuttyBase.cs
+++ b/mRemoteNG/Connection/Protocol/PuttyBase.cs
@@ -12,6 +12,7 @@ using System.Windows.Forms;
using mRemoteNG.Properties;
using mRemoteNG.Resources.Language;
using Connection;
+using System.IO;
// ReSharper disable ArrangeAccessorOwnerBody
@@ -57,6 +58,8 @@ namespace mRemoteNG.Connection.Protocol
public override bool Connect()
{
+ string optionalTemporaryPrivateKeyPath = ""; // path to ppk file instead of password. only temporary (extracted from credential vault).
+
try
{
_isPuttyNg = PuttyTypeDetector.GetPuttyType() == PuttyTypeDetector.PuttyType.PuttyNg;
@@ -85,14 +88,22 @@ namespace mRemoteNG.Connection.Protocol
var password = InterfaceControl.Info?.Password ?? "";
var domain = InterfaceControl.Info?.Domain ?? "";
var UserViaAPI = InterfaceControl.Info?.UserViaAPI ?? "";
-
+ string privatekey = "";
// access secret server api if necessary
if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
{
try
{
- ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out username, out password, out domain);
+ ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out username, out password, out domain, out privatekey);
+
+ if (!string.IsNullOrEmpty(privatekey))
+ {
+ optionalTemporaryPrivateKeyPath = Path.GetTempFileName();
+ File.WriteAllText(optionalTemporaryPrivateKeyPath, privatekey);
+ FileInfo fileInfo = new FileInfo(optionalTemporaryPrivateKeyPath);
+ fileInfo.Attributes = FileAttributes.Temporary;
+ }
}
catch (Exception ex)
{
@@ -111,22 +122,26 @@ namespace mRemoteNG.Connection.Protocol
username = Properties.OptionsCredentialsPage.Default.DefaultUsername;
break;
case "custom":
- try
- {
- ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer(
- "SSAPI:" + Properties.OptionsCredentialsPage.Default.UserViaAPDefault, out username, out password,
- out domain);
- }
- catch (Exception ex)
+
+ if (Properties.OptionsCredentialsPage.Default.ExternalCredentialProviderDefault == ExternalCredentialProvider.DelineaSecretServer)
{
- Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
+ try
+ {
+ ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer(
+ $"{Properties.OptionsCredentialsPage.Default.UserViaAPIDefault}", out username, out password, out domain, out privatekey);
+ }
+ catch (Exception ex)
+ {
+ Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
+ }
}
+
break;
}
}
- if (string.IsNullOrEmpty(password))
+ if (string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(optionalTemporaryPrivateKeyPath))
{
if (Properties.OptionsCredentialsPage.Default.EmptyCredentials == "custom")
{
@@ -149,6 +164,13 @@ namespace mRemoteNG.Connection.Protocol
arguments.Add("-pw", password);
}
}
+
+ // use private key if specified
+ if (!string.IsNullOrEmpty(optionalTemporaryPrivateKeyPath))
+ {
+ arguments.Add("-i", optionalTemporaryPrivateKeyPath);
+ }
+
}
arguments.Add("-P", InterfaceControl.Info.Port.ToString());
@@ -219,6 +241,15 @@ namespace mRemoteNG.Connection.Protocol
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.ConnectionFailed + Environment.NewLine + ex.Message);
return false;
}
+ finally
+ {
+ // make sure to remove the private key file
+ if (!string.IsNullOrEmpty(optionalTemporaryPrivateKeyPath))
+ {
+ System.Threading.Thread.Sleep(500);
+ System.IO.File.Delete(optionalTemporaryPrivateKeyPath);
+ }
+ }
}
public override void Focus()
diff --git a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol6.cs b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol6.cs
index fc326113..6f5c89d5 100644
--- a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol6.cs
+++ b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol6.cs
@@ -409,14 +409,15 @@ namespace mRemoteNG.Connection.Protocol.RDP
string gwu = connectionInfo.RDGatewayUsername;
string gwp = connectionInfo.RDGatewayPassword;
string gwd = connectionInfo.RDGatewayDomain;
+ string pkey = "";
// access secret server api if necessary
if (InterfaceControl.Info.RDGatewayExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
{
try
{
- string idviaapi = InterfaceControl.Info.RDGatewayUserViaAPI;
- ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{idviaapi}", out gwu, out gwp, out gwd);
+ string RDGUserViaAPI = InterfaceControl.Info.RDGatewayUserViaAPI;
+ ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{RDGUserViaAPI}", out gwu, out gwp, out gwd, out pkey);
}
catch (Exception ex)
{
@@ -494,13 +495,14 @@ namespace mRemoteNG.Connection.Protocol.RDP
var password = connectionInfo?.Password ?? "";
var domain = connectionInfo?.Domain ?? "";
var UserViaAPI = connectionInfo?.UserViaAPI ?? "";
+ string pkey = "";
// access secret server api if necessary
if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
{
try
{
- ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out userName, out password, out domain);
+ ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out userName, out password, out domain, out pkey);
}
catch (Exception ex)
{
@@ -522,7 +524,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
case "custom":
try
{
- ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer("SSAPI:" + Properties.OptionsCredentialsPage.Default.UserViaAPDefault, out userName, out password, out domain);
+ ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer(Properties.OptionsCredentialsPage.Default.UserViaAPIDefault, out userName, out password, out domain, out pkey);
_rdpClient.UserName = userName;
}
catch (Exception ex)
diff --git a/mRemoteNG/Language/Language.resx b/mRemoteNG/Language/Language.resx
index 31fb974d..511f1633 100644
--- a/mRemoteNG/Language/Language.resx
+++ b/mRemoteNG/Language/Language.resx
@@ -2200,10 +2200,10 @@ Nightly Channel includes Alphas, Betas &amp; Release Candidates.</value>
<comment>https://docs.microsoft.com/en-us/windows/win32/termserv/imstscsecuredsettings-workdir</comment>
</data>
<data name="OpeningCommand" xml:space="preserve">
- <value>TODO</value>
+ <value>OpeningCommand TODO</value>
</data>
<data name="PropertyDescriptionOpeningCommand" xml:space="preserve">
- <value>TODO</value>
+ <value>Description of OpeningCommand TODO</value>
</data>
<data name="RedirectDrives" xml:space="preserve">
<value>Disk Drives</value>
diff --git a/mRemoteNG/Properties/OptionsCredentialsPage.Designer.cs b/mRemoteNG/Properties/OptionsCredentialsPage.Designer.cs
index 5d3736f4..8e7f71c0 100644
--- a/mRemoteNG/Properties/OptionsCredentialsPage.Designer.cs
+++ b/mRemoteNG/Properties/OptionsCredentialsPage.Designer.cs
@@ -8,6 +8,8 @@
// </auto-generated>
//------------------------------------------------------------------------------
+using Connection;
+
namespace mRemoteNG.Properties {
@@ -58,16 +60,31 @@ namespace mRemoteNG.Properties {
this["DefaultDomain"] = value;
}
}
-
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public ExternalCredentialProvider ExternalCredentialProviderDefault
+ {
+ get
+ {
+ return ((ExternalCredentialProvider)(this["ExternalCredentialProviderDefault"]));
+ }
+ set
+ {
+ this["ExternalCredentialProviderDefault"] = value;
+ }
+ }
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
- public string UserViaAPDefault {
+ public string UserViaAPIDefault {
get {
- return ((string)(this["UserViaAPDefault"]));
+ return ((string)(this["UserViaAPIDefault"]));
}
set {
- this["UserViaAPDefault"] = value;
+ this["UserViaAPIDefault"] = value;
}
}
diff --git a/mRemoteNG/UI/Forms/OptionsPages/CredentialsPage.cs b/mRemoteNG/UI/Forms/OptionsPages/CredentialsPage.cs
index 2d5fcf30..13b45faf 100644
--- a/mRemoteNG/UI/Forms/OptionsPages/CredentialsPage.cs
+++ b/mRemoteNG/UI/Forms/OptionsPages/CredentialsPage.cs
@@ -54,7 +54,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
txtCredentialsPassword.Text =
cryptographyProvider.Decrypt(Properties.OptionsCredentialsPage.Default.DefaultPassword, Runtime.EncryptionKey);
txtCredentialsDomain.Text = Properties.OptionsCredentialsPage.Default.DefaultDomain;
- txtCredentialsUserViaAPI.Text = Properties.OptionsCredentialsPage.Default.UserViaAPDefault;
+ txtCredentialsUserViaAPI.Text = Properties.OptionsCredentialsPage.Default.UserViaAPIDefault;
}
public override void SaveSettings()
@@ -77,7 +77,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Properties.OptionsCredentialsPage.Default.DefaultPassword =
cryptographyProvider.Encrypt(txtCredentialsPassword.Text, Runtime.EncryptionKey);
Properties.OptionsCredentialsPage.Default.DefaultDomain = txtCredentialsDomain.Text;
- Properties.OptionsCredentialsPage.Default.UserViaAPDefault = txtCredentialsUserViaAPI.Text;
+ Properties.OptionsCredentialsPage.Default.UserViaAPIDefault = txtCredentialsUserViaAPI.Text;
}
private void radCredentialsCustom_CheckedChanged(object sender, EventArgs e)