diff --git a/ExternalConnectors/ExternalConnectors.csproj b/ExternalConnectors/ExternalConnectors.csproj
index b121be69..c6c49b4a 100644
--- a/ExternalConnectors/ExternalConnectors.csproj
+++ b/ExternalConnectors/ExternalConnectors.csproj
@@ -26,5 +26,8 @@
+
+ Form
+
diff --git a/ExternalConnectors/VO/VaultOpenbao.cs b/ExternalConnectors/VO/VaultOpenbao.cs
index c41d9942..b39a1bc4 100644
--- a/ExternalConnectors/VO/VaultOpenbao.cs
+++ b/ExternalConnectors/VO/VaultOpenbao.cs
@@ -1,6 +1,8 @@
-using Newtonsoft.Json.Linq;
+using Microsoft.Win32;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -15,10 +17,29 @@ namespace ExternalConnectors.VO {
}
public static class VaultOpenbao {
- private static VaultClient GetClient(string url, string token) {
+ private static RegistryKey baseKey = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteVaultOpenbao");
+ private static string token = "";
+ private static VaultClient GetClient() {
+ string url = (string)baseKey.GetValue("URL", "");
+ if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(token)) {
+ using VaultOpenbaoConnectionForm voForm = new();
+ voForm.tbUrl.Text = url;
+ _ = voForm.ShowDialog();
+ if (voForm.DialogResult != DialogResult.OK)
+ throw new VaultOpenbaoException($"No credential provided", null);
+ url = voForm.tbUrl.Text;
+ token = voForm.tbToken.Text;
+ }
IAuthMethodInfo authMethod = new TokenAuthMethodInfo(token);
var vaultClientSettings = new VaultClientSettings(url, authMethod);
- return new(vaultClientSettings);
+ VaultClient client = new(vaultClientSettings);
+ var sysInfo = client.V1.System.GetInitStatusAsync().Result;
+ if (!sysInfo) {
+ MessageBox.Show("Test connection failed", "Vault Openbao", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ throw new VaultOpenbaoException($"Url not working", null);
+ }
+ baseKey.SetValue("URL", url);
+ return client;
}
private static void TestMountType(VaultClient vaultClient, string mount, int VaultOpenbaoSecretEngine) {
switch (vaultClient.V1.System.GetSecretBackendAsync(mount).Result.Data.Type.Type) {
@@ -28,8 +49,8 @@ namespace ExternalConnectors.VO {
throw new VaultOpenbaoException($"Backend of type ldap does not match expected type {VaultOpenbaoSecretEngine}", null);
}
}
- public static void ReadPasswordSSH(string url, string token, int secretEngine, string mount, string role, string username, out string password) {
- VaultClient vaultClient = GetClient(url, token);
+ public static void ReadPasswordSSH(int secretEngine, string mount, string role, string username, out string password) {
+ VaultClient vaultClient = GetClient();
TestMountType(vaultClient, mount, secretEngine);
switch (secretEngine) {
case 0:
@@ -45,8 +66,8 @@ namespace ExternalConnectors.VO {
}
}
- public static void ReadPasswordRDP(string url, string token, int secretEngine, string mount, string role, ref string username, out string password) {
- VaultClient vaultClient = GetClient(url, token);
+ public static void ReadPasswordRDP(int secretEngine, string mount, string role, ref string username, out string password) {
+ VaultClient vaultClient = GetClient();
TestMountType(vaultClient, mount, secretEngine);
switch (secretEngine) {
case 0:
@@ -63,7 +84,7 @@ namespace ExternalConnectors.VO {
username = ldaps.Data.Username;
password = ldaps.Data.Password;
return;
-
+
default:
throw new VaultOpenbaoException($"Backend of type {secretEngine} is not supported", null);
}
diff --git a/ExternalConnectors/VO/VaultOpenbaoConnectionForm.Designer.cs b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.Designer.cs
new file mode 100644
index 00000000..957d291f
--- /dev/null
+++ b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.Designer.cs
@@ -0,0 +1,184 @@
+namespace ExternalConnectors.VO
+{
+ partial class VaultOpenbaoConnectionForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ tbUrl = new TextBox();
+ tbToken = new TextBox();
+ btnOK = new Button();
+ btnCancel = new Button();
+ tableLayoutPanel1 = new TableLayoutPanel();
+ label1 = new Label();
+ label2 = new Label();
+ tableLayoutPanel2 = new TableLayoutPanel();
+ tableLayoutPanel1.SuspendLayout();
+ tableLayoutPanel2.SuspendLayout();
+ SuspendLayout();
+ //
+ // tbUrl
+ //
+ tbUrl.Dock = DockStyle.Fill;
+ tbUrl.Location = new Point(174, 5);
+ tbUrl.Margin = new Padding(5);
+ tbUrl.Name = "tbUrl";
+ tbUrl.Size = new Size(559, 27);
+ tbUrl.TabIndex = 0;
+ //
+ // tbToken
+ //
+ tbToken.Dock = DockStyle.Fill;
+ tbToken.Location = new Point(174, 57);
+ tbToken.Margin = new Padding(5);
+ tbToken.Name = "tbToken";
+ tbToken.Size = new Size(559, 27);
+ tbToken.TabIndex = 2;
+ tbToken.UseSystemPasswordChar = true;
+ //
+ // btnOK
+ //
+ btnOK.Anchor = AnchorStyles.Right;
+ btnOK.DialogResult = DialogResult.OK;
+ btnOK.Location = new Point(250, 16);
+ btnOK.Margin = new Padding(5);
+ btnOK.Name = "btnOK";
+ btnOK.Size = new Size(101, 35);
+ btnOK.TabIndex = 10;
+ btnOK.Text = "OK";
+ btnOK.UseVisualStyleBackColor = true;
+ //
+ // btnCancel
+ //
+ btnCancel.Anchor = AnchorStyles.Left;
+ btnCancel.DialogResult = DialogResult.Cancel;
+ btnCancel.Location = new Point(387, 16);
+ btnCancel.Margin = new Padding(5);
+ btnCancel.Name = "btnCancel";
+ btnCancel.Size = new Size(101, 35);
+ btnCancel.TabIndex = 11;
+ btnCancel.Text = "Cancel";
+ btnCancel.UseVisualStyleBackColor = true;
+ //
+ // tableLayoutPanel1
+ //
+ tableLayoutPanel1.ColumnCount = 2;
+ tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 22.92994F));
+ tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 77.07006F));
+ tableLayoutPanel1.Controls.Add(label1, 0, 0);
+ tableLayoutPanel1.Controls.Add(label2, 0, 1);
+ tableLayoutPanel1.Controls.Add(tbUrl, 1, 0);
+ tableLayoutPanel1.Controls.Add(tbToken, 1, 1);
+ tableLayoutPanel1.Dock = DockStyle.Top;
+ tableLayoutPanel1.Location = new Point(0, 0);
+ tableLayoutPanel1.Margin = new Padding(5);
+ tableLayoutPanel1.Name = "tableLayoutPanel1";
+ tableLayoutPanel1.RowCount = 3;
+ tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
+ tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
+ tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 31F));
+ tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 31F));
+ tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 31F));
+ tableLayoutPanel1.Size = new Size(738, 136);
+ tableLayoutPanel1.TabIndex = 12;
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Dock = DockStyle.Fill;
+ label1.Location = new Point(5, 0);
+ label1.Margin = new Padding(5, 0, 5, 0);
+ label1.Name = "label1";
+ label1.Size = new Size(159, 52);
+ label1.TabIndex = 2;
+ label1.Text = "Server URL";
+ label1.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Dock = DockStyle.Fill;
+ label2.Location = new Point(5, 52);
+ label2.Margin = new Padding(5, 0, 5, 0);
+ label2.Name = "label2";
+ label2.Size = new Size(159, 52);
+ label2.TabIndex = 4;
+ label2.Text = "Access Token";
+ label2.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // tableLayoutPanel2
+ //
+ tableLayoutPanel2.ColumnCount = 5;
+ tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 106F));
+ tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
+ tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 26F));
+ tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
+ tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 106F));
+ tableLayoutPanel2.Controls.Add(btnOK, 1, 0);
+ tableLayoutPanel2.Controls.Add(btnCancel, 3, 0);
+ tableLayoutPanel2.Dock = DockStyle.Bottom;
+ tableLayoutPanel2.Location = new Point(0, 149);
+ tableLayoutPanel2.Margin = new Padding(5);
+ tableLayoutPanel2.Name = "tableLayoutPanel2";
+ tableLayoutPanel2.RowCount = 1;
+ tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
+ tableLayoutPanel2.Size = new Size(738, 67);
+ tableLayoutPanel2.TabIndex = 13;
+ //
+ // VaultOpenbaoConnectionForm
+ //
+ AcceptButton = btnOK;
+ AutoScaleDimensions = new SizeF(8F, 20F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(738, 216);
+ Controls.Add(tableLayoutPanel2);
+ Controls.Add(tableLayoutPanel1);
+ FormBorderStyle = FormBorderStyle.FixedDialog;
+ Margin = new Padding(5);
+ MaximizeBox = false;
+ MinimizeBox = false;
+ Name = "VaultOpenbaoConnectionForm";
+ SizeGripStyle = SizeGripStyle.Hide;
+ Text = "Vault/Openbao API Login Data";
+ Activated += VaultOpenbaoConnectionForm_Activated;
+ tableLayoutPanel1.ResumeLayout(false);
+ tableLayoutPanel1.PerformLayout();
+ tableLayoutPanel2.ResumeLayout(false);
+ ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ public System.Windows.Forms.TextBox tbUrl;
+ public System.Windows.Forms.TextBox tbToken;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ }
+}
\ No newline at end of file
diff --git a/ExternalConnectors/VO/VaultOpenbaoConnectionForm.cs b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.cs
new file mode 100644
index 00000000..233ba1e5
--- /dev/null
+++ b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.cs
@@ -0,0 +1,13 @@
+namespace ExternalConnectors.VO
+{
+ public partial class VaultOpenbaoConnectionForm : Form {
+ public VaultOpenbaoConnectionForm() {
+ InitializeComponent();
+
+ }
+
+ private void VaultOpenbaoConnectionForm_Activated(object sender, EventArgs e) {
+ tbUrl.Focus();
+ }
+ }
+}
diff --git a/ExternalConnectors/VO/VaultOpenbaoConnectionForm.resx b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.resx
new file mode 100644
index 00000000..8b2ff64a
--- /dev/null
+++ b/ExternalConnectors/VO/VaultOpenbaoConnectionForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/mRemoteNG/Connection/Protocol/PuttyBase.cs b/mRemoteNG/Connection/Protocol/PuttyBase.cs
index b4a2dba6..5bdc7163 100644
--- a/mRemoteNG/Connection/Protocol/PuttyBase.cs
+++ b/mRemoteNG/Connection/Protocol/PuttyBase.cs
@@ -163,12 +163,7 @@ namespace mRemoteNG.Connection.Protocol
}
else if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.VaultOpenbao) {
try {
- RootNodeInfo? rootNode = InterfaceControl.Info?.GetRootParent() as RootNodeInfo;
- if (rootNode == null) {
- Event_ErrorOccured(this, "Secret Server Interface Error: No valid Openbao/Vault data found in root node.", 0);
- return false;
- }
- ExternalConnectors.VO.VaultOpenbao.ReadPasswordSSH(rootNode.VaultOpenbaoUrl, rootNode.VaultOpenbaoToken, (int)InterfaceControl.Info?.VaultOpenbaoSecretEngine, InterfaceControl.Info?.VaultOpenbaoMount ?? "", InterfaceControl.Info?.VaultOpenbaoRole ?? "", InterfaceControl.Info?.Username ?? "root", out password);
+ ExternalConnectors.VO.VaultOpenbao.ReadPasswordSSH((int)InterfaceControl.Info?.VaultOpenbaoSecretEngine, InterfaceControl.Info?.VaultOpenbaoMount ?? "", InterfaceControl.Info?.VaultOpenbaoRole ?? "", InterfaceControl.Info?.Username ?? "root", out password);
} catch (ExternalConnectors.VO.VaultOpenbaoException ex) {
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}
diff --git a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs
index a3dc8a96..9a8fcb8c 100644
--- a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs
+++ b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs
@@ -483,14 +483,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
else if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.VaultOpenbao)
{
try {
- RootNodeInfo? rootNode = connectionInfo?.GetRootParent() as RootNodeInfo;
- if (rootNode == null) {
- Event_ErrorOccured(this, "Secret Server Interface Error: No valid Openbao/Vault data found in root node.", 0);
- return;
- }
if (connectionInfo.VaultOpenbaoSecretEngine == VaultOpenbaoSecretEngine.Kv)
gwu = connectionInfo.RDGatewayUsername;
- ExternalConnectors.VO.VaultOpenbao.ReadPasswordRDP(rootNode.VaultOpenbaoUrl, rootNode.VaultOpenbaoToken, (int)connectionInfo.VaultOpenbaoSecretEngine, connectionInfo.VaultOpenbaoMount, connectionInfo.VaultOpenbaoRole, ref gwu, out gwp);
+ ExternalConnectors.VO.VaultOpenbao.ReadPasswordRDP((int)connectionInfo.VaultOpenbaoSecretEngine, connectionInfo.VaultOpenbaoMount, connectionInfo.VaultOpenbaoRole, ref gwu, out gwp);
} catch (ExternalConnectors.VO.VaultOpenbaoException ex) {
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}
@@ -609,14 +604,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
else if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.VaultOpenbao) {
try {
- RootNodeInfo? rootNode = connectionInfo?.GetRootParent() as RootNodeInfo;
- if (rootNode == null) {
- Event_ErrorOccured(this, "Secret Server Interface Error: No valid Openbao/Vault data found in root node.", 0);
- return;
- }
if(connectionInfo.VaultOpenbaoSecretEngine == VaultOpenbaoSecretEngine.Kv)
userName = connectionInfo?.Username ?? "";
- ExternalConnectors.VO.VaultOpenbao.ReadPasswordRDP(rootNode.VaultOpenbaoUrl, rootNode.VaultOpenbaoToken, (int)connectionInfo.VaultOpenbaoSecretEngine, connectionInfo?.VaultOpenbaoMount ?? "", connectionInfo?.VaultOpenbaoRole ?? "", ref userName, out password);
+ ExternalConnectors.VO.VaultOpenbao.ReadPasswordRDP((int)connectionInfo.VaultOpenbaoSecretEngine, connectionInfo?.VaultOpenbaoMount ?? "", connectionInfo?.VaultOpenbaoRole ?? "", ref userName, out password);
} catch (ExternalConnectors.VO.VaultOpenbaoException ex) {
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}